Android 高級UI設計筆記01:使用ExpandableListView組件(ListView的擴展)


1. ExpandableListView是一個用來顯示二級節點的ListView。

比如如下效果的界面:

 

2. 使用ExpandableListView步驟:

(1)要給ExpandableListView設置適配器,那么必須先設置數據源;

(2)數據源,就是此處的適配器類ExpandableAdapter,此方法繼承了BaseExpandableListAdapter,它是ExpandableListView的一個子類。需要重寫里面的多個方法。getChildView()和getGroupView()方法設置自定義的布局;

(3)數據源設置好,直接給ExpandableListView.setAdapter()即可實現收縮功能。

 

3.下面就是我們就利用具體的案例來說明如何使用這個ExpandableListView組件:

(1)首先我們定義我們的布局文件activity_main.xml 如下:

<LinearLayout 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:orientation="vertical" tools:context="com.himi.expandablelistview.MainActivity" >
    <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="QQ通訊錄" android:textSize="30sp" android:textColor="#55ff0000" android:gravity="center_horizontal"
        />

    <ExpandableListView android:id="@+id/expandablelv" android:layout_width="match_parent" android:layout_height="wrap_content" >
    </ExpandableListView>

</LinearLayout>

在這個activity_main.xml布局文件中,我們引入了組件ExpandableListView,布局效果圖如下:

 

 

(2)定義我們自己的適配器MyExpandablelistviewAdapter,讓它繼承自BaseExpandableListAdapter,然后實現繼承的方法。這里我們直接把數據源放在了我們自定義的類MyExpandablelistviewAdapter之中,然后綁定這個數據源到我們定的MyExpandablelistviewAdapter之中。

數據源我們定義為:

 private String[] groups = {"家人","同學","同事"}; private String[][] childs = { {"老爸","老媽"}, {"劉德華","黎明","郭富城","張學友"}, {"馬雲","比爾蓋茨", "巴菲特"} }; private int[][] childs_imgs = { { R.drawable.img1, R.drawable.img2 }, { R.drawable.img3, R.drawable.img4 , R.drawable.img5, R.drawable.img6}, { R.drawable.img7, R.drawable.img8 , R.drawable.img9} };

MVC模式:在Android項目中,業務邏輯,數據處理等擔任了Model(模型)角色,XML界面顯示等擔任了View(視圖)角色,Activity擔任了Contronller(控制器)角色。contronller(控制器)是一個中間橋梁的作用,通過接口通信來協同 View(視圖)Model(模型)工作,起到了兩者之間的通信作用

這里的MyExpandablelistviewAdapter.java:

package com.himi.expandablelistview.adpater; import android.view.ViewGroup.LayoutParams; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ImageView; import android.widget.TextView; import com.himi.expandablelistview.R; /** * 自定義適配器MyExpandablelistviewAdapter * @author Administrator * */
public class MyExpandablelistviewAdapter extends BaseExpandableListAdapter { private Context context ; private String[] groups = {"家人","同學","同事"}; private String[][] childs = { {"老爸","老媽"}, {"劉德華","黎明","郭富城","張學友"}, {"馬雲","比爾蓋茨", "巴菲特"} }; private int[][] childs_imgs = { { R.drawable.img1, R.drawable.img2 }, { R.drawable.img3, R.drawable.img4 , R.drawable.img5, R.drawable.img6}, { R.drawable.img7, R.drawable.img8 , R.drawable.img9} }; //引入一個字段context,方便Activity實例化MyExpandablelistviewAdapter
    public MyExpandablelistviewAdapter(Context context) { this.context = context; } //獲取一級菜單的分組數目,比如這里就是3組:"我的好友","同學","同事"
    public int getGroupCount() { return groups.length; } //獲取每個一節菜單中二級菜單的分組數目,比如"家人"中有2個條目("老爸","老媽")
    public int getChildrenCount(int groupPosition) { return childs[groupPosition].length; } //獲取每個一級菜單子項對象
    public String getGroup(int groupPosition) { return groups[groupPosition]; } //獲取每個二級菜單子項對象
    public String getChild(int groupPosition, int childPosition) { return childs[groupPosition][childPosition]; } //獲取每個一級菜單子項對象Id
    public long getGroupId(int groupPosition) { return groupPosition; } //獲取每個二級菜單子項對象Id
    public long getChildId(int groupPosition, int childPosition) { return childPosition; } /** * hasStableIds有關於MyExpandablelistviewAdapter適配器刷新順序 * getGroupId和getChildId兩個方法獲取對象Id,獲取到的Id,ExpandableListView會根據這個Id確定位置顯示內容 * 然而Id是否有效穩定是由hasStableIds決定的,也就是說:這個方法就是判斷item的id是否穩定, * 如果有自己的id也就是true,那就是穩定,否則不穩定,則根據item位置來確定id * */
    public boolean hasStableIds() { return true; } //渲染一級菜單
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { if(convertView == null) { /** * LayoutInflater是一個抽象類,它的inflate方法可以把一個xml文件轉化為View對象 * 對於一個沒有被載入或者想要動態載入的界面,都需要使用LayoutInflater.inflate()來載入 * 剛剛說明了:LayoutInflater是一個抽象類,要獲取LayoutInflater的實例; * 獲得 LayoutInflater 實例的三種方式: * 1.LayoutInflater inflater = getLayoutInflater(); //調用Activity的getLayoutInflater() * * 2.LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); * * 3. LayoutInflater inflater = LayoutInflater.from(context); * 上面三種方法的本質是一樣的 */ LayoutInflater minflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = minflater.inflate(R.layout.group_item,null); } TextView tv = (TextView) convertView.findViewById(R.id.textview_group); tv.setText(groups[groupPosition]); tv.setTextSize(25); tv.setPadding(15, 5, 0, 0); return convertView; } //渲染二級菜單
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { if(convertView == null) { LayoutInflater minflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = minflater.inflate(R.layout.child_item,null); } ImageView iv = (ImageView) convertView.findViewById(R.id.imageview_child); TextView tv = (TextView) convertView.findViewById(R.id.textview_child); iv.setImageResource(childs_imgs[groupPosition][childPosition]); //導入的包為:import android.view.ViewGroup.LayoutParams;
        LayoutParams params = iv.getLayoutParams(); params.width = 200; params.height = 200; iv.setLayoutParams(params); tv.setText(childs[groupPosition][childPosition]); //記得return convertView
        return convertView; } //true:讓子項可選 ; false:讓子項不可選
    public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } }

(3)最后在MainActivity.java中綁定我們定義的MyExpandablelistviewAdapter(此時的適配器已經綁定了數據源,適配器可以控制其相應的顯示),這使用我們還需要綁定適配器到模型Model,就是說綁定適配器到ExpandableListView:

這里的MainActivity.java:

package com.himi.expandablelistview; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.ExpandableListView; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.Toast; import com.himi.expandablelistview.adpater.MyExpandablelistviewAdapter; public class MainActivity extends Activity { private ExpandableListView expan_listview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); expan_listview = (ExpandableListView) findViewById(R.id.expandablelv); expan_listview.setAdapter(new MyExpandablelistviewAdapter(this)); expan_listview.setOnChildClickListener(new OnChildClickListener() { public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { Toast.makeText(MainActivity.this, "你點擊的是第"+(groupPosition+1)+"的菜單下的第"+(childPosition+1)+"選項", 0).show(); return false; } }); } }

這里我們添加了一個ExpandableListView的點擊事件:expan_listview. setOnChildClickListener;當然這里還有其他很多監聽事件,這里我們不多加詳解,我們只要知道靈魂就行了。

 

(4)運行結果圖如下:

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM