<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 第六章:Reminders實驗:第二部分 > 譯者:[qiangxcn](http://ask.android-studio.org/?/people/qiangxcn) > 來源:[Learn Android Studio 漢化教程 第六章:Reminders實驗:第二部分](http://ask.android-studio.org/?/article/979) 這章涵括了通過對話框捕獲用戶輸入。也繼續演示適配器及SQLite數據庫的使用。這章里,我們將完成從第五章開始的例子。 ## 增加/刪除提醒 第五章里這個例子的屏幕還沒有任何提醒。為了讓布局看到提醒清單,當app啟動時加載些提醒的例子上去,這是很有用的。如果你想挑戰這章處理過程,比較下清單6-1和你的代碼。清單6-1檢查是否有保存的實例,如果有,處理將設置例子數據。為此,代碼調用了些DatabaseAdapter的方法;一個是清除所有的提醒,另一個則是加入些提醒。 Listing 6-1. Add Some Example Reminders ```java public class RemindersActivity extends ActionBarActivity { private ListView mListView; private RemindersDbAdapter mDbAdapter; private RemindersSimpleCursorAdapter mCursorAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_reminders); mListView = (ListView) findViewById(R.id.reminders_list_view); mListView.setDivider(null); mDbAdapter = new RemindersDbAdapter(this); mDbAdapter.open(); if (savedInstanceState == null) { //Clear all data mDbAdapter.deleteAllReminders(); //Add some data mDbAdapter.createReminder("Buy Learn Android Studio", true); mDbAdapter.createReminder("Send Dad birthday gift", false); mDbAdapter.createReminder("Dinner at the Gage on Friday", false); mDbAdapter.createReminder("String squash racket", false); mDbAdapter.createReminder("Shovel and salt walkways", false); mDbAdapter.createReminder("Prepare Advanced Android syllabus", true); mDbAdapter.createReminder("Buy new office chair", false); mDbAdapter.createReminder("Call Auto-body shop for quote", false); mDbAdapter.createReminder("Renew membership to club", false); mDbAdapter.createReminder("Buy new Galaxy Android phone", true); mDbAdapter.createReminder("Sell old Android phone - auction", false); mDbAdapter.createReminder("Buy new paddles for kayaks", false); mDbAdapter.createReminder("Call accountant about tax returns", false); mDbAdapter.createReminder("Buy 300,000 shares of Google", false); mDbAdapter.createReminder("Call the Dalai Lama back", true); } //Removed remaining method code for brevity... } //Removed remaining method code for brevity... } ``` 有幾個`createReminder()`方法的調用,每個都是用一個字符串作提醒文本,以及一個布爾值標記提醒是否重要。我們設置一些實體值讓顯示好看點。選中`createReminder()`方法調用的代碼塊按以`Ctrl+Alt+M | Cmd+Alt+M`汲取方法,如圖6-1示。這是一個通過重構菜單和快捷鍵結合的重構操作。輸入`insertSomeReminders`作為方法名并確認。這些代碼塊將以析出的方法代替,這些代碼塊將在方法體里了。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c5ae5c8.png) 圖6-1 析出方法對話框,創建一個`insertSomeReminders()`方法 運行app看到的界面,擁有提醒例子了。你的app應該看起來象圖6-2的截屏那樣。有些提醒顯示綠色的行選項卡,而那些重要的提醒則顯示橙色行選項卡。提交你的更改到Git,備注Adds Example reminders。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c5cf111.png) 圖6-2 插入了提醒例子的實時運行 ## 響應用戶的互動 沒有app不響應輸入。在這節,你將加入響應點擊事件的邏輯并且最終允許用戶編輯獨立的提醒。在app里的主要元素是`ListView`,一個Android `View`的子類。直致此刻,除了把它放到布局里,你還沒做過其它的什么。`android.view.View`是所有你看到的所有屏幕元素的超類。 把清單6-2的代碼加到`RemindersActivity`的`onCreate()`方法后面,即在方法結束花括號之前,并解決導入類的問題。這是一個匿名內部類實現`OnItemClickListener`接口,它只有一個方法,`onItemClicked()`。這個對象將用于你互動與它所跟蹤的`ListView`元素的實時運行。當用戶點擊`ListView`時,匿名內部類的`onCreate()`方法將被調用。我們定義一個吐司,一個Android SDK的類。調用`Toast.makeText()`將導致在屏幕上彈出一個小菜單,顯示出你傳送給方法的文本。你可以看到清單6-2的代碼,作為快速正確使用吐司的指引。 注意:吐司信息可能在一些設備上被隱藏。另一個替代途徑是記錄一個日志信息,用Android的日志記錄器,那個在第十二章會有祥述。 Listing 6-2. Set an `OnItemClickListener` with a `Toast` ```java //when we click an individual item in the listview mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(RemindersActivity.this, "clicked " + position, Toast.LENGTH_SHORT).show(); } }); ``` 點擊屏幕第一個提醒將調用`onItemClick()`方法,在清單里的位置是0,所以索引是0。這個邏輯將彈出位置信息的文本,如圖6-3所示。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c5f360a.png) 圖6-3 點擊第一條提醒彈出的吐司信息 ## 用戶對話框 大家所熟悉的一些點擊事件,現在你可增強點擊監聽為顯示一個對話框。用清單6-3的代碼替換所有的`onItemClick()`方法。解決導入時,請用`android.support.v7.app.AlertDialog`類。 Listing 6-3. `onItemClick( )` Modifications to Allow Edit/Delete ```java public void onItemClick(AdapterView<?> parent, View view, final int masterListPosition, long id) { AlertDialog.Builder builder = new AlertDialog.Builder(RemindersActivity.this); ListView modeListView = new ListView(RemindersActivity.this); String[] modes = new String[] { "Edit Reminder", "Delete Reminder" }; ArrayAdapter<String> modeAdapter = new ArrayAdapter<>(RemindersActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, modes); modeListView.setAdapter(modeAdapter); builder.setView(modeListView); final Dialog dialog = builder.create(); dialog.show(); modeListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //edit reminder if (position == 0) { Toast.makeText(RemindersActivity.this, "edit " + masterListPosition, Toast.LENGTH_SHORT).show(); //delete reminder } else { Toast.makeText(RemindersActivity.this, "delete " + masterListPosition, Toast.LENGTH_SHORT).show(); } dialog.dismiss(); } }); } ``` 在處理代碼里你看到了另Android類在工作,`AlertDialog.Builder`。這個類創建器嵌入在`AlertDialog`類里,是個靜態類,它用于創建`AlertDialog`。 在這個實例里的代碼遠超于創建一個`ListView`以及用`ArrayAdapter`喂入條目到`ListVite`。你可能回想起第五章的這種模型。這個章節建立一個有兩個潛在元素(選項)的數組,編輯提醒和刪除提醒,在傳送到`ListView`之前,這個是,輪流地,傳送給`AlertDialog.Builder`。這個創建器然后用這些選項清單創建并顯示一個對話框。 注意下代碼清單6-3最后的選擇部分。有點象之前的`OnItemClickListener()`;不管怎樣,我們附加了一個`modeListView`的監聽器,那個在當前`OnItemClickListener`里創建的。你看到的是帶有`OnItemClickListener`的`ListView`(指的是`activity_reminders.xml`里的`reminders_list_view`),(譯者:在它的`onItemClick`方法里)創建了另一個`modeListView`還有另一個嵌入的`OnItemClickListener`來響應來自`modeListView`的選項點擊事件。 內嵌的點擊監聽器彈出一個吐司信息來指示是編輯還是刪除所點擊的條目。它也重命名來自外部調用者`OnItemClickListener`的位置參數叫做`masterListPosition`來區分內置的`OnItemClickListener`的位置參數。這個`masterListPosition`用于吐司指明哪條提醒被用于可能的編輯或刪除。最后,`dialog.dismiss()`方法調用于點擊監聽器,用來完全移除對話框。 運行一下來測試新特性如圖6-4所示。點擊一條提醒接著在彈出對話框再點編輯或刪除。如果吐司里報告的提醒位置和你點擊的對不上,再確認一下你吐司里追加`masterListPosition`值而不是`postion`。按`Ctrl+K | Cmd+K`提交更改到Git,并附上信息Adds a ListView dialog for individual list items。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c618031.png) 圖6-4 模擬刪除一條提醒 ## 提供多選上下文菜單 隨著這個app逐漸成形,現在將達成這種特性:在一次操作里允許多選提醒條目用于編輯。這種特性只能在API 11或更高版本上才有效。你將通過使用資源載入協定來有條件地達成這種特性。這個處理將在這章稍后解釋并且第8章有所有的細節。你也將需要包含一個運行時檢查看看是否支持這種特性。 為提醒行條目創建另一個備用的布局。打開項目工具窗口在資源夾上右擊帶出來的上下文。選擇新的Android資源文件命名為r`eminders_row`,如圖6-5示。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c647296.png) ![](https://box.kancloud.cn/2016-08-06_57a5d3c670dbe.png) 圖6-5 新資源文件`reminders_row` 選擇資源類型為布局,這樣就自動改變目錄名為`layout`。在有效限定詞部分選擇相應的版本然后雙擊(`>>`)雙V紋章按鈕增加到選擇的限定詞里。輸入11作為平臺API級別并注意到目錄名更新了,并反映了選擇的限定詞版本。那叫資源限定并且它們整合于運行時里,讓你可以為特別的設備和平臺版本定制你的用戶界面。按回車(或點OK)接受這個新資源限定目錄并繼續。如果你打開項目工具窗并設為Android示圖,如圖6-6,你將看到`layout`文件夾下所有的`reminders_row`布局文件在一起。還有,Android示圖的項目工具窗讓相關聯的文件聚集在一起使你有效地管理它們。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c69e2cb.png) 圖6-6 聚集的布局 復制整個原始的`reminders_row`布局并粘貼到剛新建版本11的布局里。現在修改內層的水平線性布局的背景色屬性如下: ```xml android:background="?android:attr/activatedBackgroundIndicator" ``` 這個值分配背景色屬性帶前綴`?android:attr/`,這是參考定義于Android SDK里的一種風格。Android SDK提供了很多這樣的預定義屬性,并且你可以使用它們到你的app上。在多選模式時`activatedBackgroundIndicator`屬性使用了系統定義的有效背景色。 ## 目標于早期的SDK 現在你將學習如何引入一個平臺依賴的特性。打開項目工具窗并打開在Gradle劇本區下面的app模塊 `build.gradle`文件(它會在第二個入口里)。Gradle文件含有編譯的構建邏輯和app的包裝。參照你的app所支持的平臺所有配置存在于這些特別的文件里(第十三章深度探索了Gradle構建系統)。注意到最低SDK版本設置為8,這讓你的app可以運行在99%的Android設備上。現在我們將創建的這個特性需要最低SDK版本是11。涵括這節的代碼和特性將允許用戶運行在SDK11或更高版本帶來的更先進的特性,叫上下文動作模式。而且,低于SDK11的將不會有這個特性,但更重要的是,他們的app不會因此而崩潰。 ## 加入上下文動作模式 接下來介紹的多選模式的上下文動作模式菜單,是一個動作清單可用于所有選擇項的上下文。加載一個新的菜單資源,在`res/menu`目錄上右擊選擇`New ? Menu`資源文件并命名為`cam_menu`。以下列代碼清單完成它: ```xml <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android";> <item android:id="@+id/menu_item_delete_reminder" android:icon="@android:drawable/ic_menu_delete" android:title="delete" /> </menu> ``` 這個資源文件為上下文菜單定義了唯一的刪除動作條目。這里你也正用了一點不同的屬性值。這個特別的屬性象之前的背景色屬性一樣也是訪問Android內建的缺省值。不管怎樣,在那前綴`?android:attr/ prefix`只用于參考風格屬性。在這用在屬性上的語法參照一個稍有不同的格式。用at符號`@`觸發一個到資源值查詢的命名空間。你可以用這種方式訪問變量命名空間。Android命名空間是所有內建Android值所在的地方。用這個命名空間是多種變量資源所存在的如`drawable`,`string`以及布局。當你用了`@+id`為前綴,它會創建一個新的`ID`在你的項目的`R.java`文件里,且當你用到`@id`前綴,它會查找Andriod SDK的`R.java`文件存在的`ID`。這個例子里定義了一個新的`ID`名,`menu_item_delete_reminder`,它結合于菜單選項。它也從`android:drawable`命名空間里拉出一個圖標,作為它的圖標。 用新的上下文菜單和一個備用的布局運行于API 11或更高版本,你可以加載一個有條件的檢查以允許帶有上下文動作菜單的多選模式。打開`RemindersActivity`并加上下面的代碼到`onCreate`方法的后面。 ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { } ``` 構建類從`android.os`包里導入并且給你訪問一系列的常量值,那些可用于以指定的API級別來匹配設備。在這個例子里,你期望API級別等于或高于HONEYCOMB而它實際包含整數11。把清單6-4的代碼插入到剛定義的塊里。IF塊保護了運行OS低于HONEYCOMB的系統不讓這個app崩潰。 Listing 6-4. `MultiChoiceModeListener` Example ```java mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); mListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { } @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.cam_menu, menu); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.menu_item_delete_reminder: for (int nC = mCursorAdapter.getCount() - 1; nC >= 0; nC--) { if (mListView.isItemChecked(nC)) { mDbAdapter.deleteReminderById(getIdFromPosition(nC)); } } mode.finish(); mCursorAdapter.changeCursor(mDbAdapter.fetchAllReminders()); return true; } return false; } @Override public void onDestroyActionMode(ActionMode mode) { } }); ``` 解決所有導入的問題。你將注意到`getIdFromPosition()`沒有定義并標為紅色(錯誤)。把光標放在這個方法上并按勞取酬`Alt_Enter`調用`IntelliSense`并選擇創建方法。選擇`RemindersActivity`作為目標類。選擇整型作為返回類型。用清單6-5的代碼完成這個方法。 Listing 6-5. `getIdFromPosition()` method ```java private int getIdFromPosition(int nC) { return (int)mCursorAdapter.getItemId(nC); } ``` 此處理邏輯定義了一個`MultiChoiceModeListener`并把它附到L`istView`。無論何時你長按ListView的一個條目時,運行時調用`onCreateActionMode()`方法在`MultiChoiceModeListener`上。如果方法返回真值,就進入多選動作模式。這里重寫方法的邏輯填充了一個上下文菜單用于顯示動作條。使用多選動作模式的好處是你可以選擇多行。一次點擊選中了某個條目,接下來再點擊則會去選這個條目。當你點擊上下文菜單里的每個條目,運行時將帶著被點的條目調用`onActionItemClicked()`方法。 在這個方法里,通過比較`itemId`和你加到菜單項里的刪除元素的`id`,檢查下刪除條目是否被點擊了。(看看在本節開始時所描述有關刪除條目`ID`的XML清單)。如果這個條目被選,輪詢所有的清單條目并要求`mDbAdapter`來刪除它們。在刪除所選條目后,邏輯調用動作模式對象`finish()`方法,這將禁止多選動作模式并返回`ListView`到普通模式。接下來你調用`fetchAllReminders()`方法眾數據庫重新裝載所有的提醒條并傳送在`mCursorAdapter`對象`changeCursor`方法所返回的游標。最后,方法返回真值來表明動作被正確地處理了。所有其它的沒被正確處理的邏輯,方法返回假,表明一些其它的事件監聽器可能處理了這個點擊事件。 Android Studio將高亮一堆錯誤語句,因為你正使用的API無效或低于Honeycomb。這外錯誤生成于Lint,一個狀態分析工具內建于Android SDK并完全整合在Android Studio里。你需要加上下面的聲明在`RemindersActivity.onCreate()`方法里,在`@Override`聲明之上或之下都行,而且要目標API解決導入問題: ```java @TargetApi(Build.VERSION_CODES.HONEYCOMB) ``` 這個特別的聲明告訴Lint欺騙方法調用是提供的API級別的目標,不管構建配置所指定的。提交更改到Git用Adds Contextual Action Mode with context action menu作注釋。圖6-7描寫了你可能看到的新特性。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c6c4055.png) 圖6-7 允許多選模式 ## Implementing Add, Edit, and Delete 迄今為止,你已經添加了從清單里刪除提醒的邏輯。這個邏輯在上下文動作模式里也可以有效執行。目前還無法插入新提醒或編輯現有的提醒。無論如何,你將創建一個用戶自定義對話框或添加提醒,另一個用來編輯現有的提醒。最終,你將綁定這些對話框到`RemindersDbAdapter`。 在處理這個之前,先添加一些新的顏色。把這它們加到`colors.xml`文件里: ```xml <color name="light_grey">#bababa</color> <color name="black">#000000</color> <color name="blue">#ff1118ff</color> ``` 注意:通常,你的app可能有一個全面的顏色風格,這將保證所有屏幕和對話框的一致性。無論如何,顏色風格超出了這個簡單例子的范圍了。 ## 策劃一個用戶對話框 開發的一個好習慣是:以簡單工具優于執行它來描繪你的用戶界面。這樣在引入任何代碼之膠,讓你圖形化元素如何適合屏幕。你可用一個編輯器如inkscape,它是跨平臺的,或者你可以用筆記本的紙張和鉛筆。在移動商務里,這些描繪稱作線框圖(wireframe)。 圖6-8是我們的用戶對話框的插圖,完成于inkscape。這個線框圖有意不正式,來強調元素的擺放好過一個精準的外觀和感覺。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c6e4476.png) 圖6-8 線框圖描繪用戶自定義對話框 注意:這本書里的一些用戶自定義的繪圖和線框圖正是用lnkspace創建的,一個多平臺向量圖形編輯器。在`www.inkscape.org`上,它是免費的。 把線框圖就在那了,你可以開始計劃如何排列屏幕的元素。因為大多數元素從上排到下,在最外層用一個豎直線性布局,這是最顯然的選擇。不管怎樣,底下的兩個按鈕并排在一起。這樣你可以用一個水平線性布局放在前面的豎直線性布局里。圖6-9加上一些聲明來描繪和高亮這些內嵌的元件。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c707183.png) 圖6-9 線框圖描繪`widget`標簽 ## 從策劃到代碼 隨著線框圖在那,盡量用圖形化設計器來開發布局。開始在res目錄上右擊并選擇創建一個新的Android資源文件然后命名為`dialog_custom`,資源類型為布局資源。以線性布局作為根元素,完成對話框。接著我們的線框圖,從調色板拖放視圖控件到這個平臺上。清單6-6包含了這個完成的XML布局文件,并帶有將在代碼中用到的`ID`值。 Listing 6-6. Completed `dialog_custom.xml` ```xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/custom_root_layout" android:layout_width="300dp" android:layout_height="fill_parent" android:background="@color/green" android:orientation="vertical" > <TextView android:id="@+id/custom_title" android:layout_width="fill_parent" android:layout_height="60dp" android:gravity="center_vertical" android:padding="10dp" android:text="New Reminder:" android:textColor="@color/white" android:textSize="24sp" /> <EditText android:id="@+id/custom_edit_reminder" android:layout_width="fill_parent" android:layout_height="100dp" android:layout_margin="4dp" android:background="@color/light_grey" android:gravity="start" android:textColor="@color/black"> <requestFocus /> </EditText> <CheckBox android:id="@+id/custom_check_box" android:layout_width="fill_parent" android:layout_height="30dp" android:layout_margin="4dp" android:background="@color/black" android:paddingLeft="32dp" android:text="Important" android:textColor="@color/white" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> <Button android:id="@+id/custom_button_cancel" android:layout_width="0dp" android:layout_height="60dp" android:layout_weight="50" android:text="Cancel" android:textColor="@color/white" /> <Button android:id="@+id/custom_button_commit" android:layout_width="0dp" android:layout_height="60dp" android:layout_weight="50" android:text="Commit" android:textColor="@color/white" /> </LinearLayout> </LinearLayout> ``` ## 生成一個用戶對話框 現在`RemindersActivity`里用完成的對話框布局了。清單6-7實現了一個新的`fireCcustomDialog()`方法。把這些代碼放到`RemindersActivit`文件里去,僅在`onCreateOptonsMenu()`方法上面,并解決好導入的問題。 Listing 6-7. The `fireCustomDialog( )` Method ```java private void fireCustomDialog(final Reminder reminder){ // custom dialog final Dialog dialog = new Dialog(this); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setContentView(R.layout.dialog_custom); TextView titleView = (TextView) dialog.findViewById(R.id.custom_title); final EditText editCustom = (EditText) dialog.findViewById(R.id.custom_edit_reminder); Button commitButton = (Button) dialog.findViewById(R.id.custom_button_commit); final CheckBox checkBox = (CheckBox) dialog.findViewById(R.id.custom_check_box); LinearLayout rootLayout = (LinearLayout) dialog.findViewById(R.id.custom_root_layout); final boolean isEditOperation = (reminder != null); //this is for an edit if (isEditOperation){ titleView.setText("Edit Reminder"); checkBox.setChecked(reminder.getImportant() == 1); editCustom.setText(reminder.getContent()); rootLayout.setBackgroundColor(getResources().getColor(R.color.blue)); } commitButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String reminderText = editCustom.getText().toString(); if (isEditOperation) { Reminder reminderEdited = new Reminder(reminder.getId(), reminderText, checkBox.isChecked() ? 1 : 0); mDbAdapter.updateReminder(reminderEdited); //this is for new reminder } else { mDbAdapter.createReminder(reminderText, checkBox.isChecked()); } mCursorAdapter.changeCursor(mDbAdapter.fetchAllReminders()); dialog.dismiss(); } }); Button buttonCancel = (Button) dialog.findViewById(R.id.custom_button_cancel); buttonCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); dialog.show(); } ``` `fireCustomDialog( )`方法將用于插入和編輯,就算它們間有少許不同。方法的開始三行創建了一個Android對話框,沒有標題并填充清單6-6的布局。`fireCustomDialog( )`方法接著從這個布局里查找所有重要的元素并儲存到本地變量里。然后方法查看reminder參數是否為空,設置一個`isEditOperation`布爾變量。如果說有一個提醒被傳入(或者值為不空),方法會假設這不是一個編輯操作并把這個變量設為假;否則,設為真。如果調用`fireCustomDialog( )`方法的是一個編輯操作,標題設為`Edit Reminder`而且`CheckBox`和`EditText`用提醒參數的值來設定。這個方法也設置了最外層容器布局的背景色為藍色,為了從視覺上區別插入對話框和編輯對話框。 接下來的幾行由一個代碼塊組成,為提交按鈕設置及定義一個`OnClickListener`。這個監聽器響應點擊事件,更新數據庫。再次,`isEditOperation()`被檢查了,如果編輯操作進行中,那么一個新提醒創建了,用來自提醒參數的`ID`以及`EditTex`的值還有在屏的復選框值。這個提醒傳送給`mDbAdapter`,通過`updateReminder()`方法。 如果編輯沒有進行,這個邏輯查詢`mDbAdapter`來創建一個新的提醒到數據庫,用`EditText`的值還有在屏的復選框值。在無論是更新或創建調用后,所有提醒通過`mCursorAdapter.changeCursor()`方法會重新裝載.這個邏輯有點象之前添加的清單6-5代碼。點擊監聽器在提醒重新裝載后解散對話框。 在配置提交按鈕的點擊行為后,這個例子設置了另一個取消按鈕的監聽器。這個監聽器只是簡單地解散對話框。所有按鈕的行為定義后,這個例子結束于顯示用戶對話框。 現在你可以為在`onCreate()`方法里的`modeListView`用這個新方法在`OnItemClickListener`中。為這個監聽器找到`onItemClick()`方法用下面的代碼替換原來所有代碼。 ```java public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //edit reminder if (position == 0) { int nId = getIdFromPosition(masterListPosition); Reminder reminder = mDbAdapter.fetchReminderById(nId); fireCustomDialog(reminder); //delete reminder } else { mDbAdapter.deleteReminderById(getIdFromPosition(masterListPosition)); mCursorAdapter.changeCursor(mDbAdapter.fetchAllReminders()); } dialog.dismiss(); } ``` 為了編輯提醒,去掉`Toast.makeText()`調用,替換為用`ListView`位置來找到提醒的調用。這價目提醒然后被傳送到`fireCustomDialog()`方法來觸發編輯行為。為刪除提醒,用和清單6-5一樣的代碼邏輯。再次,`mDbAdapter.deleteReminderById()`用于刪除提醒,并且`changeCursor()`用于從`mDbAdapter.fetchAllReminders()`調用中返回游標。 找到`onOptionsItemSelected()`方法,在`RemindersActivity.java`文件很底部的地方,編輯它如清單6-8。 Listing 6-8. `onOptionsItemSelected` Definition ```java public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_new: //create new Reminder fireCustomDialog(null); return true; case R.id.action_exit: finish(); return true; default: return false; } } ``` 這里,當你選擇了菜單項是`action_new`,簡單地調用了`fireCustomDialog()`。傳送一個空值給它,象之前提及的空值檢查并設置`isEditOperation`為假,然后征用一個新提醒對話框。運行app檢查下新特性。你會看到新的用戶對話框。當創建新提醒時,你將看到一個綠色對話框,而編輯提醒時是一個藍色的對話框,如圖6-10和6-11所分別對應的。測試菜單項確保創建和刪除操作功能象它們應該的那樣。提交更改到Git,附上提交信息:Adds database Create, Read, Update, and Delete support with custom dialogs。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c7219a4.png) 圖6-10 新提醒對話框 ![](https://box.kancloud.cn/2016-08-06_57a5d3c745166.png) 圖6-11 編輯提醒對話框 ## 加上用戶圖標 所有的特性都放置好了,你可以加上一個用戶圖標作為完成點綴。可以用任何圖形編輯器來創建它,或者如果你不喜歡圖形編輯,從網上下點免費的。我們的例子放置ic_launcher圖標,它創建于Inkscape。找開項目工具窗并右擊`res/mipmap`目錄。選`New ? Image Asset`。將看到圖6-12那樣的對話框。點擊`Image File:`選擇框最右邊的省略號圖標,導航到你要的圖片位置并插入進來。讓其他的設置如圖6-13所示。點下一步,接著點完成。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c7627a2.png) 圖6-12 新圖片資源對話框 有不少目錄使用了`mipmap`這個名字。這些目錄每個都有著后綴,那個指派屏幕尺寸限定。Android運行時將從特別的目錄里拉出資源,依照app所運行設備屏幕的解析度。資源夾和它們的后綴在第8章將有祥解。 插入下面的幾行代碼到`onCreate()`方法里,在填充布局之后,即`setContentView(R.layout.activity_reminders);`。這些代碼將顯示用戶圖標在你的動作條里: ```java ActionBar actionBar = getSupportActionBar(); actionBar.setHomeButtonEnabled(true); actionBar.setDisplayShowHomeEnabled(true); actionBar.setIcon(R.mipmap.ic_launcher); ``` 運行代碼,將看到用戶圖標在動作條里。圖6-13展示了以用戶圖標運行的app。 ![](https://box.kancloud.cn/2016-08-06_57a5d3c798716.png) 圖6-13 動作條的用戶圖標 按`Ctrl+K | Cmd+K`提交更改到Git,以Adds a custom icon作為提交信息。 ## 小結 恭喜!你已實現了使用Android Studio完成的第一個Android app。在這個過程里,你學會了用圖形化設計器編輯XML布局文件。你也學會了如何用文本模式編輯一個行XML布局。這章展示了在支持的平臺上如何有條件地實現上下文動作模式。最后,你看到了如何加載一個用戶圖標到不同的分辨率的屏幕上。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看