可擴展收納式的ListView,好處當然是可以讓APP的UI看起來更簡潔不占空間~
在官方的API文件中其實就可以看到有提供這種功能的API文件
ExpandableListView 官方 API 文件
"ExpandableListView"
網路稍微爬一下就可以看到很多範例,在這我們就做點小修正
成品圖大概長這樣~(展開前後圖)
主要分成幾個部分
1 . xml
2 . fragment
3 . adapter
====================== xml ======================
fragment中的layout中加入
<ExpandableListView android:id="@+id/lvExp" android:layout_height="match_parent" android:layout_width="match_parent"/>建立一個新的expandable_head.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#FFFFFF" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/lblListHeader_head" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="@string/version" android:textColor="#000000" android:textSize="16sp" /> <TextView android:id="@+id/lblListHeader_memo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/setting_system_version" android:text="0.0.0" android:textColor="#767676" android:textSize="14sp" /> </LinearLayout> <ImageView android:id="@+id/img_list_close" android:layout_width="35dp" android:layout_height="35dp" android:layout_alignParentRight="true" android:src="@mipmap/ic_putup"/> </RelativeLayout>建立一個新的expandable_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="40dp" android:orientation="vertical" android:padding="8dp" android:background="#FFFFFF"> <TextView android:id="@+id/lblListItem_head" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft" android:textSize="16sp" android:textColor="#767676" /> <TextView android:id="@+id/lblListItem_memo" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft" android:textSize="12sp" android:textColor="#FF5722" /> <View android:layout_width="match_parent" android:layout_height="1dip" android:background="#F2F2F2" /> </LinearLayout>
====================== adapter ======================
public class ExpandableListAdapter extends BaseExpandableListAdapter { private Context context; private ListlistDataHeader; // header titles // child data in format of header title, child title private HashMap > listDataChild; public ExpandableListAdapter(Context context, List listDataHeader, HashMap > listChildData) { this.context = context; this.listDataHeader = listDataHeader; this.listDataChild = listChildData; } @Override public Object getChild(int groupPosition, int childPosititon) { return this.listDataChild.get(this.listDataHeader.get(groupPosition)) .get(childPosititon); } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { final String childText = (String) getChild(groupPosition, childPosition); if (convertView == null) { LayoutInflater infalInflater = (LayoutInflater) this.context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = infalInflater.inflate(R.layout.f4_expandable_items, null); } String[] Child_array = childText.split("(,,,\\+)"); TextView txtListChild_head = (TextView) convertView.findViewById(R.id.lblListItem_head); TextView txtListChild_memo = (TextView) convertView.findViewById(R.id.lblListItem_memo); txtListChild_head.setTypeface(null, Typeface.BOLD); txtListChild_memo.setTypeface(null, Typeface.BOLD); txtListChild_head.setText(Child_array[0]); txtListChild_memo.setText(Child_array[1]); return convertView; } @Override public int getChildrenCount(int groupPosition) { return this.listDataChild.get(this.listDataHeader.get(groupPosition)).size(); } @Override public Object getGroup(int groupPosition) { return this.listDataHeader.get(groupPosition); } @Override public int getGroupCount() { return this.listDataHeader.size(); } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { String headerText = (String) getGroup(groupPosition); if (convertView == null) { LayoutInflater infalInflater = (LayoutInflater) this.context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = infalInflater.inflate(R.layout.f4_expandable_head, null); }
isExpanded 判斷擴展的狀態 //在這邊加入Image 在Head點擊擴展時 右邊的圖片會做替換 ImageView HeaderRightIcon = (ImageView) convertView.findViewById(R.id.img_list_close); //
if(isExpanded){ HeaderRightIcon.setImageResource(R.mipmap.ic_putup); }else{ HeaderRightIcon.setImageResource(R.mipmap.ic_putaway); } String[] Header_array = headerText.split("(,,,\\+)"); TextView lblListHeader_head = (TextView) convertView.findViewById(R.id.lblListHeader_head); TextView lblListHeader_memo = (TextView) convertView.findViewById(R.id.lblListHeader_memo); lblListHeader_head.setText(Header_array[0]);
lblListHeader_memo.setText("1.1.0"+ "." + Header_array[1]); return convertView; } @Override public boolean hasStableIds() { return false; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } }
====================== fragment ======================
先宣告
ExpandableListAdapter listAdapter; ExpandableListView expListView; List<String> listDataHeader; HashMap<String, List<String>> listDataChild;
在這邊我們需要在adapter中加入每個版本及每個版本更新的內容
所以要在listDataHeader 與 listDataChild 中先塞入資料
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { viewRoot = inflater.inflate(R.layout.fragment_04, container, false); expListView = (ExpandableListView) viewRoot.findViewById(R.id.lvExp); expListView.setGroupIndicator(null);//預設的箭頭設為null(不使用),沒有設定null的話預設在左邊的箭頭會出現 prepareListData(); //這邊先做準備資料的動作 listAdapter = new ExpandableListAdapter(context, listDataHeader, listDataChild); expListView.setAdapter(listAdapter); return viewRoot; }
private void prepareListData() { listDataHeader = new ArrayList(); listDataChild = new HashMap >(); JSONObject jsonObject; JSONArray array = null; try { jsonObject = new JSONObject(getVersionJson(context)); array = jsonObject.getJSONArray("versionList"); } catch (JSONException e) { e.printStackTrace(); } // 加入Head資料 listDataHeader.add("1.1.0"+",,,+"+"0003"); //",,,+" 沒有特別的意思,方便做split的動作(投機取巧的方式,建議少這樣用) List ItemsList = new ArrayList (); StringBuilder sb = new StringBuilder(); // 加入每個item的資料 for (int i = 0; i <array.length(); i++) { sb = new StringBuilder(); try { JSONObject jsonObjectVersionList = array.getJSONObject(i); String version = jsonObjectVersionList.getString("Version"); JSONArray array2 = jsonObjectVersionList.getJSONArray("memoList"); for (int j = 0; j < array2.length(); j++) { JSONObject jsonObjectMemoList = array2.getJSONObject(j); String memo = jsonObjectMemoList.getString("memo"); sb.append(memo); } ItemsList.add("1.1.0."+version+",,,+"+sb); } catch (JSONException e) { e.printStackTrace(); } } listDataChild.put(listDataHeader.get(0), ItemsList); }
注意:
1 . 在這邊加入的版本資料是從一個json檔內的資料取出(改天寫一篇有關json的)
配合json做成範例的原因,因為在開發的過程中很常見到需要透過API拿回來Response的資料
蠻多都是用json的格式,我們需要解析後再取出需要的資訊來應用,所以這範例就用這種方式呈現。
2 . 在開發的過程中盡量別用"1.1.0"+",,,+"+"0003"類似的方式來加資料
在這是因為寫範例練習文章,先用簡單的方式呈現,但相信新手起步時很多人都會這樣做
因為很方便@@a.....當然方便的過程中後來我也是吃了閉門羹.....
有機會在寫一篇在開發用這種寫法的缺點在哪~
沒有留言:
張貼留言