下面是我的主 layout, 很簡單就只是一個 ExpandableListView 的 widiget.
activity_main.xml
ExpandableListView 有分 Group 和 Child, 因此分別對 Group 和 Child 設定各自的 View.
group_row.xml
child_row.xml
接下來就是主要程式的部份, 這邊我不使用 ExpandableListActivity, 原因是
在很多情況下直接繼承 (extend) ExpandableListActivity 是沒辦法, 比方說當你要使用 Fragment 的時候.
這邊為了簡化, 所以所有的 import 都不會列出來.
因為會使用到 ExpandableListView 這元件, 所以我們特別使用一個變數 (mExpandableListView) 來指向此元件.
public class MainActivity extends Activity { private ExpandableListView mExpandableListView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mExpandableListView = (ExpandableListView) findViewById(R.id.elistview); initData(); } }有了 ExpandableListView 元件, 接著必須把所需的資料放進此元件.
groupItems 使主要的群組, 而 childItems 是每個群組底下的資料
跟 ListView 一樣, 這邊定義一個 MyExpandListAdapter 來給 ExpandableListView 使用.
MyExpandListAdapter 會包含我們如何顯示每個行(row)資料和呈現的畫面.
private void initData() { final String[] groupItems = { "Group1", "Group2", "Group3", "Group4", "Group5", }; final String[] childItems = { "Child1", "Child2", "Child3", "Child4", "Child5", }; MyExpandListAdapter adapter = new MyExpandListAdapter(this, groupItems); int i = 0; int count = groupItems.length; /** * add child data to groups */ for (i = 0; i < count; i++) { adapter.addChild(i, childItems); } mExpandableListView.setAdapter(adapter); }MyExpandListAdapter 比較複雜, 因為這個主要是用來顯示資料並且在 ExpandableListView 裡的畫面呈現.
class MyExpandListAdapter extends BaseExpandableListAdapter { Context ctxt = null; /** * Use SparseArray to store my group-child mapping datas, */ SparseArray這樣就是基本的 ExpandListView 了. 以下是畫面呈現,data = new SparseArray (); String[] groups = null; public MyExpandListAdapter(Context c, String[] groupitems) { super(); ctxt = c; groups = groupitems; } @Override public String getChild(int groupPosition, int childPosition) { String[] childs = data.get(groupPosition); if (childs == null) { return null; } if (childPosition >= childs.length) { return null; } return childs[childPosition]; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { /** * in this function, we can customize our child view and show data. */ View row = convertView; if (row == null) { LayoutInflater inflater = (LayoutInflater) ctxt .getSystemService(Context.LAYOUT_INFLATER_SERVICE); row = inflater.inflate(R.layout.child_row, parent, false); } TextView tv = (TextView) row.findViewById(R.id.childlabel); String child = getChild(groupPosition, childPosition); if (child != null) { tv.setText(child); } return row; } @Override public int getChildrenCount(int groupPosition) { String[] childs = data.get(groupPosition); if (childs == null) { return 0; } return childs.length; } @Override public String getGroup(int groupPosition) { if (groupPosition >= groups.length) { return null; } return groups[groupPosition]; } @Override public int getGroupCount() { return groups.length; } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { /** * in this function, we can customize our group view and show data. */ View row = convertView; if (row == null) { LayoutInflater inflater = (LayoutInflater) ctxt .getSystemService(Context.LAYOUT_INFLATER_SERVICE); row = inflater.inflate(R.layout.group_row, parent, false); } TextView tv = (TextView) row.findViewById(R.id.grouplabel); String group = getGroup(groupPosition); if (group != null) { tv.setText(group); } return row; } @Override public boolean hasStableIds() { return false; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { /** * If set to false, we can't click child item. */ return false; } public void addChild(int group, String[] childs) { /** * Add this function for us to add childs. * It will overwrite previsou data * But this is just an example. */ data.put(group, childs); notifyDataSetChanged(); } }
如果注意到的話, 群組的折疊圖示竟然重疊了.
修改一下 group_row 的 layout
修改後的結果如下
不過一般通常折疊的圖示都是在右邊, 所以再次修改一下把折疊圖示移到最右邊.
private void initData() { final String[] groupItems = { "Group1", "Group2", "Group3", "Group4", "Group5", }; final String[] childItems = { "Child1", "Child2", "Child3", "Child4", "Child5", }; MyExpandListAdapter adapter = new MyExpandListAdapter(this, groupItems); int i = 0; int count = groupItems.length; /** * add child data to groups */ for (i = 0; i < count; i++) { adapter.addChild(i, childItems); } setIndicatorToRight(); mExpandableListView.setAdapter(adapter); mExpandableListView.setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { MyExpandListAdapter adapter = (MyExpandListAdapter) parent .getAdapter(); String group = adapter.getGroup(groupPosition); String child = adapter.getChild(groupPosition, childPosition); Toast.makeText(MainActivity.this, group + " - " + child, Toast.LENGTH_SHORT).show(); return true; } }); } private void setIndicatorToRight() { final float scale = getResources().getDisplayMetrics().density; /** * Calcaulate device screen width in pixel */ DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int width = metrics.widthPixels; mExpandableListView.setIndicatorBounds(width - (int)(50 * scale), width - (int)(10 * scale)); }下面就是最終畫面的呈現
原始碼下載: here
沒有留言:
張貼留言