Android ListView 進階——從列表中獲取值
在上一篇博文中寫到了ListView的基礎用法。
需要看ListView基礎用法的朋友請看,Android ListView基礎用法
現在大家根據上一篇博文已經可以呈現出一個列表了,但是在實際使用列表的過程中經常會在列表中用到一些按鈕、選擇框、下拉選單等功能並獲取使用者所選擇的值。這樣的需求在上一篇的用法中已經無法滿足,所以博主今天用ListView中巢狀spinner下拉選擇列表並獲取spinner中的值為例。希望可以給大家一些類似的啟發。
先上效果圖
在列表中可以選擇良好、不良、待修、修理四個選項,點選提交返回結果(四個選項分別對應0、1、2、3)
下面是點選提交後,日誌答應的結果。可以看到已經成功獲取到了選擇的內容
接下來,廢話不多說上乾貨
要做列表的思路當然還是adpter+item.xml,但是因為這個例子用到了spinner這一元件,由於spinner的特性:直接使用spinner元件無法自行規定字型大小、格式等等屬性,只能使用預設的,使用起來很難受。所以在做列表介面卡前,我們先做一個spinner的介面卡。
//Spinner介面卡
public class SpotCheckSpinnerAdapter extends BaseAdapter {
private Context mContext;
private String[] values;
public SpotCheckSpinnerAdapter(Context context){
this.mContext = context;
Resources res = mContext.getResources();
this.values = res.getStringArray(R.array.checklist_values);//構建spinner中的值
}
@Override
public int getCount() {
return values.length;
}
@Override
public Object getItem(int position) {
return values[position];
}
@Override
public long getItemId(int position) {
return 0;
}
//快取選項內容
private class ViewHolder {
TextView spinner_value;
}
public View getView(int position, View converView, ViewGroup parent){
ViewHolder holder;
if (converView == null){
converView = View.inflate( mContext,R.layout.spinner_value,null );
holder = new ViewHolder();
holder.spinner_value = (TextView) converView.findViewById( R.id.spinner_value );
converView.setTag( holder );
}else {
holder = (ViewHolder) converView.getTag();
}
String value = values[position];
holder.spinner_value.setText( value );
return converView;
}
}
說一下這裡ViewHolder的作用,每次進入頁面都要執行getView,所以等列表的長度超過一頁時會出現當頁面滑動時,有一部分內容消失,當這部分內容再次進入頁面時會getView,這就導致了資料錯位等現象。使用ViewHolder把所有已經選擇的內容存起來當再次用到時取出,這樣就避免了資料錯位的問題。
spinner中的值由R.array.checklist_values確定
該檔案目錄為
程式碼如下:
<resources>
<string-array name="checklist_values">
<item>良好</item>
<item>不良</item>
<item>待修</item>
<item>修理</item>
</string-array>
</resources>
這樣spinner介面卡就做好了。接下來要在列表介面卡中加入spinner介面卡
還是先寫列表item.xml,很簡單不做解釋,直接上程式碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="40dp"
android:textSize="20dp"
android:id="@+id/checkinfo_item_name"
android:gravity="center_vertical"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="點檢完成:"
android:gravity="center_vertical"
android:textSize="20dp" />
<Spinner
android:layout_width="125dp"
android:layout_height="wrap_content"
android:id="@+id/checkinfo_item_value"/>
</LinearLayout>
</LinearLayout>
構建列表介面卡
public class SpotCheckDetailItemAdapter extends BaseAdapter {
private Context mContext;
private String[] checkListName;
private Map<String,Integer> allValues;//用於儲存spinner 內容
public SpotCheckDetailItemAdapter(Context context,String[] checkListName){
this.mContext = context;
this.checkListName = checkListName;
allValues = new HashMap<String, Integer>();
putAllValues();
}
//把資料儲存入allValues
private void putAllValues() {
for (String str:checkListName){
allValues.put(str,0);
}
}
public void setAllValues(Map<String,Integer>allValues){
this.allValues = allValues;
}
@Override
public int getCount() {
return checkListName.length;
}
@Override
public Object getItem(int position) {
return checkListName[position];
}
@Override
public long getItemId(int i) {
return 0;
}
private class ViewHolder{
TextView checkinfo_item_name;
Spinner checkinfo_item_value;
}
public View getView(int position, View converView, ViewGroup parent){
ViewHolder holder;
if (converView == null){
converView = View.inflate(mContext,R.layout.spotcheckdetail_item,null);
holder = new ViewHolder();
holder.checkinfo_item_name = (TextView) converView.findViewById( R.id.checkinfo_item_name );
holder.checkinfo_item_value = (Spinner) converView.findViewById( R.id.checkinfo_item_value );
SpotCheckSpinnerAdapter adapter = new SpotCheckSpinnerAdapter( mContext );//spnner介面卡例項
holder.checkinfo_item_value.setAdapter( adapter );
holder.checkinfo_item_value.setOnItemSelectedListener(new ItemClickSelectListener( holder.checkinfo_item_value));
converView.setTag( holder );//將holder存在converView中
}else {
holder = (ViewHolder) converView.getTag();//重新獲取Viewholder
}
String checkedName = checkListName[position];
holder.checkinfo_item_name.setText( checkedName );
holder.checkinfo_item_value.setPrompt( checkedName );
int spinnerOptionPosition = allValues.get( checkedName );//獲取spnner的值
holder.checkinfo_item_value.setSelection(spinnerOptionPosition);//重新載入spnner內容
return converView;
}
private class ItemClickSelectListener implements AdapterView.OnItemSelectedListener {
Spinner checkinfo_item_value;
public ItemClickSelectListener(Spinner checkinfo_item_value) {
this.checkinfo_item_value = checkinfo_item_value;
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
allValues.put( checkinfo_item_value.getPrompt().toString(),position );//記錄spinner的選擇內容
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
public Map<String,Integer> getSelectValues() {
return allValues;
}
}
列表介面卡中把spinner中的值儲存在HashMap中,通過getSelectValues()方法返回結果。其他我認為重要的部分都加了註釋,應該可以理解了。
最後一步就是在activity中呼叫這個介面卡了
activity_spot_check_detail.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/list_spotcheckdetail">
</ListView>
</LinearLayout>
spot_check_commit_button.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:gravity = "center"
android:paddingRight="10dp"
android:paddingLeft="10dp">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button_commit"
android:text="提交"
android:textSize="20dp"/>
</LinearLayout>
這裡把列表和提交按鈕寫在兩個xml中,為的是當列表超出一頁時做到同步滾動。如果直接把按鈕放在列表的下方會出現按鈕固定不動的問題。
最後一步,勝利在望
public class SpotCheckDetailActivity extends AppCompatActivity {
private String[] item = {"裝置標牌","壓力錶","安全閥","密封性"};
private ListView spotCheckDetaiList;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_spot_check_detail);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null){
actionBar.hide();
}
//點檢項列表
spotCheckDetaiList = (ListView) findViewById( R.id.list_spotcheckdetail);
//介面卡例項化
final SpotCheckDetailItemAdapter adapter = new SpotCheckDetailItemAdapter( this,item);
//底部提交按鈕佈局載入
View view_bottom = View.inflate( SpotCheckDetailActivity.this,R.layout.spot_check_commit_button,null );
spotCheckDetaiList.addFooterView( view_bottom );//把按鈕佈局新增到listView的下方
Button commit = (Button) findViewById( R.id.button_commit );
commit.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d( "MainActivity", String.valueOf( adapter.getSelectValues() ) );
}
} );
//建立介面卡
spotCheckDetaiList.setAdapter( adapter );
}
}
到這裡就和上一篇講的列表的基本用法一樣了。大功告成!
大家可以看到列表的使用重點是介面卡的構建,基本上所有列表的操作都要在介面卡中完成。
相關文章
- Android:ListView的擴充與進階AndroidView
- android listview獲取選中項AndroidView
- Android中ListView控制元件onItemClick事件中獲取listView傳遞的資料AndroidView控制元件事件
- android如何獲取listview中的任意行資料AndroidView
- Android ListView中獲取選中行資料的方法AndroidView
- flutter中ListView做一個掘金列表FlutterView
- 直播app開發,Android ListView好友列表展示APPAndroidView
- Flutter進階:深入探究 ListView 和 ScrollPhysicsFlutterView
- android中的ListViewAndroidView
- Android ListView中獲取修改選中行資料的方法AndroidView
- Android在ListView的onTouch事件中獲取選中項的值AndroidView事件
- Python如何從列表中獲取笛卡爾積Python
- 【Android 進階】仿抖音系列之列表播放視訊(二)Android
- android開發中如何動態獲取listview中的item的值AndroidView
- Android DataBinding 從入門到進階Android
- Android中ExpandableListView中巢狀ListViewAndroidView巢狀
- Android進階(七)Android中的ClassLoaderAndroid
- Fragment中的那些坑——Android進階FragmentAndroid
- Android DataBinding 從入門到進階(2)Android
- Android 列表(ListView、RecyclerView)不斷重新整理最佳實踐AndroidView
- 搭建直播平臺,Android ListView 長按刪除列表項AndroidView
- 列表(recyclerView、listView及其相關)View
- Flutter的ListView(靜態列表)FlutterView
- Flutter入門進階之旅(十四)ListView&GridViewFlutterView
- Pandas 基礎 (13) - Crosstab 交叉列表取值ROS
- RecyclerView進階之層疊列表(上)View
- RecyclerView進階之層疊列表(下)View
- C++11進階知識列表C++
- Android 中listview的全選、全不選、反選、獲得選中條目資料AndroidView
- android開發(3):列表listview的實現 | 下拉重新整理AndroidView
- Android高階進階之路【一】Android中View繪製流程淺析AndroidView
- flutter系列之:flutter中listview的高階用法FlutterView
- Android ListViewAndroidView
- Python 進階_迭代器 & 列表解析Python
- 關於如何獲得ListView中選中項的值View
- listview 後天獲取選中項的值View
- ListView進階系列之一 內容順序淡淡顯示View
- CCTextFieldTTF使用getString()方法獲取值