最新消息:欢迎访问Android开发中文站!商务联系微信:loading_in

Android listview的适配器以及各种监听、效率的提升

开发进阶 AndroidChina 4676浏览 1评论

之前写过一篇关于listview的博客,现在感觉那篇博客关于listview认识不够全面。但有些方法还是可取,例如灵活的监听,写适配器。链接在这里android listview长按,单击各种事件捕捉。那个单击监听是一项项设置监听,效率也不好。

不断工作的过程,也是不断总结过程。现在对于listview有了更透彻的理解,所以重新写了一个实践demo。这个demo有涉及到listview的数据源,布局,适配器以及各种监听、效率的提升。现在对于这些理解,想写出一个通用的适配器,但发现还是有点困难,就是数据源问题,还有布局。但是写成通用适配器也是可以,用继承方法。凡是关于listview的数据源以及布局实现实现就用函数调用,然后继承后重写这些方法就可以了。因为我在公司项目也是这样,效果还不错。下面来讲解一下listview。

一、实体类ItemTest

这是一个定制listview,所以写一个实体类作为listview适配器的适配类型。

package com.example.customlistviewdemo;

/**
* 实体类 ItemTest
* @author mmsx
* 博主博客网址: http://blog.csdn.net/qq_16064871
*/
public class ItemTest {
     private int mImageViewID;
     private String mstrName;

     public ItemTest(){

     }

     public ItemTest(int ImageViewID, String strName) {
          this.mImageViewID = ImageViewID;
          this.mstrName = strName;
     }

     public int getImageViewID() {
          return mImageViewID;
     }

     public String getstrName() {
          return mstrName;
     }
}

二、listview的对于实体类ItemTest的适配器SelfAdapt

listview 适配器 继承自BaseAdapter,通过SelfAdapt的构造函数传入activity的生命周期、listview的布局、以及数据源。
在里面用了判断convertView是否为空,来减少加载布局,提升效率。
还有用了一个内部类ViewHolder来减少查找布局里面的id,用标签方式缓存convertView.setTag(viewHolder);,然后取出来viewHolder = (ViewHolder) convertView.getTag();

这样做listview效率就有很不错效果了。

package com.example.customlistviewdemo;

import java.util.ArrayList;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.TextView;

/**
* listview 适配器 继承自BaseAdapter
* @author mmsx
* 博主博客网址: http://blog.csdn.net/qq_16064871
*/
public class SelfAdapt extends BaseAdapter implements OnCheckedChangeListener{
     private Context mContext;
     private int mresourceLayoutID;
     private LayoutInflater mLayoutInflater;
     private ArrayList<ItemTest> mList;

     /**
       * 适配器的构造函数
       * @param context
       * @param resourceLayoutID
       * @param list
       */
     public SelfAdapt(Context context, int resourceLayoutID ,ArrayList<ItemTest> list){

          this.mContext = context;
          this.mresourceLayoutID = resourceLayoutID;
          this.mList = list;

          //取得xml里定义的view,并且实例化
          mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     }

     @Override
     public int getCount() {
          return mList != null ? mList.size() : 0;
     }

     @Override
     public Object getItem(int position) {
          return position;
     }

     @Override
     public long getItemId(int position) {
          return position;
     }

     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
          ViewHolder viewHolder = null;
          if (convertView == null) {
               //这样写不用每次都加载布局,以及查找id,提高listview的效率
               convertView = mLayoutInflater.inflate(mresourceLayoutID, null);
               viewHolder = new ViewHolder();
               viewHolder.imageView = (ImageView)convertView.findViewById(R.id.imageView1);
               viewHolder.textView = (TextView)convertView.findViewById(R.id.textViewTest);
               viewHolder.checkbox = (CheckBox)convertView.findViewById(R.id.checkBox1);
               //标签加入Tag
               convertView.setTag(viewHolder);
          }else {
               //当convertView不为空是,从标签ViewHolder取出
               viewHolder = (ViewHolder) convertView.getTag();
          }

          ItemTest itemTest = new ItemTest();
          itemTest = mList.get(position);

          viewHolder.imageView.setImageResource(itemTest.getImageViewID());
          viewHolder.textView.setText(itemTest.getstrName());

          //设置checkbox的监听
          viewHolder.checkbox.setOnCheckedChangeListener(this);
          viewHolder.checkbox.setTag(position);

          return convertView;
     }

     //内部类实现,提升listview效率
     class ViewHolder {
          public ImageView imageView;
          public TextView textView;
          public CheckBox checkbox;
     }

     @Override
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
          int nPosition = ((Integer) buttonView.getTag()).intValue();
          Toast.makeText(mContext, String.valueOf(nPosition) + " CheckBox 的点击" + String.valueOf(isChecked),                                 Toast.LENGTH_SHORT).show();
     }
}

三、MainActivity

在这里面设置了listview单击,长按的接口监听。

listView.setOnItemClickListener(this);    //设置单击监听,接口实现
listView.setOnItemLongClickListener(this);  //设置长按监听,接口实现

设置这两个要进行接口

implements
OnItemClickListener,
OnItemLongClickListener

下面看全部代码

package com.example.customlistviewdemo;

import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;

/**
* listview 比较标准写法,以及提升listview效率
* @author mmsx
* 博主博客网址: http://blog.csdn.net/qq_16064871
*/
public class MainActivity extends Activity implements OnItemClickListener, OnItemLongClickListener{

     private ArrayList<ItemTest> mArrayList = new ArrayList<ItemTest>();

     @Override
     protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);

           InitUI();
     }

     private void InitUI() {
           if (mArrayList != null) {
                  mArrayList.clear();
                  for (int i = 0; i < 50; i++) {
                        ItemTest itemTest1 = new ItemTest(R.drawable.bmp1,"图片一");
                        mArrayList.add(itemTest1);
                        ItemTest itemTest2 = new ItemTest(R.drawable.bmp2,"图片二");
                        mArrayList.add(itemTest2);
                  }
           }

           ListView listView = (ListView)findViewById(R.id.listView1);
           SelfAdapt selfAdapt = new SelfAdapt(getApplicationContext(), R.layout.listview_item ,mArrayList);
           listView.setAdapter(selfAdapt);
           listView.setOnItemClickListener(this);    //设置单击监听,接口实现
           listView.setOnItemLongClickListener(this);  //设置长按监听,接口实现
     }

     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
           Toast.makeText(this, "listview 的点击" + parent.getItemAtPosition(position), Toast.LENGTH_SHORT).show();
     }

     @Override
     public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
          Toast.makeText(this, "listview 的长按", Toast.LENGTH_SHORT).show();
          return true;
     }

}

四、listview的布局listview_item

是要实现实体类ItemTest,我格外增加了chexbox控件监听,示例一下实现。

其中这句话有时很重要    android:descendantFocusability=”blocksDescendants”

如果你的自定义ListViewItem中有Button或者Checkable的子类控件的话,那么默认focus是交给了子控件。所以需要加上这一句。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="50dp"
      android:descendantFocusability="blocksDescendants"
      android:orientation="horizontal" >

      <ImageView
              android:id="@+id/imageView1"
              android:layout_width="50dp"
              android:layout_height="50dp"
              android:src="@drawable/bmp1" />

      <TextView
              android:id="@+id/textViewTest"
              android:layout_width="0dp"
              android:layout_height="50dp"
              android:layout_weight="1"
              android:gravity="center"
              android:text="TextView"
              android:textColor="#FF236A9C" />

      <CheckBox
              android:id="@+id/checkBox1"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:textColor="#FF236A9C"
              android:text="选择" />

</LinearLayout>

五、activity_main

<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=".MainActivity" >

        <ListView
                android:id="@+id/listView1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true" >

        </ListView>

</RelativeLayout>

六、实现的效果图

另外我还在收集listview各种小知识,例如分隔线,点击不要默认效果,listview不滚动用滚动条等,后期会独自写一篇博客。

项目资源下载:

转载请注明出处的博客网址: http://blog.csdn.net/qq_16064871

转载请注明:Android开发中文站 » Android listview的适配器以及各种监听、效率的提升

您必须 登录 才能发表评论!

网友最新评论 (1)

  1. 烂大街的知识点,关键是DEMO里面有个很严重的BUG也没有解决!就这么在微信里面推荐了我也是醉了。
    ZeroLin2015-09-06 09:16