最近面试了一些安卓开发人员,我常问的问题就是关于listview的优化,大家知道,ListView的优化,真的是老问题了,但是百问不厌。
ListView最通用的写法,写一个listview,然后定义一个adaptor继承系统BaseAdaptor 重写getCount getItem getItemId getView 然后再写一个ViewHolder,一大堆的重复代码,我在一个项目中有十几个ListView 然后重复写了十几二十个Adaptor和一大堆无用且繁琐的代码…
后来谷歌又出了一个RecyleView才拯救了一大堆呼天喊地的程序猿。但是我们能不能让我们普通的ListView也可以这么方便使用呢?现在我们来仿一仿RecyleView.Adaptor 让我们写更少的代码,只关心我们关系的业务逻辑代码 。
package com.example.testlistview;
import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
/**
*
* @author 肖蕾
*
* @param <DataType> 传入的数据类型
* @param <viewHolder> ViewHoler的类型
*/
public abstract class BaseAdaptor<DataType,viewHolder extends BaseAdaptor.Holder> extends BaseAdapter
{
/**
* 保存的数据
*/
private List<DataType> list;
public BaseAdaptor(List<DataType> list)
{
this.list = list;
}
@Override
public int getCount()
{
return getItemCount();
}
@Override
public DataType getItem(int position)
{
return list.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
/**
* View 的创建
* @param parent 父控件
* @param viewType 类型
* @return
*/
public abstract viewHolder onCreateViewHolder(ViewGroup parent, int viewType);
/**
* ViewHolder与数据的绑定
* @param holder viewHoler对象
* @param data 数据
* @param position 定位
*/
public abstract void onBindViewHolder(viewHolder holder,DataType data,int position);
public int getItemCount()
{
if (list == null) {
return 0;
}
return list.size();
}
public int getItemViewType(DataType data,int position)
{
return super.getItemViewType(position);
}
@SuppressWarnings("unchecked")
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
viewHolder holder = null;
DataType data = list.get(position);
if (convertView == null)
{
holder = onCreateViewHolder(parent,getItemViewType(data,position));
convertView = holder.getRootView();
} else
{
holder = (viewHolder) convertView.getTag();
}
onBindViewHolder(holder,data, position);
return convertView;
}
public abstract static class Holder
{
private View root;
public Holder(View view)
{
this.root = view;
}
public View getRootView()
{
root.setTag(this);
return root;
}
}
}
这样我们就完工了,使用起来非常简单。
使用方法:
一、 继承上面的BaseAdapter 并写好相应的类型,Ctrl + 1 自动重写相应的方法 。
public class mAdapter extends BaseAdaptor<String, ViewHolder>
{
public mAdapter(List<String> list)
{
super(list);
}
/**
* 新建一个ViewHoler
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = View.inflate(parent.getContext(), R.layout.item, null);
ViewHolder holder = new ViewHolder(view);
return holder;
}
/**
* ViewHoler与数据绑定
*/
@Override
public void onBindViewHolder(ViewHolder holder, String data, int position)
{
holder.content.setText(data);
}
}
二、自己写一个ViewHoler并继承上面的类的BaseAdapter.Holder
class ViewHolder extends BaseAdaptor.Holder
{
TextView content;
public ViewHolder(View view)
{
super(view);
content = (TextView) view.findViewById(R.id.content);
}
}
三、使用
public class MainActivity extends Activity
{
ListView listview;
List<String> list = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listview);
// ----初始化一些模拟数据---------------
for (int i = 0; i < 100; i++)
list.add(i+"");
// ------------------
listview.setAdapter(new mAdapter(list));
}
}
看看效果图