Android—万能ListView适配器

ListView是开发中最常用的控件了,但是总是会写重复的代码,浪费时间又没有意义。

最近参考一些资料,发现一个万能ListView适配器,代码量少,节省时间,总结一下分享给大家。

首先有一个自定义的Adapter继承于BaseAdapter,下面是自定义的Adapter,精华在getView()方法中

复制代码
package com.example.mylistview.util;

import java.util.List;

import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; public abstract class CommonAdapter<T> extends BaseAdapter { /** * 上下文 */ private Context mContext; /** * 实体类集合 */ private List<T> mDatas; private LayoutInflater mInflater; /** * 控件id */ private int mlayoutId; public CommonAdapter(Context context, List<T> datas, int layoutId) { this.mContext = context; this.mDatas = datas; this.mlayoutId = layoutId; mInflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return mDatas.size(); } @Override public T getItem(int arg0) { // TODO Auto-generated method stub return mDatas.get(arg0); } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(int arg0, View arg1, ViewGroup arg2) { // TODO Auto-generated method stub ViewHolder holder = ViewHolder.get(mContext, arg1, arg2, mlayoutId, arg0); convert(holder, getItem(arg0)); return holder.getConvertView(); } public abstract void convert(ViewHolder holder, T t); }
复制代码

以上的抽象方法convert(ViewHolder holder, T t);就相当于以前通用代码中的

viewHolder.mTextView = (TextView) convertView .findViewById(R.id.id_tv_title);

viewHolder.mTextView.setText(Bean.getName());

找到控件的id再去设施setText等重复的代码方法中的参数ViewHolder holder, T t    holder就相当于以前通用代码中的viewHolder,t就相当于一个自己定义的实体类Bean。

以上代码中getView()方法中有一个ViewHolder是需要自己声明的,以下是代码以及详细注释:

复制代码
package com.example.mylistview.util;

import android.content.Context;
import android.graphics.Bitmap; import android.renderscript.Type; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; public class ViewHolder { /** * SparseArray类存放View集合 */ private SparseArray<View> mViews; /** * */ private int mPosition; /** * 布局文件 */ private View mConvertView; public View getConvertView() { return mConvertView; } public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) { this.mViews = new SparseArray<View>(); this.mPosition = position; this.mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false); this.mConvertView.setTag(this); } /** * 拿到一个ViewHolder对象 * @param context * @param convertView * @param parent * @param layoutId * @param position * @return */ public static ViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position) { if (null == convertView) { return new ViewHolder(context, parent, layoutId, position); } else { ViewHolder holder = (ViewHolder) convertView.getTag(); holder.mPosition = position; return holder; } } /** * 通过控件的id获取对应的控件,如果没有则加入views * @param viewId * @return */ public <T extends View> T getView(int viewId) { View view = mViews.get(viewId); if (null == view) { view = mConvertView.findViewById(viewId); mViews.put(viewId, view); } return (T) view; } /** * 为TextView设置字符串 * @param viewId * @param text * @return */ public ViewHolder setText(int viewId, String text) { TextView tv = getView(viewId); tv.setText(text); return this; } /** * 为ImageView设置图片 * * @param viewId * @param drawableId * @return */ public ViewHolder setImageResource(int viewId, int drawableId) { ImageView view = getView(viewId); view.setImageResource(drawableId); return this; } public int getPosition() { return mPosition; } }
复制代码

再写一个Adapter继承于万能适配器CommonAdapter,还是要写一个自己的Adapter,因为一个项目可能会有多个ListView,但是每个的item元素,布局都会有所不同的,这个泪用来区分不同的ListView与自己所对应的item.这个代码量较少完全可以写成内部类在Activity.java中.

复制代码
package com.example.mylistview.adapter;

import java.util.List;

import android.content.Context; import android.view.View; import android.view.View.OnClickListener; import android.widget.CheckBox; import com.example.mylistview.R; import com.example.mylistview.domain.Bean; import com.example.mylistview.util.CommonAdapter; import com.example.mylistview.util.ViewHolder; public class MyAdapter extends CommonAdapter<Bean> { public MyAdapter(Context context, List<Bean> datas, int layoutId) { super(context, datas, layoutId); // TODO Auto-generated constructor stub  } @Override public void convert(ViewHolder holder, final Bean bean) { // TODO Auto-generated method stub  holder.setText(R.id.tv_title, bean.getTitle()) .setText(R.id.tv_desc, bean.getDesc()) .setText(R.id.tv_time, bean.getTime()) .setText(R.id.tv_phone, bean.getPhone()); /** * 防止CheckBox混乱 */ final CheckBox cBox = (CheckBox)(holder.getView(R.id.cb)); if (cBox != null) { cBox.setChecked(bean.isChecked()); cBox.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { bean.setChecked(cBox.isChecked()); } }); } } }
复制代码

 

优化之后用适配器的时候就简单多了下面是实体类,item和MainActivity.java中的代码:

实体类:

复制代码
package com.example.mylistview.domain;

public class Bean { private String title; private String desc; private String time; private String phone; private boolean isChecked; public boolean isChecked() { return isChecked; } public void setChecked(boolean isChecked) { this.isChecked = isChecked; } /** * @param title * @param desc * @param time * @param phone */ public Bean(String title, String desc, String time, String phone) { this.title = title; this.desc = desc; this.time = time; this.phone = phone; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
复制代码

MainActivity.java:

重点代码:

参数有上下文,集合,和自己对应的item就可以了
 adapter = new MyAdapter(this, mDatas, R.layout.item); 
复制代码
package com.example.mylistview.ui;

import java.util.ArrayList;
import java.util.List; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import com.example.mylistview.R; import com.example.mylistview.adapter.MyAdapter; import com.example.mylistview.domain.Bean; public class MainActivity extends Activity { private ListView listView; private List<Bean> mDatas; /** * 适配器 */ private MyAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); listener(); } private void listener() { // TODO Auto-generated method stub listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub startActivity(new Intent(MainActivity.this, SecondActivity.class)); } }); } private void initData() { // TODO Auto-generated method stub mDatas = new ArrayList<Bean>(); Bean bean = new Bean("Android新技能 Get", "Android-打造万能的ListView和GridView适配器", "2015-08-05", "10086"); mDatas.add(bean); bean = new Bean("捡到权志龙一个", "在星巴克捡到权志龙一个", "2015-08-06", "10086"); mDatas.add(bean); bean = new Bean("GetTOP一个", "在韩国首尔捡到TOP一个", "2015-08-07", "10086"); mDatas.add(bean); adapter = new MyAdapter(this, mDatas, R.layout.item); listView.setAdapter(adapter); } private void initView() { // TODO Auto-generated method stub listView = (ListView) findViewById(R.id.listView); } }
复制代码

item布局:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp" >

    <CheckBox
        android:focusable="false"
        android:id="@+id/cb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerInParent="true" />

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:singleLine="true"
        android:text="Android新技能 Get" />

    <TextView
        android:id="@+id/tv_desc"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_title"
        android:layout_marginTop="10dp"
        android:layout_toLeftOf="@id/cb"
        android:maxLines="2"
        android:text="Android-打造万能的ListView和GridView适配器"
        android:textColor="#898989" />

    <TextView
        android:id="@+id/tv_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_desc"
        android:layout_marginTop="10dp"
        android:text="2015-08-05"
        android:textColor="#898989"
        android:textSize="12sp" />

    <TextView
        android:id="@+id/tv_phone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@id/tv_desc"
        android:layout_marginTop="10dp"
        android:background="#20793D"
        android:maxLines="1"
        android:text="10086"
        android:padding="4dp"
        android:textColor="#FFF" />

</RelativeLayout>
复制代码

效果图:

用这个去适配另一个不同的布局:

新布局的Adapter一样继承自己的万能adapter:CommonAdapter

复制代码
package com.example.mylistview.adapter;

import java.util.List;
import java.util.Map; import android.content.Context; import com.example.mylistview.R; import com.example.mylistview.util.CommonAdapter; import com.example.mylistview.util.ViewHolder; public class SecondAdapter extends CommonAdapter<Map<String, String>> { public SecondAdapter(Context context, List<Map<String, String>> datas, int layoutId) { super(context, datas, layoutId); // TODO Auto-generated constructor stub  } @Override public void convert(ViewHolder holder, Map<String, String> t) { // TODO Auto-generated method stub holder.setText(R.id.tv_item2values, t.get("values")); } }
复制代码

Activity.java代码:

复制代码
package com.example.mylistview.ui;

import java.util.ArrayList;
import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; import com.example.mylistview.R; import com.example.mylistview.adapter.MyAdapter; import com.example.mylistview.adapter.SecondAdapter; public class SecondActivity extends Activity { private ListView listView_second; private SecondAdapter secondAdapter; private List<Map<String, String>> lists = new ArrayList<Map<String, String>>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); initView(); initData(); } private void initData() { // TODO Auto-generated method stub for (int i = 0; i < 4; i++) { Map map = new HashMap<String, String>(); map.put("values", "条目" + i); lists.add(map); } secondAdapter = new SecondAdapter(this, lists, R.layout.item2); listView_second.setAdapter(secondAdapter); } private void initView() { // TODO Auto-generated method stub listView_second = (ListView) findViewById(R.id.listView_second); } }
复制代码

item:

复制代码
<?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="match_parent"
    android:orientation="horizontal" >

 

    <TextView
        android:id="@+id/tv_item2values"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="ffffff"
        android:layout_margin="16dp"
        android:gravity="center" />

</LinearLayout>
复制代码

效果图:

备忘,希望能给大家带来帮助。

转载于:https://www.cnblogs.com/lenkevin/p/5779951.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值