先上图。可以看到。这是一个很普通的扩展列表。在子项中。有一个减号的按钮。
要 实现的功能是点击某个item。绿色的文本数字加一。点击红色的减号。文本减一。吼。这个真的不容易的啊。特别对于我这样的菜鸟来说。不过幸好的是我在写 这个之前。研究过一段时间的listview。可扩展列表事实上和listview没有太大区别。都是用适配器来完成数据到界面的填充。listview 的适配器用getview的方法来返回一个view用于显示。但是扩展列表有两级。所以就有getgroupview和getchildview两个方法 分别返回红色条纹的组视图。和白色条纹的子视图。回到话题。
点击某个item的事件是setOnChildClickListener这个 方法来设置监听器。这个是容易办到的。但是怎么监听控件的点击事件。如果直接用setonclick来注册监听器的话。会发现一个情况。就是不管点击 item还是点击减号。通通都不执行函数体了。关于这点疑问我个人觉得是因为点击事件传递有关。在返回值中将传递性变为了false。这里就不做更深的讨 论。好。那如何避免这种情况。也就是说让点击item和点击减号都能正常运行呢。这就要用到上面提到的getchildview这个函数了。这个函数前面 已经提过。是用来绘制子项的。看一下他的函数声明。
public View getChildView( int groupPosition,
int childPosition, boolean isLastChild,
View convertView, ViewGroup parent)
一共有五个参数。
groupPosition 组位置(该组内部含有子元素)
childPosition 子元素位置(决定返回哪个视图)
isLastChild 子元素是否处于组中的最后一个
convertView 重用已有的视图(View)对象。注意:在使用前你应该检查一下这个视图对象是否非空并且这个对象的类型是否合适。由此引伸出,如果该对象不能被转换并显示正确的数据,这个方法就会调用getchildview(int ,int,boolean,view,viewgroup)来创建一个视图(View)对象。(这点类似于listview。如果看过如何优化listview的同学。对于这个就会很清楚了。)
parent 返回的视图(View)对象始终依附于的视图组。
返回值
指定位置上的子元素返回的视图对象
那为什么要提这个函数呢。这个函数是系统绘制子项的时候回调的一个函数。什么意思?
当 我们点击上图中的面条这一选项时。其中包含三个子项。就是三个view。也就是说要调用三次getchildview来绘制这三个view.(其实是调用 了六次。先将三个view绘制一遍。然后重复绘制一遍。关于这个。没找到什么合理的解释。有知道的朋友可以告知我一声。)
既然这个函数是来 绘制子项的。那如果将减号的监听器设置在这里面。会怎么样?当然是每绘制一个view就为其中的减号设置了监听器。这个相比之前的之间来设置减号的监听器 有什么分别?当然是有的。之前的那种设置方法。仅仅是设置了一个减号的监听器。但是系统是不知道这个减号是哪个减号的。举个例子。假如说这个扩展列表是一 栋房子。item是一层。而这个减号是一间房子。现在要知道哪里着火了。就要在每间房子中都放置一个火警报警器。如果将这个火警报警器放在楼外边。怎么能 知道到底是哪里发生了火灾呢。同理。如果不将监听器随着geichildview在每一个绘制的view中去设置。那点击那些没有设置监听器的view。 点击事件怎么可能促发。不知道讲没讲清楚。
这个逻辑理顺了。还有些问题。我们知道列表在绘制的时候是不停的调用getchildview这 个方法的。什么意思呢。就是当我们点击面条这个组。系统调用三次getchildview来绘制三个view。再点击一次面条。这三个view就收起来。 同时系统将他们销毁。再点开。系统其实是又调用了三次。重新绘制的。提这个干嘛?当然是要注意的地方了。之前解决了点击item和点击减号的事件响应问 题。但是变化的文本是不会帮你保存下来的。加入你开始的时候文本是1.再次绘制的时候仍然是1.所以在改变了文本之后你要对适配器的数据进行更新。博主之 前为这个可是吃了不少苦。当然有些朋友可能早就知道了。
package com.example.expandablelistview;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
private int[][] nums = new int[][] { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 0 } };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ExpandableListView expandablelistview = (ExpandableListView) this
.findViewById(R.id.Expandablelistview);
final