編輯:關於Android編程
適配器視圖AdapterView繼承自視圖組ViewGroup (一個包含其他子視圖的容器),它是需要適配器的視圖容器,常用的適配器視圖有 Spinner、ListView、GridView、Gallery、ViewPager。
適配器視圖是一種特殊類型的視圖組。與其他的視圖組類型一樣,適配器視圖的主要用途是表示一個包含子視圖的視圖。因此,適配器視圖確定了其子視圖布局的表現形式。此外,它還在關系中扮演了其他一些特殊角色:適配器視圖控制屏幕上所顯示的項目數量:這是一個非常關鍵的認識。雖然適配器對需要顯示的數據綁定視圖的移交進行控制,但卻由適配器視圖來告訴適配器應該生成多少視圖。這一點在數據綁定過程中至關重要,因為它可以考慮到各種屏幕大小,同時幫助內存管理。後面將介紹更多這方面的內容。
適配器視圖包含對項目選擇響應事件,以及請求綁定數據實體的機制:當使用適配器視圖時,可以根據用戶交互簡單地構建響應布局。此外,還可以非常容易地訪問相應的數據項,而不必通過極端方法來查找原始數據項。
適配器視圖可以支持使其子視圖具有動畫效果的邏輯:當使用諸如垂直或者水平滾動列表之類的控件時,如果可以引入一些平滑的動畫效果那就更好了,這樣可以改善用戶的體驗。可從ViewGroup類中繼承該操作。
適配器在視圖與數據之間扮演了一個橋梁的作用,它將數據中的每一項數據轉化為適配器視圖可以使用的每一個視圖項。
該圖中,左側類圖是關於適配器Adapter的,可以看到BaseAdapter抽象類實現了ListAdapter和SpinnerAdapter這兩個接口,在我們自定義的適配器中,就是要繼承BaseAdapter這個類。右側類圖是關於適配器視圖AdapterView的,最下面的那四個具體類Spinner、Gallery、ListView、GridView就是常用的適配器視圖。
下面講解幾個實例,練習使用Spinner和ListView適配器視圖。
Spinner (下拉列表)有兩種定義方式
1.使用靜態資源使用資源文件中的字符串數組,數據是固定的;
這是最常用、最簡單的方式。
2.使用適配器
使用數組適配器(ArrayAdapter),數據長度可變。
String[] skills =getResources().getStringArray(R.array.skills);
在主活動Java代碼中,通過id獲取到XML布局文件定義的Spinner適配器視圖控件,並給它設置下拉列表項被選擇監聽事件,spinner.setOnItemSelectedListener(),將用戶選擇的下拉選項,顯示在一個TextView上。
在主活動.java文件中,先聲明適配器視圖Spinner、數據和適配器,創建好適配器,並給Spinner設置適配器,適配器將視圖和數據一項一項的聯系起來。上圖可見,數據是一個ArrayList,此次數據是可以變化的,初始化的時候,給它add()了幾個數據,設置該數據可以從網絡上獲得。
XML布局文件--顯示效果如圖:
實現功能:從下拉列表中,可以刪除選中的項,也可以增加新項。
<RelativeLayout 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" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="專業技能" android:id="@+id/textView" android:layout_alignParentTop="true" android:layout_alignBottom="@+id/spinner" android:gravity="center_vertical" android:layout_marginRight="16dp"/> <Spinner android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/spinner" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/button_remove" android:layout_toEndOf="@+id/button_remove"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="刪除選中項" android:id="@+id/button_remove" android:layout_below="@+id/spinner" android:onClick="doRemove"/> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/editText" android:singleLine="true" android:hint="已掌握的的技能" android:layout_below="@+id/button_remove" android:layout_toRightOf="@+id/button_add" android:layout_toEndOf="@+id/button_add"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="添加新選項" android:id="@+id/button_add" android:layout_alignBottom="@+id/editText" android:onClick="doAdd"/>
RelativeLayout>
package com.example.administrator.adapterdemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; import android.widget.Toast; import java.util.ArrayList; /** * 使用Spinner適配器視圖 * 動態進行數據的處理操作 */ public class Spinner2Activity extends AppCompatActivity { // 視圖 private Spinner spinner; // 數據 private ArrayList data; // 適配器:視圖與數據之間的橋 private ArrayAdapter adapter; private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_spinner2); spinner = (Spinner) findViewById(R.id.spinner); editText = (EditText) findViewById(R.id.editText); initView();//初始化 } private void initView() { // 初始化數據:可以數據源或網絡獲取 data = new ArrayList<>(); data.add("Android"); data.add("iOS"); data.add("Java"); data.add("C++"); // 參數一:上下文(Context) // 參數二:系統中的布局資源 android.R.layout.simple_spinner_dropdown_item // 參數三:數據,可以是字符串數據【長度不可變】,也可以是 ArrayList【長度可變】 adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, data); // 將適配器設置為視圖 spinner.setAdapter(adapter); } /** * 從 Spinner 中刪除一項 * * @param v button_remove */ public void doRemove(View v) { // 獲得選中項的位置;若無,則返回 -1 int position = spinner.getSelectedItemPosition(); if (-1 == position) { Toast.makeText(this, "無選中項", Toast.LENGTH_SHORT).show(); } else { // 從數據中刪除當前選中項 data.remove(position); // 適配器通知【視圖】數據集已改變,視圖會重繪 adapter.notifyDataSetChanged(); } } /** * 在 Spinner 中新增一項 * * @param v button_add */ public void doAdd(View v) { // 獲得輸入內容 String input = editText.getText().toString(); if (input.equals("")) { return; //防止添加“空行” } editText.setText(""); // 在數據中添加新內容 data.add(input); // 獲得列表的適配器中數據項的總數 int size = spinner.getAdapter().getCount(); //size = data.size(); // 設置選中選的位置 spinner.setSelection(size - 1); } }
由多行構成
每行一個視圖項
行數由數據決定
可單選、多選
是最常用的適配器視圖
模式
描述
CHOICE_MODE_NONE
普通模式
CHOICE_MODE_SINGLE
單選模式
CHOICE_MODE_MULTIPLE
多選模式
CHOICE_MODE_MULTIPLE_MODAL
Contextual ActionBar(CAB)
長按進入的多選模式
(暫不使用,具體見菜單章節)
效果圖如下:
系統提供的布局模版文件
描述
android.R.layout.simple_list_item_1
包含一個控件(TextView)
android.R.id.text1
android.R.layout.simple_list_item_2
包含兩個控件(TextView)
android.R.id.text1
android.R.id.text2
android.R.layout.simple_list_item_activated_1
包含一個控件,可激活(高亮顯示)的模版
android.R.layout.simple_list_item_checked
可選擇(單選、多選均可)
android.R.layout.simple_list_item_single_choice
可單選(RadioButton)
android.R.layout.simple_list_item_multiple_choice
可多選(CheckBox)
(1)實現如圖“聯系人”顯示。
XML布局文件代碼: activity_list_view2.xml
<RelativeLayout 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=".MainActivity"> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/listView" android:layout_alignParentTop="true" android:layout_above="@+id/button" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="選中的內容" android:id="@+id/button" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:onClick="doClick"/> RelativeLayout>
(2)活動類—代碼:ListView2Activity.java
package com.example.administrator.adapterdemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.SparseBooleanArray; import android.view.View; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Toast; import java.util.ArrayList; import java.util.HashMap; public class ListView2Activity extends AppCompatActivity { // 數據的標簽(KEY) private static final String KEY_NAME = "name"; private static final String KEY_PHONE = "phone"; // 視圖 private ListView listView; // 數據:由鍵值對構成的列表【供簡單適配器使用】 private ArrayList> data; // 適配器:簡單適配器【一行可以顯示多個控件】 private SimpleAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_view2); listView = (ListView) findViewById(R.id.listView); initView();//初始化 } private void initView() { // 初始化數據 data = new ArrayList<>(); for (int i = 0; i < 30; i++) { HashMap item = new HashMap(); item.put(KEY_NAME, "聯系人 " + i); item.put(KEY_PHONE, "號碼 " + i); data.add(item); } // 數據的 KEY 構成的數組 String[] from = {KEY_NAME, KEY_PHONE}; // 控件的 ID 構成的數組 int[] to = {android.R.id.text1, android.R.id.text2}; // 參數一:上下文 // 參數二:數據 // 參數三:系統布局模版【activated 代表可高亮顯示,2 代表有兩個控件】 // 參數四:數據的 KEY 構成的數組 // 參數五:控件的 ID 構成的數組 adapter = new SimpleAdapter( getApplicationContext(), data, android.R.layout.simple_list_item_activated_2, from, to); // 設置為多選模式 listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); // 設置適配器 listView.setAdapter(adapter); } /** * 顯示選中內容 * * @param v button */ public void doClick(View v) { // 獲得選中項的總數 int count = listView.getCheckedItemCount(); // 獲得選中項的標識【使用SQLite及游標時可用】 long[] ids = listView.getCheckedItemIds(); // 獲得選中的位置【單選】 int position = listView.getCheckedItemPosition(); // 獲得選中的位置【多選,獲得一個稀疏矩陣】 SparseBooleanArray array = listView.getCheckedItemPositions(); // 顯示結果 Toast.makeText(this, array.toString(), Toast.LENGTH_SHORT).show(); } }
完整工程:https://github.com/ljheee/AdapterDemo
工程名AdapterDemo,工程下有4個活動(Activity),啟動運行主活動,演示Spinner使用靜態數據;主活動界面下有三個Button,點擊可實現向其他活動的跳轉。左下角Button跳轉到Spinner2Activity演示Spinner動態處理數據;中間是演示簡單ListView的使用;右下角跳轉到最後一個ListView的演示。
簡單拓展RadioButton控件使用如果不看這些,就直接下托RadioButton和CheckBox的區別:1、單個RadioButton在選中後,通過點擊無法變為未選
寫程序的過程中,想法總會不斷地變,有時候會很糾結,到底做哪種效果好,怎麼做好呢? 就比如這個音樂播放器,我原來的想法是把列表頁面跟歌詞頁面放在同一個Activity中的兩
一.前言第一次做導航時,並沒有關注語音播報,今天特意把這個功能完善一下。但是發現關於語音播報的實現也遇到了一些問題,在官方的討論區也發現關於語音播報的問題特別多,問題基本