1、简介
在Android开发过程中,我们经常需要写一些ListView和GridView等控件,如果给每一个都写一个适配器的话,过程无疑十分的枯燥,只会消耗大量的时间做这写毫无意义的事情,下面给大家介绍一个通用适配器。
2.一般的适配器的使用
普通的用法是:每一个ListView或者是GridView需要一个资源配置的XML文件,一个ViewHolder,一个普通的继承BaseAdapter的适配器。
1.布局文件
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
</ListView>
2.Item的布局文件:item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="您好!"/>
</RelativeLayout>
3.Adapter
package com.fly.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.List;
/**
* Created by fly on 2016/10/9.
*/
public class MyAdapter extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private List<String> list;
public MyAdapter(Context context, List<String> list) {
this.context = context;
this.list = list;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return list.size();
}
@Override
public String getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item, parent);
holder = new ViewHolder();
holder.textView = (TextView) convertView.findViewById(R.id.textView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(list.get(position));
return convertView;
}
private class ViewHolder {
TextView textView;
}
}
相信大家对以上的写法并不陌生,估计有的人都已经写的要吐血了。下面给大家介绍一种通用的适配器。下面我们来总结一下写适配器的所需要的步骤:
1、现在主布局中添加一个ListView的控件;
2、编写一个Item的布局文件;
3、声明一个类继承BaseAdapter,并重写所需要重写的方法;
4、写一个ViewHoler的内部类,里面声明Item中的控件;当是第一次调用该适配器时存储控件,之后直接调用ViewHolder里面声明的控件,用来提高效率。
5、通过getView()方法来实现所需要的功能。
通过总结我们发现上面步骤中1~4完全相同,那么我们的问题来了:能不能将之前的第三步和第四步完全封装到一个类中,以方便我们使用呢?
答案当然是可以的,要不然我怎么接着往下写呢!
首先我们来换个思路,每一个适配器中都需要有一个ViewHolder,那么我们干脆写一个ViewHolder用来放置所有的控件。要放置很多个控件我们可以用到集合和数组,我们还需要通过特定的条件来找到该控件,不然我们怎么用。因此我们可以使用到Map集合来存储各种控件,通过控件的id来获取。有一个SparseArray是对Map集合的封装,是key为Integer的Map集合。因为我们所使用的控件的id都是int类型,所以可以使用该集合。
1、通用的ViewHolder
package com.fly.adapter;
import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by fly on 2016/10/9.
*/
public class CommonViewHolder {
//key是Integer类型的Map集合
private SparseArray<View> mViews;
private View convertView;
private CommonViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
//初始化
mViews = new SparseArray<>();
//加载视图
convertView = LayoutInflater.from(context).inflate(layoutId, parent,false);
convertView.setTag(this);
}
//CommonViewHolder的入口方法
public static CommonViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position) {
if (convertView == null) {
return new CommonViewHolder(context, parent, layoutId, position);
}
return (CommonViewHolder) convertView.getTag();
}
//这里是获取各种view
public <T extends View> T getView(int viewId){
View view = mViews.get(viewId);
if (view == null) {
view = convertView.findViewById(viewId);
mViews.put(viewId,view);
}
return (T) view;
}
//获取convertView
public View getConvertView(){
return convertView;
}
}
写完ViewHolder之后,可以在适配器中使用了,下面是之后的Adapter的代码:
package com.fly.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.List;
/**
* Created by fly on 2016/10/9.
*/
public abstract class CommonAdapter<T> extends BaseAdapter {
protected Context context;
protected List<T> list;
protected LayoutInflater inflater;
protected int itemLayoutId;
public CommonAdapter(Context context, List<T> list, int itemLayoutId) {
this.context = context;
this.list = list;
inflater.from(context);
this.itemLayoutId = itemLayoutId;
}
@Override
public int getCount() {
return list.size();
}
@Override
public T getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//获取CommonViewHolder
CommonViewHolder holder = getCommonViewHolder(position, convertView, parent);
//通过getView()获取控件
TextView textView = holder.getView(R.id.textView);
textView.setText(getItem(position).toString());
return holder.getConvertView();
}
}
上面的代码可以根据需要传入不同的Java bean或者是类型,就不一一实现了。
下面开始写通用的适配器:
首先我们来分析一下写适配器的步骤:
1、传入一个Context对象;
2、传入一个LayoutInflater对象
3、传入一个List集合
4、根据需求在getView方法中写需求
这样的话我们其实是可以将getView方法提取出来,让其子类去实现该方法。这样的话代码就可以改成这样了:
package com.fly.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.List;
/**
* Created by lihb on 2016/10/9.
*/
public abstract class CommonAdapter<T> extends BaseAdapter {
protected Context context;
protected List<T> list;
protected LayoutInflater inflater;
protected int itemLayoutId;
public CommonAdapter(Context context, List<T> list, int itemLayoutId) {
this.context = context;
this.list = list;
inflater.from(context);
this.itemLayoutId = itemLayoutId;
}
@Override
public int getCount() {
return list.size();
}
@Override
public T getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public abstract View getView(int position, View convertView, ViewGroup parent);
}
package com.fly.picasso;
import android.content.Context;
import android.widget.TextView;
import java.util.List;
/**
* Created by fly on 2016/9/30.
*/
public class MyAdapter extends CommonAdapter {
public MyAdapter(Context context, List list, int itemLayoutId) {
super(context, list, itemLayoutId);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//获取CommonViewHolder
CommonViewHolder holder = getCommonViewHolder(position, convertView, parent);
//通过getView()获取控件
TextView textView = holder.getView(R.id.textView);
textView.setText(getItem(position).toString());
return holder.getConvertView();
}
}
这样的话一个简单的通用适配器就完成了。