目前分類:Android-勞動部課程 (54)

瀏覽方式: 標題列表 簡短摘要
●畫面預覽
 
●補充說明--SettingsActivity
1.新增setting activity
SettingsActivity與PreferenceActivity
 
2.會建立兩個activity和4個xml layout,並自設很多範例程式,可以修改
ex:private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener ...
這段程式就是在監控summary有沒有改變 
SettingsActivity與PreferenceActivity
 
=>紅框部分就是summary
SettingsActivity與PreferenceActivity
 
3.到pref_general.xml新增一個EditTextPreference,並且在模擬器修改它的值
SettingsActivity與PreferenceActivity
 
4.開啟android device monitor,看設定資料寫入設定檔的名稱為packagename+_preferences.xml
(注意此處packagename已修改為SettingsActivityAndPreferenceActivity)
 
5.要把我們修改後的設定值抓回來,先確認要抓的那個設定欄位的key值
 
 
public void clickRead(View view) {
    SharedPreferences sp=getSharedPreferences(getPackageName()+"_preferences",MODE_PRIVATE);
    String str=sp.getString("edit_text_preference_1","");
    Toast.makeText(this,str,Toast.LENGTH_SHORT).show();
}
**說明:
1.取得的 SharedPreferences檔名為packagename+ _preferences
2.取得我們要的欄位的值,getString()第一個參數就要放那個欄位的key
3.用Toast秀出這個內容

 

●程式參考(GitHub):檔案存取(四)SettingsActivity與PreferenceActivity

 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●畫面預覽

HashMap與SimpleAadapter

●補充說明

(一)Collection<E>=>一群東西的集合
 
(二)Set<E> interface=>有排序(ex:TreeSet Class)、沒有排序(ex:HashSet Class)
=>不可重複,用來計算不一樣資料的總筆數
HashSet<String> myset = new HashSet<>();
        myset.add("aa");
        myset.add("aa");
        myset.add("bb");
        myset.add("aa");
        myset.add("aa");
        for (String s : myset) {
            System.out.println(s);
        }
=>結果會只有aa和bb
 
(三)Map就是key對value的關係
=>Interface Map<k,v>,常用HashMap Class
=>Map就像一張表格
 
Key
Value
username
John
tel
123
HashMap<String, String> mymap = new HashMap();
mymap.put("username", "john");
mymap.put("tel", "0911111111");
System.out.println(mymap.get("tel"));
**說明:
1.結果是0911111111
2.new HashMap();在java7以後可以省略<>
3.mymap.put("username", "john");=>把key和value放入表格中
4.android中很多資料存取是用map關係
 
*Map的另一種寫法
 
Key
Value
TPE
TC
KH
02
04
07
=>把上面的做法改為下面三個,並且放入arraylist中
 
Key
Value
city
code
台北
02
 
Key
Value
city
code
台中
04
 
Key
Value
city
code
高雄
07
 
        ArrayList<Map<String, String>> mylist = new ArrayList();
        HashMap<String, String> m1 = new HashMap();
        m1.put("city", "台北");
        m1.put("code", "02");
        mylist.add(m1);
        
        HashMap<String, String> m2 = new HashMap();
        m2.put("city", "台中");
        m2.put("code", "04");
        mylist.add(m2);
        
        HashMap<String, String> m3 = new HashMap();
        m3.put("city", "高雄");
        m3.put("code", "07");
        mylist.add(m3);
        
        for(Map<String,String> m:mylist){
            System.out.println(m.get("city")+","+m.get("code"));
        }
**說明:
1.outputs為
HashMap與SimpleAadapter
2.這邊的get method為HashMap CLass下的get method而非arraylist下的get method
 
3.get():public V get(Object key):Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
 
4.android可用這種結構=>simple adapter

 


●程式與說明--java code

public class MainActivity extends AppCompatActivity {
private ListView lv;
private SimpleAdapter sa;
ArrayList<Map<String,String>> mylist= new ArrayList<>();
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv=(ListView)findViewById(R.id.lv);
HashMap<String, String> m1 = new HashMap<>();
m1.put("city", "台北");
m1.put("code", "02");
mylist.add(m1);
HashMap<String, String> m2 = new HashMap<>();
m2.put("city", "台中");
m2.put("code", "04");
mylist.add(m2);
HashMap<String, String> m3 = new HashMap<>();
m3.put("city", "高雄");
m3.put("code", "07");
mylist.add(m3);
 
sa=new SimpleAdapter(MainActivity.this,
mylist,
android.R.layout.simple_list_item_2,
new String[]{"city","code"},
new int[]{android.R.id.text1,android.R.id.text2});
 
lv.setAdapter(sa);
 
 
}
}
**說明:
1.建立arraylist
2.把資料放進arraylist中
3.建立 SimpleAdapter()物件,放五個參數=>context(MainActivity.this),Map資料,listview的版型,Map的key值陣列,key要對應到的資源(這邊因為是使用內建的layout,所以也有內建的資源id)
4.使用simpleadapter的話,版型和資源id都可使用自訂的
 
*如果要加圖片並且用自己的layout
 
public class MainActivity extends AppCompatActivity {
private ListView lv;
private SimpleAdapter sa;
ArrayList<Map<String,Object>> mylist= new ArrayList<>();
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv=(ListView)findViewById(R.id.lv);
HashMap<String,Object> m1 = new HashMap<>();
m1.put("city", "台北");
m1.put("code", "02");
m1.put("img",R.drawable.taipei);
mylist.add(m1);
HashMap<String, Object> m2 = new HashMap<>();
m2.put("city", "台中");
m2.put("code", "04");
m2.put("img",R.drawable.taichun);
mylist.add(m2);
HashMap<String, Object> m3 = new HashMap<>();
m3.put("city", "高雄");
m3.put("code", "07");
m3.put("img",R.drawable.kaishon);
mylist.add(m3);
 
sa=new SimpleAdapter(MainActivity.this,
mylist,
R.layout.myitem, //如果是用自己的版型,R前面不用放android.
new String[]{"city","code","img"},
new int[]{R.id.t1,R.id.t2,R.id.iv});
 
lv.setAdapter(sa);
 
 
}
}
**說明:
1.先把MAP改為 Map<String,Object>,下面相對應的HashMap也要跟著改
2.把圖片放到m1/m2/m3中,key為img,value為id
3.最後的字串陣列要加入img key,資源陣列要放入img的id

 

●程式參考(GitHub):檔案存取(三)HashMap與SimpleAadapter

 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●畫面預覽

●補充說明

(一)Adapter=> 把資料和listview結合
An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
 
(二)序列化:把資料儲存到物件
 
(三)Arraylist自己就可以直接序列化儲存
 
 
arraylist
 
(四)ArrayAdapter:是android內建的adapter,有內建的layout可以用,不需要另外自己寫layout
=>不能用2維陣列,只能用1維陣列和arraylist

 


●程式與說明--java code

lv = (ListView) findViewById(R.id.lv);
adp=new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, ar);
registerForContextMenu(lv);
lv.setAdapter(adp);
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick
      (AdapterView<?> adapterView, View view, int i, long l) {
        index=i;
        //如果定return true就不會跳出contextmenu
        //true if the callback consumed the long click, false otherwise
        return false;
    }
});
**說明:
1.先建立一個陣列
2.直接new ArrayAdapter,給三個參數,第一個是context,第二個是layout的樣子,第三個是要放進去的資料陣列
3.把listView設定給ArrayAdapter

 

●程式參考(GitHub):檔案存取(二)Adapter與ListView 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●Android檔案存取--永久性資料處理(關機後重開機資料還是會存在)
1.SharedPreferences (系統的物件)
=>使用時機:
a.當資料只有一兩筆ex:使用者手機暱稱
b.資料有好幾個一筆ex:電話/email/name
c.應用程式的設定
2.檔案(內部--本機記憶體、外部-sd卡)=>用來存取圖片、大量文字等資料
=>存取外部檔案時會有權限問題,對於敏感權限(ex:通訊錄、照片、詳細定位等與隱私相關)android 6以後都要user授權
3.資料庫(SQL Lite)=>資料量在幾百筆以上或需要特殊篩選(ex:搜尋)時使用,如果資料量沒有這麼多,存在檔案就可以
4.雲端(存放在雲端的好處是即使手機重灌還可以使用)

 

●補充說明-android device moniter觀看data

(一)開啟android device moniter

android device moniter
=>開啟file explorer,android模擬器要使用早一點的版本,才能在android device moniter看到data,如下圖
android device moniter
 
=>這個模擬器比較新就無法看到data下的內容
android device moniter
 
(二)開模擬器的時候,如果出現"Error running app: Instant Run requires 'Tools | Android | Enable ADB integration' to be enabled."要把Enable ADB Integration勾選
android device moniter
 
點button之後,回到android device moniter=>data/data/packagename/shared_prefs/檔案名稱.xml
再點右上角存到桌面
android device moniter
 
開啟檔案,就可以看見剛剛寫入的key和value
 

●程式與說明--java code

(一)write(寫入)

public void writeclick(View view) {
    SharedPreferences sp=
    getSharedPreferences("test",MODE_PRIVATE);
    SharedPreferences.Editor ed=sp.edit();
    ed.putString("mytestkey","123");
    ed.commit();
}
**說明:
1.宣告一個share preference的物件
2.但這邊不是用new,而是從系統取回來這個物件,所以用getSharedPreferences(自訂檔案名稱,mode模式)
3.接著要取得sharePreference物件中的Editor物件,用來放值
4.使用putStirng(key,value);
5.ed.commit();提交放入手機中=>Commit your preferences changes back from this Editor to the SharedPreferences object it is editing.
=>假設要放不只一筆,先全部put完再commit一次即可

 

(二)read(讀取)

public void readclick(View view) {    
    SharedPreferences sp=
    getSharedPreferences("test",MODE_PRIVATE);
    String str=sp.getString("mytestkey","no data");
    Toast.makeText(this,str,Toast.LENGTH_SHORT).show();
}
**說明:
1.這邊的getSharedPreferences的參數要和write的一樣
2.getString():String getString (String key,String defValue):Retrieve a String value from the preferences.
=>defValueString: Value to return if this preference does not exist.This value may be null.
=>第二個參數是設定讀不到的時候要顯示的資料

 

●程式參考(GitHub):檔案存取(一)SharedPreferences

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面

=>點button後產生progerss dialog,五秒後自動消失

多重執行緒(thread)與ProgressDialog

●程式說明:

(一)android多重執行緒

=>progressDialog (可取消/不可取消)用程式設定自行取消
public void click1(View view) {
    final ProgressDialog pd= new ProgressDialog(MainActivity.this);
    pd.show();
    new Thread(){
        @Override
        public void run() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    pd.dismiss();
                }
            });
        }
 
    }.start();
 
**說明
1.這邊測試使用設定停1秒,實際上的做法應該是在抓資料抓圖片或在做運算等做完才讓它dismiss()
2.prgressDialog.show()預設是點外面就可以取消
3.如果不用new Thread,點button就會覺得沒反應,實際上是出現一下馬上消失
 
**在android 8的ui設計準則中不希望有東西擋住畫面,所以在android 8中把progressDialog擋掉了(出現刪除線)
=>假設我們在ps.show();前面加上下面兩行程式碼,畫面在轉圈圈的時候是完全無法動的,android 8不希望這樣的狀況發生,因為有可能就整個當掉無法處理
pd.setMessage("please wait");
pd.setCancelable(false);
=>解決android 8不接受progressDialog的作法:把progress bar放到dialog中,而不用progressDialog
 
 

●程式--java code

public void click1(View view) {
    final ProgressDialog pd= new ProgressDialog(MainActivity.this);
    pd.setMessage("please wait");
    pd.setCancelable(false);
    pd.show();
    new Thread(){
        @Override
        public void run() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    pd.dismiss();
                }
            });
        }

    }.start();

}

 

●程式參考(GitHub):多重執行緒和ProgressDialog

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面

=>將自己app中的內容分享給其他app

=>這邊將文章內容分享到SMS簡訊服務中

Intent 分享app中的內容     Intent 分享app中的內容    Intent 分享app中的內容

 


 

●程式--java code

MainActivity.java
public void share(View view) {
    Intent in=new Intent();
    in.setAction(Intent.ACTION_SEND);
  //EXTRA_TEXT:A constant CharSequence that is associated with the Intent, 
  //used with ACTION_SEND to supply the literal data to be sent.
    in.putExtra(Intent.EXTRA_TEXT
    ,getResources().getString(R.string.share_content));
    in.setType("text/plain");
    startActivity(in);
}

 

●程式參考(GitHub):Implicit Intent / Share Content 

●關於Intent EXTRA_DATA的參考:Intent Standard Extra Data

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面

=>當在其他app中看到要分享的文字、圖片、影像..等,點分享可以跳出自己的app分享我們自己的app中

=>圖中將fb的圖片分享到我們的app--"ImplicitIntentAndShareContent"中

Intent 分享自己的app    Intent 分享自己的app   Intent 分享自己的app

 


 

●程式--AndroidManifest.html

<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <!--定義分享的資料型態-->
        <data android:mimeType="image/*" />
        <!--如果自己寫了一個APP也要能分享就要在Manifest
        加上action android:name="ACTION_SEND"        當使用者使用分享功能時,自己的APP就會出現在可以選擇分享的APP清單上-->
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

 

 

●程式--java code

MainActivity.java
private ImageView mShowImage;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mShowImage = findViewById(R.id.showImg);

    //在其他app按分享時可以看到自己的app 並將檔案分享到自己的app    if (getIntent() != null && getIntent().getExtras() != null) {
        //Intent.EXTRA_STREAM:
        //URI holding a stream of data associated with the Intent, 
        //used with ACTION_SEND to supply the data being sent.
        String uri = getIntent().getExtras().get(Intent.EXTRA_STREAM).toString();
        mShowImage.setImageURI(Uri.parse(uri));
    }

}
 

 

●程式參考(GitHub):Implicit Intent / Share Content 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面

=>透過隱性intent將資料傳遞到另一個activity

Screenshot_20190515-145056.jpg    Screenshot_2019-05-15-14-33-45.png

 

●補充說明

(一)隱性Intent(把action寫在 mainifest中)不是指定誰來用,而是只要有在系統註冊這個動作的APP都可以用
 
(二)隱性Intent可以跨app呼叫,因為manifest的資訊在安裝app時,都會註冊在android系統中,所以只要知道設定的action name就可以呼叫不同app的隱性Intent
=>當有兩個action同名字時,就會跳兩個出來讓你選擇(請參考:)
 
EX:同一個APP有兩個activity都註冊了sendMsg這個action,就會出現如下畫面

Screenshot_20190515-150911.jpg

 

 

●程式--AndroidManifest.html

<activity android:name=".Main2Activity">
    <!--隱性intent要先加intent-filter-->
    <intent-filter>
        <!--有在mainfest中註冊這個action的actitvity都可以使用-->
        <!--如果只是自己的程式要用,就可以自定義名稱,如下-->
        <action android:name="sendMsg"/>        
        <!--DEAFAULT就是代表聽到sendMsg時就會跳出來-->
        <category android:name="android.intent.category.DEFAULT"/>   
    </intent-filter>
</activity>

 

●程式--java code

(一)MainActivity.java
public void impicit(View view) {
    Intent in=new Intent();
    //getIntent()取得putExtra的資料
    in.setAction("sendMsg");    
     //get res/values/strings 
    in.putExtra("msg",getResources().getString(R.string.share_content));
    startActivity(in);
}

(二)Main2Activity.java
//getIntent()取得putExtra的資料
Intent in=getIntent();
String str=in.getStringExtra("msg");
TextView text=findViewById(R.id.textResult);
text.setText(str);

 

 

●程式參考(GitHub):Implicit Intent / Share Content 

 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面

webview load html from assets    webview load html from assets

 

●補充說明

(一)WebView

=>離線的時候也能用webview,這是連到android本機端的網頁

=>所以可以把網站都丟到這個asset資料夾中,就能在離線的狀況下看網站:這叫hybrid的作法

 
1.使用webview先在AndroidManifest.xml中設定權限
<uses-permission android:name="android.permission.INTERNET"/>
 
2.拉出一個webview,給id
 
3.在app下面new一個assets folder,放在main下面=>確定
 
4.再到assets folder new一個file=>named index.html,加上<h1>和<p>
5.把程式碼修改為連到這個網址,注意這邊的android_asset不加s
wv.loadUrl("file:///android_asset/index.html");
 
6.設定第二頁,在index.html中加上可以跳到下一頁的連結
<p><href="page2.html">前往第二頁</a></p>
 
7.在java code加上下面兩行,才能正確連結到下一頁,因為android 8以後有改strictMode,應該是因為安全性設定的問題,不能直接用file:///開檔案,要用fileprovider,這兩個的用法是建立一個VmPolicy物件(模擬器規則物件),讓這個程式可以不用被app的規則限制住而是用模擬器規則(因為只是用來做測試的,所以不需要很多規則),這不是一個好的做法,但暫時先這樣做=>在api22以前沒有這個問題
 
StrictMode.VmPolicy.Builder builder =
 new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
 
(二)如何回上一頁=>做完上面,會發現跳到第二頁以後無法返回上一頁,因為如果直接按back button會跳出app,這是因為我們的app只有一個activity,android的back buttong功能是離開activity,這邊因為page2也在同一個activity中所以無法回上一頁,這邊就要使用onBackPressed()
 
public void onBackPressed(){
    if(wv.getUrl().contains("index.html")){
        super.onBackPressed();
    }else{
        wv.goBack();
    }
}
 
(三)如果在第二頁加上javascript程式碼,要記得在javacode加上
wv.getSettings().setJavaScriptEnabled(true);

 

 

●程式--html

(一)index.html

<h1>Hello World!</h1>
<p>i am the index</p>
<p><a href="page2.html">前往第二頁</a></p>

 

(二)page2.html

<h1>this is page 2</h1>
<script>
    function calc(){
    var q1=document.getElementById("q1").value;
    var q2=document.getElementById("q2").value;
    var ans=eval(q1)+eval(q2);
    var spanans=document.getElementById("ans");
    spanans.innerHTML=ans;
    }

</script>
<input type="text" id="q1"/>+
<input type="text" id="q2"/>
<input type="button" value="=" onclick="calc()">
<span id="ans"></span>

 

●程式--java code

WebView wv;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    wv=(WebView)findViewById(R.id.wv);

    //要設定javascript可以運作
    wv.getSettings().setJavaScriptEnabled(true);
    
   //一定要設定WebViewClient,否則找不到page2.html
   wv.setWebViewClient(new WebViewClient());

    //android_asset不加s
    wv.loadUrl("file:///android_asset/index.html");

    //加上這個就可以開檔案,因為android 8以後有改strictMode,
    //不能直接用file:///開檔案,要用fileprovider來做
    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());

}
//當按下手機的back button時的method
public void onBackPressed(){
    //取得url以後檢查url中有沒有index.html,
    //如果有就跳出activity,沒有就回上一頁
    if(wv.getUrl().contains("index.html")){
        //呼叫父類別的onBackPressed()會直接離開activity,
        //但是不可以將此功能註解掉
        super.onBackPressed();
    }else{
        //回上一頁
        wv.goBack();
    }
}

 

●程式參考(GitHub):Webview Load html from Assets

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面

create Options Menu         create Options Menu

 

 

●建立一個xml menu(Defining a Menu in XML)

1.對res按右鍵=>New=>Android Resource Directory

create Options Menu

2.Resource type 選定為menu,會自動帶入Directory name

create Options Menu

3.對已建立的menu directory按右鍵=>New=>Menu resource file

create Options Menu

4.輸入file name,完成menu xml的建立

create Options Menu


●程式-- mymenu.xml 

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/menu1"
        android:icon="@android:drawable/ic_dialog_email"
        android:title="@string/option1"
        app:showAsAction="ifRoom|collapseActionView" />
    <item
        android:id="@+id/menu2"
        android:title="option2"
        tools:ignore="HardcodedText" />
</menu>

 

●程式-- java code

@Override  //利用程式產生options menu
    //這個方法會傳入一個menu物件(就是三個點)
    public boolean onCreateOptionsMenu(Menu menu) {
        //增加選單(作法一)
        //menu.add("option1");
        //menu.add("option2");
        
        //增加選單更好的做法(作法二)
        //menu.add(0,1,0,"option1");
        //menu.add(0,2,0,"otpion2");
        
        //resource file設定option menu的作法(作法三)
        getMenuInflater().inflate(R.menu.mymenu,menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override //偵測哪一個選單被按下,會傳回item
    public boolean onOptionsItemSelected(MenuItem item) {
        //這邊的idR檔中的id
        if(item.getItemId()==R.id.menu1){
            Toast
            .makeText(this,"option1 is selected",Toast.LENGTH_SHORT)
            .show();
        }
        if(item.getItemId()==R.id.menu2){
            Toast
            .makeText(this,"option2 is selected",Toast.LENGTH_SHORT)
            .show();
        }
        
        return super.onOptionsItemSelected(item);
    }
}

●程式參考(GitHub):How to create Options Menu in Android

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

在程式中寫layout,通常有兩種狀況
1.按鈕或圖案會因為雲端資料做改變,所以要用程式寫來控制動態的改變
2.layout很嚴謹,不能因為手機不同尺寸不同而有改變,這時就要用程式來控制
 
●程式--java code
protected void onCreate(Bundle savedInstanceState) {
    int i;
    super.onCreate(savedInstanceState);
    //先把setContentView(R.layout.activity_main)刪除
    LinearLayout ll=new LinearLayout(MainActivity.this);
    //for做三個一樣的按鈕
    for (i=1;i<=3;i++){ 

        //先設定layoutwidth,height,weight
        LinearLayout.LayoutParams para= 
          new LinearLayout.LayoutParams
          (ViewGroup.LayoutParams.WRAP_CONTENT,
          ViewGroup.LayoutParams.WRAP_CONTENT,1);
        
        //其他屬性的設定可以如下
        //para.gravity = Gravity.CENTER; 
        //para.bottomMargin=20;
        Button btn=new Button(MainActivity.this);
        btn.setText("hello");
        //把設定好的layout設定給btn
        btn.setLayoutParams(para);
        final String str=String.valueOf(i);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this,str,Toast.LENGTH_SHORT).show();
            }
        });
        //linearlayout下加一個btn,因為btn也是view
        ll.addView(btn);
    }
    //如果不用linearlayout,而是直接setContentView(btn);
   //那就會有一個跟版面完全一樣大小的button
   //可以直接設定linearlayout,因為linearlayout也是view
    setContentView(ll); 
}
 
 
●程式參考(GitHub):動態產生按鈕
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●程式說明
 
1. 當使用startActivityForResult(in,RequestCode);到下一頁後,關閉下一頁時,就一定會回到這頁然後run  onActivityResult()
 
2. setResult(result code,intent data)這個功能在設定現在這個activity結束後要回傳甚麼資料
 
3.假設在第二頁,不按button,直接使用手機的back功能回上一頁,但又沒有輸入資料,這時就會閃退,因為直接back時,沒有run onclick ok method,就沒有跑setResult(),所以沒有 resultCode,回到上一頁時, onActivityResult就收到 intent 資料是null,當在呼叫 data.getStringExtra()時,就會出現nullException
=>所以做法是在 onActivityResult()method中加上判斷if( requestCode==RequestCode )
 
4. requestCode是用來指地要回傳資料的name,一般會先用final變數定義,也用 requestCode 判斷拿回來的資料和我們要的是不是一樣
 
 

 

●程式--java code
 
MainActivity.java
 
final int RequestCode=1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

public void click(View view) {
    Intent in=new Intent();
    in.setClass(this,Main2Activity.class);
    startActivityForResult(in,RequestCode);

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode==RequestCode){
        if(resultCode==RESULT_OK){
            Toast
            .makeText(this,data.getStringExtra("2data"),Toast.LENGTH_SHORT)
            .show();
        }
    }
}

 

Main2Activity.java

public void ok(View view) {
    EditText text=(EditText)findViewById(R.id.text);
    String str=text.getText().toString();
    Intent in=new Intent();
    in.putExtra("2data",str);
    setResult(RESULT_OK,in);
    finish();
}

 

●程式參考(GitHub):Getting a Result from an Activity

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面

include and merge   include and merge    include and merge    include and merge    include and merge

●實作練習:補充說明 

(一)利用merge來簡化UI,以此例來說,在merge時不用再加入padding和orientation,因為最外層的linearlayout已經加入,但在merge的畫面看起來會很奇怪(如下圖),是因為有些設定放在最外層

include and merge

 

(二)使用indclude把畫面放進主要layout中

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="30dp"
    tools:context="com.example.student.qnatest.q1">

    <include
        android:id="@+id/all_layout"
        layout="@layout/all_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

include and merge

 

(三)用include/merge只要設定一次id,所以同一個layout可以用在三個不同的activity中,如此例有三個題目但都共用一個activity_q.xml的layout

setContentView(R.layout.activity_q);

 

(四)textview中加入html網頁語法

=>網頁特殊符號用法可以參考下列網址
 
ex:
\"=>表示 "
\U00A0=>表示空白(跟萬國碼的space不同)
&lt;=>表示<
&gt;=>表示>
 
 
(五)要在android values/strings.xml中加入html語法,要先加上<![CDATA[.... ]]>
ex:<![CDATA[<font color="#444444">視覺</font>]]>
 
(六)在java code中要讀取values/strings中的html語法要用Html.fromHtmel()
=>要判斷android版本,因為api 24以上使用Html.fromHtml(String,int);已棄用Html.fromHtml(String);
=>api 23以下使用Html.fromHtml(String);
 
 
(七)紀錄答案採用getTag(),所以在設定文字的時候要同時設定tag,這邊利用vaules/strings有html語法,要再使用Html.fromHtml()讀取
 
setTag:
r1.setTag(Html.fromHtml(getString(R.string.q1selection1)));
r2.setTag(Html.fromHtml(getString(R.string.q1selection2)));
r3.setTag(Html.fromHtml(getString(R.string.q1selection3)));

 

getTag取得答案:

myanswer=view.getTag().toString();

 

 
(八)透過Intent的putExtra,把資料傳遞到下一個activity,第二層和第三層要把前一層的先用getIntent.getStringExtra()取得,再帶入下一層

以第三題為例:

in.putExtra("a3", myanswer);
in.putExtra("a1",getIntent().getStringExtra("a1"));
in.putExtra("a2",getIntent().getStringExtra("a2"));

 

(九)最後在結果頁也是利用getIntent.getStringExtra()取得每一題的答案再比對結果

text1 = getIntent().getStringExtra("a1");
text2 = getIntent().getStringExtra("a2");
text3 = getIntent().getStringExtra("a3");

 

*程式參考(gitHub):問答小學堂

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面 

     

 

●實作練習:補充說明 

(一)動畫=>動畫範例限定android api level 16(android 4.1),如果開專案的時候沒選api16,就在這邊改

Animation

 

(二)建立動畫Resource File

Animation

(三)AnimationDrawable說明

Animation

(四)任務說明

Animation

 

●實作練習:xml

(一)activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.student.lab06.MainActivity">

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/img"
        android:layout_marginTop="20dp"
        android:orientation="horizontal">

        <Button
            android:id="@+id/start"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="click"
            android:text="start" />

        <Button
            android:id="@+id/stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="click"
            android:text="stop" />

        <Button
            android:id="@+id/secs"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="click"
            android:text="after5secStop" />

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:textSize="20sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <View
            android:id="@+id/viewlogo"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_gravity="center"
            android:background="@drawable/nba_logo_spurs" />

        <TextView
            android:id="@+id/logoname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:text="" />
    </LinearLayout>

    <Button
        android:id="@+id/go"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="go"
        android:text="Go" />

    <TextView
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text=""
        android:textSize="20sp" />
</LinearLayout>

 

(二)arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <array name="nbalogo">
        <item>@drawable/nba_logo_knicks</item>
        <item>@drawable/nba_logo_magic</item>
        <item>@drawable/nba_logo_pistons</item>
        <item>@drawable/nba_logo_spurs</item>
        <item>@drawable/nba_logo_nets</item>
        <item>@drawable/nba_logo_clippers</item>
        <item>@drawable/nba_logo_76ers</item>
        <item>@drawable/nba_logo_suns</item>
        <item>@drawable/nba_logo_hornets</item>
        <item>@drawable/nba_logo_raptors</item>
        <item>@drawable/nba_logo_lakers</item>
        <item>@drawable/nba_logo_warriors</item>
    </array>
    <string-array name="nabname">
        <item>knicks</item>
        <item>magic</item>
        <item>pistons</item>
        <item>spurs</item>
        <item>nets</item>
        <item>clippers</item>
        <item>76ers</item>
        <item>suns</item>
        <item>hornets</item>
        <item>raptors</item>
        <item>lakers</item>
        <item>warriors</item>
    </string-array>
</resources>

 

(三)frame_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/d1" android:duration="100"/>
    <item android:drawable="@drawable/d2" android:duration="100"/>
    <item android:drawable="@drawable/d3" android:duration="100"/>
    <item android:drawable="@drawable/d4" android:duration="100"/>
    <item android:drawable="@drawable/d5" android:duration="100"/>
    <item android:drawable="@drawable/d6" android:duration="100"/>
    <item android:drawable="@drawable/d7" android:duration="100"/>
    <item android:drawable="@drawable/d8" android:duration="100"/>
    <item android:drawable="@drawable/d9" android:duration="100"/>
    <item android:drawable="@drawable/d10" android:duration="100"/>
</animation-list>

 

●實作練習:java code

public class MainActivity extends AppCompatActivity {
    private ImageView img;
    //在屬性要先設定動畫物件
    private AnimationDrawable animate;
    private TextView text;
    //view可以設定背景圖片,比imageview省資源
    private View viewlogo;
    private TextView logoname, message;
    //資源檔陣列
    // getResources().obtainTypedArray()會回傳TypedArray
    private TypedArray NBAlogos;
    //陣列有多少張圖
    private int logoNumber;
    private Button go;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        intiView();
        initNBAlogos();
        initAnimation();
    }

    private void intiView() {
        img = findViewById(R.id.img);
        text = findViewById(R.id.text);
        viewlogo = findViewById(R.id.viewlogo);
        logoname = findViewById(R.id.logoname);
        message = findViewById(R.id.message);
        go = findViewById(R.id.go);
    }

    //設定圖片陣列資源,設定view背景圖片
    private void initNBAlogos() {
        //obtainTypedArray():
        // Returns a TypedArray holding an array of the array values.
        //取得nbalogo陣列資源
        NBAlogos = getResources().obtainTypedArray(R.array.nbalogo);
        //取得陣列長度
        logoNumber = NBAlogos.length();
        //getDrawable (int index)
        //Retrieve the Drawable for the attribute at index.
        //取得陣列第0項的圖設定給view
        viewlogo.setBackground(NBAlogos.getDrawable(0));
    }

    private void initAnimation() {
        //設定imageview
        img.setBackgroundResource(R.drawable.frame_animation);
        //取得imageview的背景給動畫物件animate
        animate = (AnimationDrawable) img.getBackground();
    }


    public void click(View view) {
        int id = view.getId();
        switch (id) {
            case R.id.start:
                animate.start(); //開始動畫
                break;
            case R.id.stop:
                animate.stop(); //結束動畫
                break;
            case R.id.secs:
                animation5seconds();
                break;
        }
    }

    //Handler 處理代辦事項
    //Each Handler instance is associated with
    // a single thread and that thread's message queue.
    //There are two main uses for a Handler:
    // (1) to schedule messages and runnables to
    // be executed as some point in the future; and
    // (2) to enqueue an action to be performed
    // on a different thread than your own.
    private Handler handle = new Handler();

    private void animation5seconds() {
        int delaytime = 5000;
        animate.start();
        Runnable task = new Task(); //多型的作法
        boolean result = handle.postDelayed(task, delaytime);
        text.setText(result ? "交付成功" : "交付失敗");
    }


    //這邊使用內部類別來implement Runnable    // 因為如果另外建立一個外部類別,將無法使用private變數
    //The Runnable interface should be implemented by
    // any class whose instances are intended to be executed by a thread.
    // The class must define a method of no arguments called run.
    private class Task implements Runnable {
        @Override
        public void run() {
            animate.stop();
            text.setText("時間到");
        }
    }

    private Runnable start = new startchange();
    private Runnable stop = new stopchange();

    public void go(View view) {
        handle.post(start); //立刻執行任務
        handle.postDelayed(stop, 3000);
        go.setEnabled(false);
    }

    
    private class startchange implements Runnable {

        @Override
        public void run() {
            //取得字串陣列資源
            String[] name = getResources().getStringArray(R.array.nabname);
            //隨機選取0~12的數字
            int index = (int) (Math.random() * logoNumber);
            //換圖
            viewlogo.setBackground(NBAlogos.getDrawable(index));
            //換隊名
            logoname.setText(name[index]);
            //this是指 startchange這個物件本身
            boolean result = handle.postDelayed(this, 100);  
            message.setText(result ? "設定成功" : "設定失敗");
        }

    }

    private class stopchange implements Runnable {
        @Override
        public void run() {
            //取消任務start
            handle.removeCallbacks(start);  
            go.setEnabled(true);
            //不可以放在go()裡面,
            // 因為go以後要等三秒後才會顯示時間到,
            // 如果放在go()裡面會被設定成功覆蓋掉
            message.setText("時間到");
        }
    }
}

 

 

*程式參考(gitHub):Animation動畫的實作與練習

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面 

AlertDialog

●實作練習:xml

(一)activity_main.xml

<Button
    android:id="@+id/seventhbtn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="seventhbtn"
    android:text="自訂選單" />

 

(二)fragment_dialogfragment.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.student.lab05.dialogfragment">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <EditText
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="15dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="5dp"
            android:hint="Username"
            android:inputType="textEmailAddress" />

        <EditText
            android:id="@+id/password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginBottom="5dp"
            android:fontFamily="sans-serif"
            android:hint="Password"
            android:inputType="textPassword" />

    </LinearLayout>

</FrameLayout>

 

●實作練習:java code

(一)MainActivity.java

public void seventhbtn(View view) {
    //建立自訂的dialog
    dialogfragment my=new dialogfragment();
    my.show(getSupportFragmentManager(),"dialogfragment");

}

public void changeContent(CharSequence msg){
    text.setText(msg);
}

public int times(){
    count=++count;
    return count;
}

 

(二)dialogfragment.java

//繼承對象由Fragment變更為android.support.v4.app.DialogFragment
//因為不是一般的Fragment,
//要刪除onCreateView,並且override DialogFragmentonCreateDialog
public class dialogfragment extends DialogFragment {
    private EditText name;
    int count;
    //private EditText password;

    public dialogfragment() {
        // Required empty public constructor
    }

    @NonNull
    @Override
    //Override to build your own custom Dialog container.
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        //Instantiates a layout XML file into its corresponding View objects.
        //透過inflater讀取fragment_dialogfragment.xml來產生view
        //取得inflater
        LayoutInflater inflater=getActivity().getLayoutInflater(); 

        //fragment_dialogfragment.xml取得自訂畫面,
         //作法inflate(resources,viewGroup)
        //因為這邊沒有viewgroup所以是null
        View v=inflater.inflate(R.layout.fragment_dialogfragment,null);
        name=v.findViewById(R.id.name);
        
        //Activity getActivity ()
        //Return the Activity this fragment is currently associated with.
        AlertDialog.Builder builder=new AlertDialog.Builder(getActivity());
        //AlertDialog.Builder setView (View view)
        //Sets a custom view to be the contents of the alert dialog.
        builder.setView(v)
            .setPositiveButton("SIGN IN", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    MainActivity main=(MainActivity)getActivity();
                    int count=main.times();
                    CharSequence Name=name.getText();
                    StringBuilder all=new StringBuilder();
                    all.append("次數")
                       .append(count)
                       .append(" 歡迎光臨 ")
                       .append(Name);
                    main.changeContent(all);
                }
            })
            .setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                   //先取得mainActivity,再透過寫在mainactivity中的 changeContent
                   //方法改變mainActivitytextview內容
                    MainActivity main=(MainActivity)getActivity();
                  main.changeContent("登入取消");
                }
            });

      //AlertDialog create ()
      //Creates an AlertDialog with the arguments supplied to this builder.
      //回傳建立的Dialog
      return builder.create();
    }
}

 

*程式參考(gitHub):AlertDialog實作

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面 

Screenshot_2019-05-02-13-57-21.png     Screenshot_2019-05-02-13-57-37.png    Screenshot_2019-05-02-13-57-48.png

     

●實作練習:xml

(一)values/array.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="array">
        <item>我知道</item>
        <item>你少來</item>
        <item>還用你說嗎</item>
    </string-array>
</resources>

 

(二)activity_main.xml

<Button
    android:id="@+id/fourbtn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="fourbtn"
    android:text="項目清單" />

<Button
    android:id="@+id/fifthbtn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="fifthbtn"
    android:text="可複選的核取方塊項目" />

<Button
    android:id="@+id/sixthbtn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="sixthbtn"
    android:text="單選的radio按鈕項目" />

 

●實作練習:java code

//按鈕四會產生項目清單
public void fourbtn(View view) {  
   final String[] arr=getResources().getStringArray(R.array.array);
    //this就是誰要使用這個dialog
   //android.R.style.Theme_DeviceDefault_Dialog 指定要用的主題風格
    new AlertDialog
            .Builder(this,android.R.style.Theme_Holo_Light_Dialog_NoActionBar)
            .setTitle("你好帥")
            .setItems(arr, new DialogInterface.OnClickListener() {
            @Override
                //int i是代表陣列中選取的那個項目的索引碼
                public void onClick(DialogInterface dialogInterface, int i) {
                    text.setText(arr[i]);
                }
            })
            .show();
}

public void fifthbtn(View view) {
     final String[] arr=getResources().getStringArray(R.array.array);
    //建立一個陣列紀錄每個checkbox是否有被選取,陣列長度要和字串長度一樣
    final boolean[] selected=new boolean[arr.length];
    new AlertDialog
            .Builder(this,android.R.style.Theme_Holo_Light_Dialog_NoActionBar)
            .setTitle("你超正")
            //多選要用setMultiChoiceItems
            .setMultiChoiceItems
            (arr, selected, new DialogInterface.OnMultiChoiceClickListener() {
                @Override
                //這邊的onClick是代表每次勾選或取消勾選時執行,
                //i代表這次勾選的項目編號,b代表這次勾選的選項狀態
                public void onClick
               (DialogInterface dialogInterface, int i, boolean b) {
                //因為勾選後沒有要執行甚麼程式,所以這邊空白,執行是在ok按鈕按下去才做
                }
            })
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick
                (DialogInterface dialogInterface, int which) {
                  StringBuilder result=new StringBuilder();
                    //按下ok按鈕後,到selected陣列逐一檢查,如果某個選項is true,
                     //就把同樣編碼的arr陣列字串丟到stringbuilder                    for(int i=0;i<selected.length;i++){
                        if(selected[i]){
                            result.append(arr[i]).append("\n");
                        }
                    }
                    text.setText(result);
                }
            })
            .setNegativeButton
            ("CANCEL", new DialogInterface.OnClickListener() {
                @Override//cancelbutton沒有其他動作
                public void onClick(DialogInterface dialogInterface, int i) {

                }
            })
            .show();

}

//mChoice用來記錄被選取的選項,因為selectN(被選取選項的編號)是一個區域變數,沒
//辦法丟給okonclick,所以要丟給一個全域變數來記錄
private int mChoice;
public void sixthbtn(View view) {
    final String[] arr=getResources().getStringArray(R.array.array);
    mChoice=0;
    new AlertDialog.Builder(this)
            .setTitle("你好美")
            //單一選項用setSingleChoiceItems,第二個參數是被選取選項的編號
            .setSingleChoiceItems
           (arr, mChoice, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int selectN) {
                    mChoice=selectN;
                }
            })
            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    text.setText(arr[mChoice]);
                }
            })
            .setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    text.setText("算了吧");
                }
            })
            .show();

}

 

*程式參考(gitHub):AlertDialog實作

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面 
 

AlertDialog    AlertDialog   AlertDialog

AlertDialog     AlertDialog

●補充說明:

(一)AlertDialog 選擇support會比較好,因為會支援舊版的android系統

AlertDialog

(二) 這個方塊告訴我們setPositiveButton()中的兩個參數放甚麼!

AlertDialog

(三)當匿名類別使用外部的變數時,因為考量到匿名類別的生命週期和外部變數可能會不一樣,所以要把被使用到的外部變數宣告為final,而匿名類別會自動把該變數copy下來
 
 

●實作練習:xml

<TextView
    android:id="@+id/text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:textColor="@android:color/background_dark"
    android:layout_gravity="center"
    android:text="Hello World!"/>
<Button
    android:id="@+id/ok"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="一個按鈕"
    android:onClick="ok"/>
<Button
    android:id="@+id/secondbtn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="兩個按鈕"
    android:onClick="secondbtn"/>
<Button
    android:id="@+id/thirdbtn"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="三個按鈕"
    android:onClick="thirdbtn"/>

 

●實作練習:java code

=>MainActivity 要先implements DialogInterface.OnClickListener

public void ok(View view) {
    //打造的對話框使用當前的activity主題顏色
    new AlertDialog.Builder(this)
            .setMessage("你好帥喔")
           //將此按鈕事件委託給當前的activity
           .setPositiveButton("我知道",this)
           .show();
}

@Override 
//第一個按鈕的postiveButton的onClick method
public void onClick(DialogInterface dialogInterface, int i) {
    text.setText("我知道");
}

//按下secondbtn,要將兩個按鈕交給同一個alert a物件處理
public void secondbtn(View view) {
    alert a=new alert();
    new AlertDialog.Builder(this)
            .setMessage("你好帥喔")
            .setPositiveButton("謝謝",a)
            .setNegativeButton("狗腿",a)
            .show();
}


//這邊將第個二按鈕的對話框按鈕事件委託給內部類別alert
private class alert implements AlertDialog.OnClickListener{
    @Override
    public void onClick(DialogInterface dialogInterface, int i) {
        switch (i){
            //DialogInterface.BUTTON_POSITIVE會是一個整數,類似R.id的作法
            case DialogInterface.BUTTON_POSITIVE:
                text.setText("謝謝");
                break;
            case DialogInterface.BUTTON_NEGATIVE:
                text.setText("狗腿");
                break;
        }
    }
}

//當第三個按鈕按下去時,用匿名類別直接實作程式碼,不再另外寫一個類別,當裡面的程式很簡單的時候適用
public void thirdbtn(View view) {
    new AlertDialog.Builder(this)
            .setMessage("你好帥喔")
            .setPositiveButton("謝謝讚美", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    text.setText("謝謝讚美");
                }
            })
            .setNegativeButton("太狗腿了", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    text.setText("太狗腿了");
                }
            })
            .setNeutralButton("無言", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    text.setText("無言");
                }
            })
            .show();
}

 

*程式參考(gitHub):AlertDialog實作

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面 

RadioButton    RadioButton    RadioButton

 

●程式說明:

(一)Radion button屬性

=>buttonTint:選鈕顏色

=>textcolor:文字顏色

=>checked:是否被選

=>textApperarance:文字大小
 
 
(二)取得radiobutton的文字與文字顏色
getText()
getCurrentTextColor(): Return the current color selected for normal text.
 
(三)設定背景顏色和文字顏色
setBackgroundColor(int bg): Set background behind animation.
參數: int: The background color. If 0, no background. Currently must be black, with any desired alpha level.
setTextColor(int color):Sets the text color for all the states (normal, selected, focused) to be this color.
參數: int: A color value in the form 0xAARRGGBB. Do not pass a resource (做法是0xAARRGGBB(AA代表透明度alpha,不透明為ff))
 
(四)設定radio button的選取狀態setChecked:Changes the checked state of this button
 
(五)manifeast的activity設定
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
 
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".colorPick"></activity>
</application>
=>這裡可以看到這個專案有兩個activity,負責啟動的那一個裡面有子標籤< intent-filter >,所以希望哪個activity啟動就要把這個子標籤的內容放進那個activity,若兩個activity都有這個子標籤,下載app安裝後,就會有兩個啟動的icon負責啟動不同的activity
 

●實作練習:xml

(一)activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.student.lab04.MainActivity">

    <TextView
        android:id="@+id/initext"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:layout_gravity="center"
        android:layout_marginTop="30dp"
        android:gravity="center"
        android:text="顏色未設定"
        android:textSize="25sp"
        android:textColor="@android:color/background_dark"/>

    <Button
        android:id="@+id/gotopick"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="30dp"
        android:textSize="16sp"
        android:text="選擇顏色"
        android:onClick="gotopick"/>

</LinearLayout>

 

(二)activity_color.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingTop="130dp"
    tools:context="com.example.student.lab04.colorPick">

    <RadioGroup
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center">
        <!--預設紅色被選取-->
        <RadioButton
            android:id="@+id/red"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="12dp"
            android:buttonTint="@android:color/holo_red_light"
            android:checked="true"
            android:onClick="picked"
            android:text="holo_red_light"
            android:textColor="@android:color/holo_red_light"
            android:textSize="20sp" />

        <RadioButton
            android:id="@+id/orange"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="12dp"
            android:buttonTint="@android:color/holo_orange_dark"
            android:onClick="picked"
            android:text="holo_orange_dark"
            android:textColor="@android:color/holo_orange_dark"
            android:textSize="20sp" />

        <RadioButton
            android:id="@+id/green"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="12dp"
            android:buttonTint="@android:color/holo_green_light"
            android:onClick="picked"
            android:text="holo_green_light"
            android:textColor="@android:color/holo_green_light"
            android:textSize="20sp" />

        <RadioButton
            android:id="@+id/blue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="12dp"
            android:buttonTint="@android:color/holo_blue_dark"
            android:onClick="picked"
            android:text="holo_blue_dark"
            android:textColor="@android:color/holo_blue_dark"
            android:textSize="20sp" />

    </RadioGroup>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="cancel"
            android:text="CANCEL" />

        <Button
            android:id="@+id/ok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="ok"
            android:text="OK" />
    </LinearLayout>

</LinearLayout>

 

●實作練習:Java Code

(一)MainActivity.java

public class MainActivity extends AppCompatActivity {
    Button gotopick;
    //因為有另一個class要取得colortext的值,
    //並且設定initext,所以這三個都要是static
    static TextView initext;
    static int color=0;
    static CharSequence text="";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gotopick =(Button)findViewById(R.id.gotopick);
        initext =(TextView)findViewById(R.id.initext);
    }

    public void gotopick(View view){
        Intent in=new Intent();
        //可以用this取代MainAcitvity.this
        in.setClass(this,colorPick.class);
        startActivity(in);
    }
}

 

(二)colorPick.java

public class colorPick extends AppCompatActivity {
    Button cancel,ok;
    RadioButton red,orange,green,blue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_color_pick);
        cancel =(Button)findViewById(R.id.cancel);
        ok =(Button)findViewById(R.id.ok);
        red =(RadioButton)findViewById(R.id.red);
        green =(RadioButton)findViewById(R.id.green);
        orange =(RadioButton)findViewById(R.id.orange);
        blue =(RadioButton)findViewById(R.id.blue);
    }
    public void picked(View view){
        if(red.isChecked()){
            //取得radio button的文字顏色丟給color
            //(因為是屬於MainAcitvity的,所以要用MainActivity.color)
            MainActivity.color=red.getCurrentTextColor();
            //取得radio button的文字丟給text
            MainActivity.text=red.getText();
            //設定initext這個textview的背景顏色
            MainActivity.initext.setBackgroundColor(MainActivity.color);
            //設定initext這個textview的文字
            MainActivity.initext.setText(MainActivity.text);
            //顏色表示方式:0xAARRGGBB(AA代表透明度alpha,不透明為ff)
            MainActivity.initext.setTextColor(0xffffffff);
        }
        if(orange.isChecked()){
            MainActivity.color=orange.getCurrentTextColor();
            MainActivity.text=orange.getText();
            MainActivity.initext.setBackgroundColor(MainActivity.color);
            MainActivity.initext.setText(MainActivity.text);
            MainActivity.initext.setTextColor(0xffffffff);
        }
        if(green.isChecked()){
            MainActivity.color=green.getCurrentTextColor();
            MainActivity.text=green.getText();
            MainActivity.initext.setBackgroundColor(MainActivity.color);
            MainActivity.initext.setText(MainActivity.text);
            MainActivity.initext.setTextColor(0xffffffff);
        }
        if(blue.isChecked()){
            MainActivity.color=blue.getCurrentTextColor();
            MainActivity.text=blue.getText();
            MainActivity.initext.setBackgroundColor(MainActivity.color);
            MainActivity.initext.setText(MainActivity.text);
            MainActivity.initext.setTextColor(0xffffffff);
        }

    }
    public void cancel(View view){
        //setChecked:Changes the checked state of this button
        //所以恢復到紅色被選擇的狀態
        red.setChecked(true);
    }

    public void ok(View view){
        picked(view);
        //Call this when your activity is done and should be closed
        finish();
    }
}

 

 

 

*程式參考(gitHub):RadioButton與跨activity傳送資料實作練習

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面 

(一)720dp以下畫面

fragment      fragment 

 

(二)720dp以上畫面

fragment

●程式說明:

(一)使用fragment
1.fragment(片段):可以由很多veiw組成,做成一個片段以後就可以重複使用,不需要一直複製貼上相同的程式碼
 
2.在專案=>右鍵=>new=>Fragment=>fragment(blank)
=>先命名,勾選產生xml,這樣會自動產生一個layout,可以做版面調整
=>下面兩個選項是自動產生一些程式碼不需要勾選
 
3.在mainactivity.xml中加入fragment,其中android:name為fragment的類別屬性名稱,tools:layout為xml的layout名稱
<fragment
    android:name="com.example.student.lab03.CountFragment"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    tools:layout="@layout/fragment_count"/>
 
(二)補充說明
1.xmlns=>ns:name space(命名空間),因為命名空間必須獨一無二,所以xmlns=一個獨立網址來命名
RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 
2.andorid:layout_width=>左邊的android:其實就等於 http://schemas.android.com/apk/res/android,是為了區分出這個xml屬性是android用的而非一般的xml
 
3.android:屬性在執行時會有效(發生在裝置上)
   tools:屬性在設計階段預覽有效(程式在執行時,tools的屬性是不存在的)
 
4.在fragment的程式中,onCreateView會回傳一個view,這邊透過inflater,把fragment回傳給activity
=>因為findveiwbyid一般可以直接在activity中做是因為從AppCompatActivity中繼承了這個方法
=>但是我們現在是要在fragment中找id,並沒有繼承這個方法
=>另外,如果要findviewbyid,要寫在哪?
=>如果寫在onCreaterView中,不能寫在return後面,因為return後就結束程式了,所以 onCreaterView完成,在下面寫一個新的onStart(),而且不能直接findView,要先getView(),這個方法是從fragment繼承下來的
 
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_count, container, false);
}
 
public void onStart(){
    super.onStart();
    teamName=(TextView)getView().findViewById(R.id.teamName);
    score=(TextView)getView().findViewById(R.id.score);
}

 

(三)片段的生命週期
=>有些方法沒使用到,但仍會從父類別繼承
=>onCreateView()是用來建立新的view
 
 
1.因為規定fragment.xml中的onClick屬性所設定的method一定要寫在mainactivity.java中,所以三個計分button的onclick都要在 mainactivity.java中建立method=>可以點小燈泡=>產生onClick event handler
 
=>選擇產生的java
 
=>在mainactivity產生三個method
 
2.先找到fragment,再找到fragment中的 view
=>利用 getSupportFragmentManager()得到一個fragmentmanager(後面代表會回傳的內容)
=>再利用manager和fragment id來找到view
=>找到後會回傳一個fragment
=>要轉型成我們自己的CountFragment
public void add3p(View view) {
    CountFragment teamA= (CountFragment)getSupportFragmentManager().findFragmentById(R.id.teamA);
    teamA.score.setText("3");
}
 
(四)自訂按鈕風格
1.在values/styles.xml中修改,方法如下:
<style name="ButtonStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginBottom">8dp</item>
<item name="android:layout_marginTop">8dp</item>
<item name="android:textSize">@dimen/fontSize</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:background">@color/colorPrimary</item>
</style>
 
2.再去fragment.xml中指定要用的style
<Button
android:id="@+id/add3p"
android:text="+3 分球"
style="@style/ButtonStyle"
/>


●實作練習:xml

(一)activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.student.lab0302.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <fragment
            android:id="@+id/teamA"
            android:name="com.example.student.lab0302.CountFragment"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            tools:layout="@layout/fragment_count" />

        <!--中間的分隔線是一個view物件,寬度為1dp-->
        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:layout_marginTop="10dp"
            android:background="@android:color/darker_gray" />

        <fragment
            android:id="@+id/teamB"
            android:name="com.example.student.lab0302.CountFragment"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            tools:layout="@layout/fragment_count" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerInParent="true"
        android:orientation="horizontal">

        <Button
            android:id="@+id/clear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:background="@color/colorPrimary"
            android:onClick="clear"
            android:text="重置"
            android:textColor="@android:color/white"
            android:textSize="@dimen/fontSize" />
    </LinearLayout>

</RelativeLayout>

(二)fragment_count.xml

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.student.lab0302.CountFragment">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:id="@+id/teamName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="隊名"
            android:textSize="@dimen/fontSize" />

        <TextView
            android:id="@+id/score"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="0"
            android:textSize="60dp" />

        <!--刪除onclikc的設定全部委外-->
        <Button
            android:id="@+id/add3p"
            style="@style/ButtonStyle"
            android:text="+3 分球"
            android:textSize="@dimen/fontSize" />

        <Button
            android:id="@+id/add2p"
            style="@style/ButtonStyle"
            android:text="+2 分球" />

        <Button
            android:id="@+id/add1p"
            style="@style/ButtonStyle"
            android:text="罰球" />
    </LinearLayout>

</FrameLayout>

 

(三)h720dp-port/fragment_count.xml

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.student.lab0302.CountFragment">
    
    <!--因為高度720所以高度夠高,可以放圖片,如果在一般手機高度不夠高,就不顯示圖片-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <ImageView
            android:id="@+id/teamLogo"
            android:layout_width="250dp"
            android:layout_height="250dp"
            android:layout_gravity="center"
            android:layout_marginBottom="16dp"
            android:src="@drawable/hornets" />

        <TextView
            android:id="@+id/teamName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="隊名"
            android:textSize="@dimen/fontSize" />

        <TextView
            android:id="@+id/score"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="0"
            android:textSize="60sp" />
        <!--刪除onclikc的設定全部委外-->
        <Button
            android:id="@+id/add3p"
            style="@style/ButtonStyle"
            android:text="+3 分球" />

        <Button
            android:id="@+id/add2p"
            style="@style/ButtonStyle"
            android:text="+2 分球" />

        <Button
            android:id="@+id/add1p"
            style="@style/ButtonStyle"
            android:text="罰球" />
    </LinearLayout>

</FrameLayout>

●實作練習:Java Code

(一)MainActivity.java

public class MainActivity extends AppCompatActivity {
    CountFragment teamA;
    CountFragment teamB;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        teamA= (CountFragment)getSupportFragmentManager()
               .findFragmentById(R.id.teamA);
        teamB= (CountFragment)getSupportFragmentManager()
              .findFragmentById(R.id.teamB);
    }


    @Override
    //右鍵=>generate=>override method=>onStart()
    protected void onStart() {
        super.onStart();
        //不能放在onCreate中,因為mainactivityoncreate的時候fragmentview還沒產生
        //onCreate是在做設定開啟的畫面
        teamA.setName("黃蜂");
       teamB.setName("火箭");
       teamA.setTeamLogo(R.drawable.hornets);
       teamB.setTeamLogo(R.drawable.rockets);
    }

    public void clear(View v) {
        teamA.reset();
        teamB.reset();
    }
}

 

(二)CountFragment.java

//繼承View.OnClickListener介面,讓button按下時可以執行所有onclick方法
//fragmentoverride這個onclick方法
public class CountFragment extends Fragment 
    implements View.OnClickListener {
    private TextView teamName;
    private TextView score;
    //因為現在button要在fragment中直接使用,所以要先宣告
    private Button add3p, add2p, add1p;
    private ImageView teamLogo;

    public CountFragment() { //fragment無參數建構子
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, 
    ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_count, container, false);

    }

    public void onStart() {
        super.onStart();
        teamName = (TextView) getView().findViewById(R.id.teamName);
        teamLogo = (ImageView) getView().findViewById(R.id.teamLogo);
        score = (TextView) getView().findViewById(R.id.score);
        add3p = (Button) getView().findViewById(R.id.add3p);
        add2p = (Button) getView().findViewById(R.id.add2p);
        add1p = (Button) getView().findViewById(R.id.add1p);

        //要設定onClickListener監聽,監聽的對象是就是自己(this)
        add3p.setOnClickListener(this);
        add2p.setOnClickListener(this);
        add1p.setOnClickListener(this);
    }

    public void reset() {
        score.setText("0");
    }

    //因為CharSequence是個interface,
    //有很多classimplement它:String /StringBuilder/...
    public void setName(CharSequence name) {
        teamName.setText(name);
    }

    public void setTeamLogo(int id) {
        //因為小螢幕中不會有teamLogo,
        //所以小螢幕再找teamlogo id時會找不到而傳一個空值給teamlogo
        if (teamLogo != null) {
            //Sets a drawable as the content of this ImageView.
            teamLogo.setImageResource(id);
        }
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        int scoreCount = Integer.parseInt(score.getText().toString());
        switch (id) {
            //因為add3pbutton類別,
             //但idint,不能直接寫,所以要寫完整的R.id.add3p
            case R.id.add3p:
                score.setText(String.valueOf(scoreCount + 3));
                break;
            case R.id.add2p:
                score.setText(String.valueOf(scoreCount + 2));
                break;
            case R.id.add1p:
                score.setText(String.valueOf(scoreCount + 1));
                break;

        }
    }
}

 

*程式參考(gitHub):籃球記分板

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●實作練習:預期畫面 

Screenshot_2019-04-26-10-20-45.png     Button and StringBuilder     Button and StringBuilder

●程式說明:

1. checkbox繼承button所以會有onclick,也繼承textview,所以也會有textallcaps屬性,去查check box api

2. 用String builder來處理大量的字串顯示

=>字串就是字元的陣列

=>因為如果使用String會有個問題,String物件是不能改變的,當使用String每加一次字串,就會產生一個新的 String物件,這樣會越來越多垃圾,
舉例說明:String x="a"+"b"+"c"
=>"a"+"b"時會先產生一個新的String物件,用這個新的String物件再去加"c",又產生一個新的 String物件 ,這過程中多出來又用不到的 String物件就會變成垃圾,佔據記憶體空間
=>在java中如果String用+的,其實在程式內部就會自己用StringBuilder來做,但要記得做完以後要更新要先清空上一個舊的
 
3.StringBuilder method:
StringBuilder.delete(起始索引,結束索引):刪除字串時不包括結束索引的字串,delete(0,3)意思是刪除0~2之間的字
StringBuilder.append(新字串):將新字串加到原有字串的後面
 

4.可以自己寫測試程式,用android monitor來測試checkbox是否有正常運作

 

●實作練習:xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.student.lab0301.MainActivity">
    <!--toppings-->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        tools:ignore="MissingConstraints"
        tools:layout_editor_absoluteX="0dp"
        tools:layout_editor_absoluteY="0dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:text="Toppings"
            android:textSize="25sp"
            tools:ignore="HardcodedText" />

        <!--共用一個onClick method=>myClick-->
        <CheckBox
            android:id="@+id/veg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:onClick="myClick"
            android:text="泡菜"
            android:textSize="25sp" />
        />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingBottom="16dp"
            android:text="Quantity"
            android:textSize="25sp"
            tools:ignore="HardcodedText" />

        <!--quanity-->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <Button
                android:id="@+id/add"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:layout_marginRight="16dp"
                android:onClick="myClick"
                android:text="+"
                android:textSize="25sp"
                tools:ignore="HardcodedText,RtlHardcoded" />

            <TextView
                android:id="@+id/quantity"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:text="0"
                android:textColor="@android:color/black"
                android:textSize="25sp"
                tools:ignore="HardcodedText" />

            <Button
                android:id="@+id/subtract"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:layout_marginLeft="16dp"
                android:onClick="myClick"
                android:text="-"
                android:textSize="25sp"
                tools:ignore="HardcodedText,RtlHardcoded" />
        </LinearLayout>

        <!--price-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="price"
            android:textAllCaps="true"
            android:textSize="25sp"
            tools:ignore="HardcodedText" />

        <TextView
            android:id="@+id/price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_orange_light"
            android:text=""
            android:textColor="@android:color/black"
            android:textSize="25sp" />

        <Button
            android:id="@+id/send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="myClick"
            android:text="ok"
            android:textSize="25sp"
            tools:ignore="HardcodedText" />
    </LinearLayout>
</android.support.constraint.ConstraintLayout>

 

●實作練習:Java Code

package com.example.student.lab0301;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;

import java.text.NumberFormat;

public class MainActivity extends AppCompatActivity {
    TextView quantity;
    TextView price;
    CheckBox veg;

    //一般命名變數時,前面加個m代表整個類別可以使用的變數,設定初始值
    private int mQuantity=0;
    private int mPrice=50;
    //可給初始容量,如果超過會自動擴大,如果不給會用預設,大約16個字元
    private StringBuilder msg=new StringBuilder(100);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        quantity=(TextView)findViewById(R.id.quantity);
        price=(TextView)findViewById(R.id.price);
        veg=(CheckBox)findViewById(R.id.veg);
    }

    //送出
    public void send(View v){
        displaytotalPirce();
    }

    //顯示數量
    public void displayquantity(){
        String ntoString=String.valueOf(mQuantity);
        quantity.setText(ntoString);
    }

    //加數量
    public void add(View v){
        mQuantity++;
        displayquantity();
        price.setText("");
    }

    //減數量
    public void subtract(View v){
        if(mQuantity>0){
            mQuantity--;
            displayquantity();
        }
        price.setText("");

    }

    //計算總價
    public void displaytotalPirce(){
        int totalP=mQuantity*mPrice;

        //因為字串是字元的陣列,所以可以用.length()取得字串長度
        int len=msg.length();

        //如果沒有把原本的字串刪除,會連上一次顯示的字串一起出現
        msg.delete(0,len);

        //貨幣格式化=>可以出現$符號
        String pay= NumberFormat.getCurrencyInstance().format(totalP);

        if(mQuantity==0){
            if(veg.isChecked()) {
                msg.append("客戶:鳴人\n商品:臭豆腐\n是否要加泡菜?\n免費試吃");
            }else{
                msg.append("客戶:鳴人\n商品:臭豆腐\n是否要加泡菜?\n免費試吃");
            }
        }else{
            if(veg.isChecked()){
                msg.append("客戶:鳴人\n商品:臭豆腐\n是否要加泡菜?\n")
                        .append("數量:").append(mQuantity)
                        .append("\n總額:").append(pay)
                        .append("\n謝謝!");
            }else{
                msg.append("客戶:鳴人\n商品:臭豆腐\n是否要加泡菜?\n")
                        .append("數量:").append(mQuantity)
                        .append("\n總額:").append(pay)
                        .append("\n謝謝!");
            }
        }

        price.setText(msg);
    }
        //如果要把測試程式關閉,xml中的checkboxonclick也必須移除,不然會找不到出現閃退問題
        public void chk(View v){
            if(veg.isChecked()){
                System.out.println("yes");
            }else{
                System.out.println("no");
            }
        }

        //統一管理所有button
        public void myClick(View v){
            //因為每個button(veiw)元件都共用一個myClick()方法,所以要先取得要用的v(這邊是指正在使用的那個button)id
            //因為id是放在R檔中,裡面都是int
            int id=v.getId();
            switch(id){
                case R.id.veg:
                    chk(v);
                    break;
                case R.id.add:
                    add(v);
                    break;
                case R.id.subtract:
                    subtract(v);
                    break;
                case R.id.send:
                    send(v);
                    break;
            }
        }
}

 

*程式參考(gitHub):計算商品價格並加入免費小菜加點

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

«12 3