4

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

 2 years ago
source link: http://www.androidchina.net/2699.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

之前写过一篇关于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"
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>

六、实现的效果图

Center

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

项目资源下载:

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK