原文連接:http://blog.csdn.net/duguju/article/details/49538341html
有時咱們須要用GridView顯示目錄列表,有時甚至是二級的,即listview每個item裏面又各自嵌入一個gridview,可是當二級目錄(數據條目)的數量過多時,界面會比較臃腫,這時咱們就想要有相似展開與摺疊的效果,做者採用的策略是數據分段的分別顯示,其中對於顯示邊界(處於限制顯示數目的特定位置)的控件要有數據的動態更新和點擊判斷操做。效果如圖:java

具體實現:android
1、Activity界面app
- package com.example.gridinlist;
-
- import java.util.Vector;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.widget.ListView;
-
- public class MainActivity extends Activity {
-
- private ListView listView;
- private MyAdapter adapter;
- private Vector<String> stringVector = new Vector<String>();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initView();
- }
-
- private void initView() {
- listView = (ListView) findViewById(R.id.list);
- adapter = new MyAdapter(this, this.getLayoutInflater(), stringVector);
-
- stringVector.add("0");
- stringVector.add("1");
- stringVector.add("2");
- stringVector.add("3");
- stringVector.add("4");
- stringVector.add("5");
-
- listView.setAdapter(adapter);
- }
- }
主Activity,裏面只有一個textview(標題)和listview(主體),其中Listview的適配器MyAdapter是自寫的(也是實現效果的主要邏輯代碼)。ide
這裏咱們直傳給MyAdapter一個字符串向量,爲了簡便,無論一級仍是二級目錄都是用的這一個向量(實際中每一個二級子向量應該都是不一樣的),用戶可根據需求自行添加或修改(也可使用Parcel將其封裝爲一個二級的數據類型,具體再也不贅述)。佈局
Activity佈局文件this
- <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="${relativePackage}.${activityClass}" >
-
- <TextView
- android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:layout_centerHorizontal="true"
- android:text="@string/hello_world" />
-
- <ListView
- android:id="@+id/list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_marginLeft="7dip"
- android:layout_marginRight="7dip"
- android:layout_marginBottom="7dip"
- android:layout_below="@+id/title"
- android:cacheColorHint="#00000000"
- android:drawSelectorOnTop="false"
- android:listSelector="#00000000"
- android:scrollbars="none"
- android:scrollingCache="true"
- android:drawingCacheQuality="low"
- android:divider="#00000000"
- android:dividerHeight="0dip"
- android:fadingEdgeLength="0.0sp"
- />
-
-
- </RelativeLayout>
2、自寫的istview的Adapter(關鍵代碼)spa
- package com.example.gridinlist;
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Vector;
- import android.annotation.SuppressLint;
- import android.content.Context;
- import android.database.DataSetObserver;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.BaseAdapter;
- import android.widget.GridView;
- import android.widget.SimpleAdapter;
- import android.widget.TextView;
- import android.widget.Toast;
-
- public class MyAdapter extends BaseAdapter
- {
- private static final String TAG = "MyAdapter";
- private LayoutInflater inflater;
- private Context context;
- private Vector<String> vector;
- private int numGridShowLimit = 4;
-
-
- public MyAdapter(Context context,LayoutInflater inflater,Vector<String> vector)
- {
- this.context = context;
- this.inflater = inflater;
- this.vector = vector;
- }
-
-
- private static class ViewHolder
- {
- private TextView titleTextView;
- private GridView contentGridView;
- private GridView contentMoreGridView;
- }
-
-
- @SuppressLint("InflateParams")
- @Override
- public View getView(int position, View convertView, ViewGroup parent)
- {
- final ViewHolder viewHolder;
- if( convertView == null )
- {
- convertView = inflater.inflate(R.layout.adapter_listview,null);
- viewHolder = new ViewHolder();
- viewHolder.titleTextView = (TextView) convertView.findViewById(R.id.list_txt_title);
- viewHolder.contentGridView = (GridView) convertView.findViewById(R.id.list_grid);
- viewHolder.contentMoreGridView = (GridView) convertView.findViewById(R.id.list_grid_more);
- convertView.setTag(viewHolder);
- }
- else viewHolder = (ViewHolder) convertView.getTag();
-
- try
- {
- if(vector != null && vector.size() > 0)
- {
- final String category = vector.get(position);
- if(category != null)
- {
- viewHolder.titleTextView.setText("list item "+category);
- }
-
- if (vector.size() > 0) {
- final ArrayList<HashMap<String, Object>> categoryList = new ArrayList<HashMap<String, Object>>();
- final ArrayList<HashMap<String, Object>> categorySubList1 = new ArrayList<HashMap<String, Object>>();
- final ArrayList<HashMap<String, Object>> categorySubList2 = new ArrayList<HashMap<String, Object>>();
-
- if (vector != null && vector.size() > 0) {
- for (int i = 0; i < vector.size(); i++) {
- String o = vector.get(i);
- if (o != null) {
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put("ItemText", "grid" + o);
- categoryList.add(map);
- }
- }
- }
- final int mypos = position;
-
-
- if (vector.size() > numGridShowLimit) {
-
-
- for (int i = 0; i < numGridShowLimit; i++) {
- String o = vector.get(i);
- if (o != null) {
- if (i==numGridShowLimit-1) {
- HashMap<String, Object> map = new HashMap<String, Object>();
- if (viewHolder.contentMoreGridView.getVisibility()==View.GONE) {
-
- map.put("ItemText", "" + "+");
- }else {
-
- map.put("ItemText", "grid" + o);
- }
- categorySubList1.add(map);
- }else {
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put("ItemText", "grid" + o);
- categorySubList1.add(map);
- }
-
- }
- }
-
-
- for (int i = numGridShowLimit; i < vector.size(); i++) {
- String o = vector.get(i);
- if (o != null) {
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put("ItemText", "grid" + o);
- categorySubList2.add(map);
- }
- }
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put("ItemText", "-");
- categorySubList2.add(map);
-
-
- final SimpleAdapter simpleAdapter1 = new SimpleAdapter(context, categorySubList1,
- R.layout.adapter_gridview,
- new String[] { "ItemText" },
- new int[] { R.id.ItemText });
- viewHolder.contentGridView.setAdapter(simpleAdapter1);
-
-
- final SimpleAdapter simpleAdapter2 = new SimpleAdapter(context, categorySubList2,
- R.layout.adapter_gridview,
- new String[] { "ItemText" },
- new int[] { R.id.ItemText });
- viewHolder.contentMoreGridView.setAdapter(simpleAdapter2);
-
-
- viewHolder.contentMoreGridView.setOnItemClickListener(new OnItemClickListener() {
- public void onItemClick(AdapterView<?> AdapterView, View view,int pos, long row) {
- if (categoryList.size()>numGridShowLimit && pos==categoryList.size()-numGridShowLimit) {
-
- View rel = (View) viewHolder.contentGridView.getChildAt(numGridShowLimit-1);
- TextView tv = (TextView) rel.findViewById(R.id.ItemText);
- tv.setText("+");
- viewHolder.contentMoreGridView.setVisibility(View.GONE);
- }else {
- view.setTag(mypos*100+numGridShowLimit+pos);
- Toast.makeText(context, " list position:"+ mypos+"\ngrid position:"+pos, Toast.LENGTH_SHORT).show();
- }
- }
- });
- }
- else {
-
- final SimpleAdapter simpleAdapter = new SimpleAdapter(context, categoryList,
- R.layout.adapter_gridview,
- new String[] { "ItemText" },
- new int[] { R.id.ItemText });
- viewHolder.contentGridView.setAdapter(simpleAdapter);
- }
-
-
- viewHolder.contentGridView.setOnItemClickListener(new OnItemClickListener() {
- public void onItemClick(AdapterView<?> AdapterView, View view,int pos, long row) {
- if (categoryList.size()>numGridShowLimit && pos==numGridShowLimit-1) {
- TextView tv = (TextView) view.findViewById(R.id.ItemText);
- String content = tv.getText().toString();
- if (content.equals("+")) {
-
- tv.setText("grid"+vector.get(numGridShowLimit-1));
- viewHolder.contentMoreGridView.setVisibility(View.VISIBLE);
- }else {
- view.setTag(mypos*100+pos);
- Toast.makeText(context, " list position:"+ mypos+"\ngrid position:"+pos, Toast.LENGTH_SHORT).show();
- }
- }else {
- view.setTag(mypos*100+pos);
- Toast.makeText(context, " list position:"+ mypos+"\ngrid position:"+pos, Toast.LENGTH_SHORT).show();
- }
- }
- });
- }
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- Log.e(TAG, "Exception");
- }
-
- return convertView;
- }
-
- @Override
- public int getCount()
- {
- return vector.size();
- }
-
- @Override
- public Object getItem(int position) {
- return null;
- }
-
- @Override
- public long getItemId(int position) {
- return 0;
- }
-
- @Override
- public void unregisterDataSetObserver(DataSetObserver observer)
- {
- if (observer != null) {
- super.unregisterDataSetObserver(observer);
- }
- }
- }
具體步驟請看代碼中的註釋,須要注意的是,裏面的GridView使用的是自寫的控件,由於若使用Android自帶的GridView,會出如今ListView中只顯示一行grid的狀況,這是由於ListView沒法動態獲取GridView的數目而沒法肯定它的高度,所以默認認爲只有一行數據。.net
解決方法是:在自寫的GridView裏面,須要重寫onMeasure方法,這樣就能夠獲得GridView的高度了,代碼以下:3d
- package com.example.gridinlist;
-
- import android.widget.GridView;
-
- public class MyGridView extends GridView
- {
- public MyGridView(android.content.Context context,
- android.util.AttributeSet attrs)
- {
- super(context, attrs);
- }
-
-
- public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
- {
- int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
- MeasureSpec.AT_MOST);
- super.onMeasure(widthMeasureSpec, expandSpec);
-
- }
-
- }
ListView的item佈局文件:
- <?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="wrap_content"
- android:layout_marginTop="1dip"
- android:layout_marginBottom="1dip"
- android:orientation="vertical"
- android:baselineAligned="false"
- android:background="#ffffff"
- >
-
- <RelativeLayout
- android:id="@+id/list_rel"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dip"
- android:layout_marginBottom="10dip"
- >
-
- <ImageView
- android:id="@+id/list_img_icon"
- android:layout_width="3dip"
- android:layout_height="17dip"
- android:layout_marginLeft="15dip"
- android:contentDescription="@null"
- android:scaleType="fitXY"
- android:layout_centerVertical="true"
- android:src="@drawable/selected_orange"
- android:visibility="visible" />
-
- <TextView
- android:id="@+id/list_txt_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@+id/list_img_icon"
- android:layout_marginLeft="7dip"
- android:layout_marginRight="7dip"
- android:gravity="center"
- android:layout_centerVertical="true"
- android:singleLine="true"
- />
-
- </RelativeLayout>
-
- <com.example.gridinlist.MyGridView
- android:id="@+id/list_grid"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_marginBottom="1dip"
- android:columnWidth="70dip"
- android:horizontalSpacing="10dip"
- android:verticalSpacing="10dip"
- android:listSelector="@android:color/transparent"
- android:numColumns="4"
- android:paddingLeft="15dip"
- android:paddingRight="15dip"
- android:scrollbars="none"
- android:stretchMode="columnWidth"
- android:visibility="visible" >
- </com.example.gridinlist.MyGridView>
-
- <com.example.gridinlist.MyGridView
- android:id="@+id/list_grid_more"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_marginTop="10dip"
- android:layout_marginBottom="1dip"
- android:columnWidth="70dip"
- android:horizontalSpacing="10dip"
- android:verticalSpacing="10dip"
- android:listSelector="@android:color/transparent"
- android:numColumns="4"
- android:paddingLeft="15dip"
- android:paddingRight="15dip"
- android:scrollbars="none"
- android:stretchMode="columnWidth"
- android:visibility="gone" >
- </com.example.gridinlist.MyGridView>
-
- </LinearLayout>
裏面包含一個標題,以及兩個自寫的GridView(一個顯示前面部分,另外一個顯示剩下的,點擊展開與摺疊其實就是第二個GridView的顯示與隱藏)
GridView的item佈局文件:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <TextView
- android:id="@+id/ItemText"
- android:layout_width="70dip"
- android:layout_height="32dip"
- android:background="@drawable/btn_txt_bg"
- android:text=""
- android:gravity="center"
- />
-
- </RelativeLayout>
只是簡單的一個TextView,用戶想擴展或豐富可自行修改。代碼下載鏈接:http://download.csdn.net/detail/duguju/9233759