自定义万能Adapter和自定义多变布局可交互ListView(一)
来源:互联网 发布:电磁炉 电陶炉 知乎 编辑:程序博客网 时间:2024/06/07 05:29
前言
ListView与Adapter是Android一组很常用的组合,本篇博客旨在探究它们的各种应用场景:1、自定义万用Adapter+自定义同布局不可交互ListView(简单)2、自定义万用Adapter+自定义不同布局可交互ListView(略复杂)
自定义万能用Adapter
一、准备内容:
1.自定义ViewHolder; 2.自定义Abstract CommonAdapter(extends BaseAdapter) 3.自定义Entity用于存储数据(复杂情况下可以对多种数据类型进行封装) 4.自定义回调接口或抽象类
二、CommonAdapter需要数据:
1.Context context;--上下文不要解释 2.List<Entity>;--Entity里可封装多种数据类型
三、CommonAdapter提供调用方法(不包含BaseAdapter的抽象方法):
1.abstract void convert;--获取item组件的抽象方法,子类继承实现 2.abstract int getLayoutId;--获取item布局的抽象方法,子类继承实现,可用于获取不同布局
四、自定义ViewHolder提供给CommonAdapter的调用方法
1.getViewHolder;--获取ViewHolder实例 2.getmContertView;--返回已加载ContertView实例 3.getView;--获取item内组件
五、子类XXXAdapterCommonAdapter
1.实现抽象方法; 2.设置回调onXXXListener;
六、演示效果
七、直接贴代码
1.FirstListActivity: (1)activity_firstlist: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="heros.example.com.mylistview.MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:textSize="20dp" android:text="自定义万能用Adapter" /> <ListView android:id="@+id/firstlist" android:layout_marginTop="20dp" android:layout_below="@+id/textView" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </RelativeLayout> (2)FirstListActivity.class public class FirstListActivity extends AppCompatActivity { List<MyEntity> entityList; MyEntity firstEntity; FirstAdapter mAdapter; @BindView(R.id.firstlist) ListView firstlist; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_firstlist); ButterKnife.bind(this); setItem(); } private void setItem() { //构造数据 entityList = new ArrayList<MyEntity>();//空指针高发处 for (int i=0; i < 20; i++) { firstEntity = new MyEntity(R.layout.item_fistlist,R.drawable.book, "神经网络与深度学习","电子工业出版社","价格:¥"+(40+i)); entityList.add(firstEntity); } //创建adapter mAdapter = new FirstAdapter(this,entityList, mClickListener, onItemClickListener); firstlist.setAdapter(mAdapter); //设置回调 firstlist.setOnItemClickListener(onItemClickListener); } //Item响应回调 AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(FirstListActivity.this, "这一本:¥" + (40+position), Toast.LENGTH_SHORT).show(); } }; //控件响应回调 MyClickListener mClickListener = new MyClickListener() { @Override public void myOnClick(int position, View view) { Toast.makeText(FirstListActivity.this, "这一本是:神经网络与深度学习", Toast.LENGTH_SHORT).show(); } public void onClick(View v) { //先响应onclick(权限高) 可以将响应移交出去 myOnClick((Integer) v.getTag(), v); } }; } 2.自定义适配器 (1)FirstAdapter.class继承自CommonAdapter.class public class FirstAdapter extends CommonAdapter { //这里声明了两种回调响应 //OnItemClickListenerListView自带属性 AdapterView.OnItemClickListener onItemClickListener; //MyClickListener自定义响应接口(也可使用抽象类回调) MyClickListener mClickListener; public FirstAdapter(Context context, List<MyEntity> list, MyClickListener myClickListener, AdapterView.OnItemClickListener onItemClickListener) { //回调父类构造方法 super(context, list); this.onItemClickListener = onItemClickListener; this.mClickListener = myClickListener; } //实现父类抽象方法,加载item内组件 @Override public void convert(ViewHolder mViewHolder, MyEntity mEntity, int position) { ImageView leftImg = (ImageView) mViewHolder.getView(R.id.leftImg); TextView tv1 = (TextView) mViewHolder.getView(R.id.itemTv1); TextView tv2 = (TextView) mViewHolder.getView(R.id.itemTv2); TextView tv3 = (TextView) mViewHolder.getView(R.id.itemTv3); leftImg.setImageResource(mEntity.getImgId()); tv1.setText(mEntity.getNameStr()); tv2.setText(mEntity.getIntroduceStr()); tv3.setText(mEntity.getPirceStr()); leftImg.setOnClickListener(mClickListener); } //实现父类抽象方法,传送item布局id @Override public int getLayoutId(int type) { return R.layout.item_fistlist; } } (2)抽象类CommomAdapetr.class public abstract class CommonAdapter extends BaseAdapter { ViewHolder mViewHolder; List<MyEntity> mEntityList; MyEntity mEntity; LayoutInflater mInflater; Context context; public CommonAdapter(Context context, List<MyEntity> list){ this.context = context; this.mEntityList = list; mInflater = LayoutInflater.from(context); } @Override public int getCount() { return mEntityList.size(); } //这里主要返回的类型修改为MyEntity @Override public MyEntity getItem(int position) { return mEntityList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { //从MyEntity中获取布局类型号,调用子类实现抽象方法getLayoutId,获取布局int int layoutId = getLayoutId(getItem(position).getType()); //获取mViewHolder实例 ViewHolder mViewHolder = getViewHolder(context,position,convertView,parent,layoutId); convert(mViewHolder,getItem(position),position); //一定注意这里返回的方式,我就遗忘这里不止一次造成空指针 return mViewHolder.getContertView(); } //获取item组件的抽象方法,子类继承实现 public abstract void convert(ViewHolder mViewHolder, MyEntity mEntity, int position); //获取item布局的抽象方法,子类继承实现,可用于获取不同布局 public abstract int getLayoutId(int type); } (3)ViewHolder.class(也可以写成内部类) public class ViewHolder { private SparseArray<View> mView;//存储要获取组件的数组 private int position; private View mContertView;//装载组件的容器 public ViewHolder(Context context,int position,ViewGroup parent,int layoutId){ this.position = position; this.mView = new SparseArray<View>(); mContertView = LayoutInflater.from(context).inflate(layoutId,parent,false); mContertView.setTag(this); } public static ViewHolder getViewHolder(Context context,int position, View convertView, ViewGroup parent,int layoutId){ //判断是否首次调用getViewHolder if(convertView==null){ //首次为空 return new ViewHolder(context,position,parent,layoutId); }else{ //非首次不为空 return (ViewHolder) convertView.getTag(); } } //获取item内组件 public <T extends View> T getView(int viedId){ View view = mView.get(viedId); if(view==null){ view = mContertView.findViewById(viedId); mView.put(viedId,view); } return (T)view; } //返回已加载mContertView实例 public View getContertView(){ return mContertView; } } 3.自定义数据存储与回调接口 (1)MyEntity.class public class MyEntity{ public MyEntity(int type, int imgId, String nameStr, String introduceStr, String pirceStr) { this.type = type; this.imgId = imgId; this.nameStr = nameStr; this.introduceStr = introduceStr; this.pirceStr = pirceStr; } int type; int imgId; String nameStr; String introduceStr; String pirceStr; public int getType() { return type; } public void setType(int type) { this.type = type; } public String getNameStr() { return nameStr; } public void setNameStr(String nameStr) { this.nameStr = nameStr; } public int getImgId() { return imgId; } public void setImgId(int imgId) { this.imgId = imgId; } public String getIntroduceStr() { return introduceStr; } public void setIntroduceStr(String introduceStr) { this.introduceStr = introduceStr; } public String getPirceStr() { return pirceStr; } public void setPirceStr(String pirceStr) { this.pirceStr = pirceStr; } public String toString(){ String str = "MyEntity{type:"+Integer.toString(type)+",nameStr:"+nameStr+ ",introduceStr"+introduceStr+",pirceStr:"+pirceStr+"}"; return str; } } (2)MyClickListener.class public interface MyClickListener extends View.OnClickListener { public void myOnClick(int position, View view); } 4.程序入口MainActivity (1)activity_main <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="heros.example.com.mylistview.MainActivity"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:textSize="20dp" android:text="自定义ListView应用场景探究" /> <Button android:id="@+id/button1" android:text="自定义万用Adapter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textView" android:layout_alignLeft="@+id/textView" android:layout_alignRight="@+id/textView" android:layout_centerHorizontal="true" android:layout_marginTop="20dp"/> <Button android:id="@+id/button2" android:text="自定义不同布局可交互ListView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/button1" android:layout_alignLeft="@+id/textView" android:layout_alignRight="@+id/textView" android:layout_centerHorizontal="true" android:layout_marginTop="20dp"/> </RelativeLayout> (2)MainActivity.class public class MainActivity extends AppCompatActivity { @BindView(R.id.textView) TextView textView; @BindView(R.id.button1) Button button1; @BindView(R.id.button2) Button button2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); } @OnClick({R.id.button1, R.id.button2}) public void onClick(View view) { switch (view.getId()) { case R.id.button1: Intent i1 = new Intent(MainActivity.this,FirstListActivity.class); startActivity(i1); break; case R.id.button2: Intent i2 = new Intent(MainActivity.this,SecondListActivity.class); startActivity(i2); break; } } }
总结
1.通过abstract CommonAdapter + ViewHolder,仅仅需要FirstAdatper extends CommonAdapter,实现其中两个抽象方法就可以完成基础的adapter功能;
2.使用Entity可以传送多类型数据,并且可以通过设置type实现不同item布局;
3.使用XXXListener可以实现事件回调,自定义回调更好用;
源码连接
# 转载请注明出处!!!
阅读全文
0 0
- 自定义万能Adapter和自定义多变布局可交互ListView(一)
- 自定义listview holder 和adapter
- Android低阶【chapter-5】ListView和自定义适配器(Adapter)
- Android中自定义Adapter和ListView
- ListFragment使用ListView和自定义Adapter
- listview 自定义Adapter
- listview 自定义Adapter
- 自定义Adapter与ListView
- ListView使用自定义Adapter
- ListView 自定义Adapter
- 自定义ListView的Adapter
- 自定义Adapter的ListView
- 自定义listview的adapter
- Listview的自定义Adapter
- 自定义adapter的listview
- 自定义Adapter填充listview
- 自定义ListView的Adapter
- 自定义listview的显示(重写Adapter)
- ubuntu中的语言支持没有了怎么办
- linux 内存管理
- Webots 获取30天试用版license
- 惊魂时刻!技术生涯中遇到的最让你担惊受怕的事件是什么?
- Glassfish&netbeans乱码纠正
- 自定义万能Adapter和自定义多变布局可交互ListView(一)
- 正则表达式给查找到的内容加引号
- linux编辑Authority文件时如何调到行尾或行首
- 这哪是NBA球场!简直就是黑科技实验室啊!
- CRC校验算法
- MFC常用DC相关类的作用
- 大端小端(字节序)
- OpenCV图像读取与灰度化
- 数据结构---线性表---顺序存储