经过一段时间的潜伏,小编我终于有功夫更新下博客了。今天谈一谈ListView的嵌套问题。
这个问题已经有无数前辈对此分析过了,而网上也充满了千篇一律的模板,虽然可以使用,但还是会存在瑕疵,且不利于扩展。最近小编在工作上也遇到了这个头疼的问题,最终用另外一种方法把它解决了(是一种笨方法,网上没有哦),通俗来说,就是把各层ListView看成一个ListView,通过每次判断当前index的位置,来绘制当前的View,这样既保证了各层ListView的监听事件,又可以流畅的添加多层内容,下面上传代码,大家仔细领会其中的奥秘。
本例子设计的是一个两层ListView嵌套。首先是布局文件,就是一个简单的ListView列表。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"下面便是本讲的重点:请童鞋们睁大眼睛。
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<!-- @author Arthur Lee -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="9"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="listView嵌套ListView"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" >
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" >
</ListView>
</LinearLayout>
</LinearLayout>
package com.example.nested;
/**
* @author Arthur Lee
* @time 08/04/2014
* */
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class MultiAdapter extends BaseAdapter {
Context context;
List<People> listParent;//父类数据
List<Student> listChild;//子类数据
LayoutInflater inflater;
HashMap<String, Boolean> clickFlag;//封装的点击事件
HashMap<String, List<Student>> listItem;//封装的子类数据,对应于每个父类的item
private int viewIndex1 = -1;//标记父类item的当前位置
private int viewIndex2 = -1;//标记子类item的当前位置
public MultiAdapter(Context context, List<People> listParent) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.listParent = listParent;
this.clickFlag = new HashMap<String, Boolean>();
this.listItem = new HashMap<String, List<Student>>();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
//每次对当前ListView的长度进行统计,检查listitem中是否存入新的数据,
//若存在,则意味着有一个父类item的点击事件被触发,子类item需要显示出来
int count = listParent.size();
if (null != listItem) {
for (String name : listItem.keySet()) {
listChild = listItem.get(name);
if (null != listChild)
count += listChild.size();
}
}
return count;
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
// TODO Auto-generated method stub
//根据当前的index值和返回的绘制标记,选择父类或子类的item绘制
int index = getLayout(position);
switch (index) {
case 1:
return getView1(
position,
view,
viewGroup,
listParent.get(viewIndex1));
case 2:
return getView2(
position,
view,
viewGroup,
listItem.get(listParent.get(viewIndex1).getName()).get(
viewIndex2));
default:
break;
}
return view;
}
//绘制父类ListView的item,即第一层ListView
public View getView1(int position, View view, ViewGroup viewGroup,
final People people) {
view = inflater.inflate(R.layout.first, null);
final TextView name = (TextView) view.findViewById(R.id.first_name);
final TextView year = (TextView) view.findViewById(R.id.first_year);
final TextView click = (TextView) view.findViewById(R.id.first_click);
name.setText(people.getName());
year.setText(people.getYear());
if (null == clickFlag.get(people.getName())
|| true == clickFlag.get(people.getName()))
click.setText("更多");
else
click.setText("收起");
click.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (null == clickFlag.get(people.getName())
|| true == clickFlag.get(people.getName())) {
clickFlag.put(people.getName(), false);
click.setText("收起");
listItem.put(people.getName(), getMessage());
notifyDataSetChanged();
} else {
clickFlag.put(people.getName(), true);
listItem.remove(people.getName());
click.setText("更多");
notifyDataSetChanged();
}
}
});
return view;
}
//绘制子类ListView的item,即第二层ListView
public View getView2(int position, View view, ViewGroup viewGroup,
final Student student) {
view = inflater.inflate(R.layout.second, null);
final TextView name = (TextView) view.findViewById(R.id.second_name);
final TextView year = (TextView) view.findViewById(R.id.second_year);
name.setText(student.getName());
year.setText(student.getYear());
name.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Toast.makeText(context, "选中" + name.getText().toString(),
Toast.LENGTH_LONG).show();
}
});
return view;
}
//对当期position的item判断和确定
/*
* 同理可绘制三层嵌套,或者在两层listView之间加入其他头部view或尾部view
*/
public int getLayout(int position) {
//默认每次都初始化viewIndex1和viewIndex2,保持数据的一致性
viewIndex1 = -1;
viewIndex2 = -1;
int index = -1;//当前item的游标
Iterator it = listParent.iterator();
while (it.hasNext()) {
index += 1;
viewIndex1 += 1;
People people = (People) it.next();
//首先判断一下是否是父类item,若是,则绘制父类item
if (position == index) {
return 1;
}
//若不是,判断是否是该父类下的子类item
if (null != listItem) {
listChild = listItem.get(people.getName());
if (null != listChild) {
if (position > index
&& position <= (index + listChild.size())) {
//若是,则绘制子类item
viewIndex2 = position - index - 1;
return 2;
} else
index += listChild.size();
}
}
}
return index;
}
//子类数据的获得
public List<Student> getMessage() {
List<Student> list = new ArrayList<Student>();
for (int i = 0; i < 3; i++) {
Student s = new Student("School:::" + i, "Grade." + i);
list.add(s);
}
return list;
}
}
然后是MainActivity的使用
package com.example.nested;
/**
* @author Arthur Lee
* @time 08/04/2014
* */
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.widget.ListView;
import android.widget.ScrollView;
public class MainActivity extends Activity {
static ListView list;
ScrollView scroll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = (ListView) findViewById(R.id.list);
list.setAdapter(new MultiAdapter(this, getMessage()));
}
public List<People> getMessage() {
List<People> list = new ArrayList<People>();
for (int i = 0; i < 5; i++) {
People people = new People("NO." + i, "Brith." + i);
list.add(people);
}
return list;
}
}
这就是全部内容了,欢迎大家踊跃提意见。