之前写过一篇关于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
如有转载未注明出处博客网址,或者没有得到作者的同意。作者持有版权所有权。