>

javacode

Friday, May 6, 2016

AlertDialog(對話框)的應用-Callback機制(回調函式)

 對話框
想必大家對這東東並不陌生,不論是應用程式或是網頁 都看得到他的身影

先看看Google的介紹

Google AlertDialog


AlterDialog有個限制 在對話框中的按鈕 最少為一個 最多三個

AlterDialog是利用建構者模式 

內部類別

  • 非靜態的內層類別,稱為內部類別
  • 內部類別的物件必須存在於外部類別物件當中
  • 內外層物件隱含交互參考,內層物件可參考到外層物件,外層物件可參考到內層物件

「instance of a class」的圖片搜尋結果

靜態巢狀類別

  • 內層類別宣告為靜態,稱為 靜態巢狀類別
  • 靜態巢狀類別物件可單獨建立

而AlertDialog則是利用了靜態巢狀類別這方式而設計的

Dialog
關於Dialog(三種按鈕:正面,負面,中立)



首先 
先將layout 設定為LinearLayout 
orientation設定為vertical(垂直)
<LinearLayout
     ......省略........
     android:orientation="vertical"
     ......................
     <TextView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:id="@+id/text"
         android:gravity="center"
         android:text="Hello World"
         android:textSize="18dp"/>
     <Button
         android:layout_width="match_parent"
         android:layout_height = "wrap_content"
         android:onClick="clickAlterDialog"
         android:textAllCaps="false"
         android:text="AlertDialog Ok"

MainActivity:

將要使用到的物件先宣告出來




我們的Button 利用好萊塢模式(onClick) 所以不需要特別在宣告
我們只需要實作出 代表onClick的方法就可


clickAlertDialog的方法表示 當按下Button時 會生成一個對話框 


這個onClick的方法是實現 DialogInterface.onClickListener 

對話框裡面按鈕所觸發的事件
以上的寫法個人是十分不喜歡 如果是多個對話框 在實作DialogInterface這方法裡就會有一堆的switch...
(光想...就十分頭痛)
所以只用兩個對話框來做這樣的示範...
給對話框一個reference,用reference去做判斷
這當中就會有些狀況發生 當Activity 被銷毀時 並不能保證 reference 參考到的對話框也會一同被銷毀,這時候它就會默默地消耗你的記憶體。 活在你看不到的地方...

以下的對話框都會使用匿名的方式 匿名的好處是使用完它就會被銷毀 不用考慮到他的生命週期
當然程式碼還是會看起來臃腫些..至於愛用哪種方式就見仁見智囉
Layout的宣告就不再贅述了..就是一直加個Button
第三個按鈕的效果圖




提供清單的Dialog


首先在 values裡新增一個新的 resouce file 取名自己命名



我命名為arrays arrays的內容:




綠色區塊為匿名內部類別 
String[] response為區域變數 在匿名內部類別的區域變數必須加上final這個修飾詞 不然的話在textView.setText(response[which])會有錯誤唷

項目可複選的Dialog



 先設定好 多選裡的事件
 再來就是創建 正項按鈕裡要做事件

項目多選一的Dialog



在setSingleChoiceItems 這事件(onClick)執行完後,which就會消失,所以要用一個欄位來記錄到底是點選了哪一個選項。
再將紀錄的選項值放入我們的陣列裡,這樣就會知道選擇了哪一個。


自訂Dialog 

新增Fragment 這是Google推薦的Dialog的用法





先設定好Fragment的Layout



android:fontFamily="sans-serif" 是等寬字體



修改MyDialogFragment

  • 變更繼承的對象為android.support.v4.app.DialogFragment
  • 由於這個DialogFragment並不是一般的Fragment,刪除onCreateView()方法
  • 覆寫DialogFragment的onCreateDialog()



覆寫onCreateDialog方法
在onCreateDialog動態產生畫面



在Activity建立 自訂的 Dialog



MainActivity:



效果圖




Fragment與Activity 通訊

與Activity通訊(Android Developers):為Activity建立回調函式(Callback)

類別圖:


Fragment 透過介面(interface)跟Activity溝通

  • 兩個類別要解除耦合(decoupling),中間透過介面來溝通


程式碼改變的不多 

MyDialogFragment:
多加個interface

在設定正項按鈕裡 將想要傳給Activity的資料注入interface裡的方法


利用回調函式 以後誰想要資料 只需要實作出 這個類的interface CallBack就可以取得資料

MainActivity:


這樣就取得了在DialogFragment editText裡的資料囉



再做稍稍延伸  想要紀錄 登入者登入的次數 同樣的登入者會做累加

我們將會利用Map來達到這樣的目的

先宣告個Map出來
private Map<String,Integer>map = new Map<>();

接著在onInputComplete裡做判斷



效果圖:



Github:程式碼

Tuesday, May 3, 2016

面試題目-動態加載Button


母親節檔期忙到不行.....腿和手默默發出無聲地顫抖抗議呀!!(餐飲業好可怕呀~~)...............遲來的更新m(_ _)m

    面試題目
試著做出 畫面有三個Button 亂數跑這三個Button
跑到的Button會有個 X , 當按下 X , X會消失 這時候會有個TextView紀錄案中多少次
這個做出來後
請延伸為9個按鈕 放入List裡面 將按鈕數據化 不可以使用switch去判斷

最開始三個不難做出來了,但延伸的問題讓我卡住,初學者的我來說 ,基本功沒很到位 ,稍稍做了功課後 實現了一下...

效果圖:

首先先分析 自己會需要什麼東東
1.TextView,GridLayout 用來放9個Button(這9個按鈕 我們會用動態產生出來),一個開始Button
2.不是IO或是費時的工作不要用Thread,用Handler給UI Thread執行
3.實現onClickListener

話不多說 直接實現看看

Layout:RelativeLayout

<ReliativeLayout
  .......
  .......省略......

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_centerHorizontal="true"
       android:text="次數"
       android:id="@+id/count"
       android:textSize="24dp"/>
   <Button
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
       android:layout_centerHorizontal="true"
       android:id="@+id/start"
       android:text="start"
       android:onClick="start"/>
    <GridLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:columnCount="3"
       android:rowCount="3"
       android:id="@+id/gridlayout"/>
</RelativeLayout>

MainActivity:


public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private GridLayout gridLayout;
    private TextView textView;
    private Handler handler;
    private int counter = 0;
    private List<Button> list = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initButtons();
    }
    /*初始化*/
    public void initButtons() {
        textView = (TextView) findViewById(R.id.count);
        handler = new Handler();
        gridLayout = (GridLayout) findViewById(R.id.gridlayout);
        /*動態加載Button*/        
            for (int i = 0; i < 9; i++) {
            Button button = new Button(this);
            button.setOnClickListener(this);
            /*將Button放入List裡*/            
            list.add(button);
            /*將List放入GridLayout*/            
            gridLayout.addView(button);
        }
    }
    /*啟動Runnable*/    
    public void Start(View view) {
        textView.setText("次數 :");
        counter = 0;
        handler.post(x_random_runnable);
        handler.postDelayed(x_random_runnableStop, 10000);
    }
    private X_Random_Runnable x_random_runnable = new X_Random_Runnable();
    private X_Random_RunnableStop x_random_runnableStop = new X_Random_RunnableStop();
    /*實現onClickListener*/    
    @Override
    public void onClick(View v) {
        /*判斷按下的Button是不是 X*/
        if ("X".equals(((Button) v).getText().toString())) {
            ++counter;
            textView.setText("擊中" + counter + "次數");
            initButtonSetText();
        }
    }
    /*讓X消失*/
    private void initButtonSetText() {
        for(int i=0;i<list.size();i++){
            list.get(i).setText("");
        }
    }

    /*實現Runnable 亂數跑 9個Button*/
    private class X_Random_Runnable implements Runnable {

        @Override
        public void run() {
            int index = (int) (Math.random() * list.size());
            for (int i = 0; i < list.size(); i++) {
                if (i == index) {
                    list.get(i).setText("X");
                } else {
                    list.get(i).setText("");
                }
            }
            handler.postDelayed(this, 1500);
        }
    }
    /*停止Runnable*/
    private class X_Random_RunnableStop implements Runnable {

        @Override
        public void run() {
            handler.removeCallbacks(x_random_runnable);
        }
    }
}

GitHub
https://github.com/Brian43/MyIntervewTest