为什么不直接使用GridView?
由于GridView很难实现下拉刷新功能,开源的pullToRefresh 是通过基于listView实现的。为了既要有下拉刷新功能,又要达到GridView(一行可以显示多列)效果,于是就产生了extends BaseAdapter自定义实现一个ListAsGridBaseAdapter 的想法。
注:本人代码实现参考自公司项目代码,亲手编写,如有雷同,纯属巧合。
代码
ListAsGridBaseAdapter.java
package com.qunar.yuzhiyun.listviewasgridview;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
/**
* ListAsGridBaseAdapter使得listView 实现gridView的效果
* 由于下拉刷新控件pullToRefresh基于listView实现,在gridView中很难实现下拉刷新下
* 为了下拉刷新功能,于是退一步采用这种方法来达到目的
* Created by yuzhiyun on 17/8/9.
*/
public abstract class ListAsGridBaseAdapter extends BaseAdapter {
//每一行有多少列
private int numColumns = 1;
private Context context;
public ListAsGridBaseAdapter( Context context) {
this.context = context;
}
public int getNumColumns() {
return numColumns;
}
public void setNumColumns(int numColumns) {
this.numColumns = numColumns;
}
@Override
public int getCount() {
//item数量不一定是numColumns的倍数,最后一行可能没占满
return (int) Math.ceil(getItemCount() * 1f / getNumColumns());
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
Log.i("msg","getView();");
//由于我们目的是实现gridView的效果,所以每一行的视图都可以用横向的LinearLayout布局来实现
LinearLayout linearLayout;
int columnWidth = 0;
if(viewGroup!=null)
columnWidth=viewGroup.getWidth()/numColumns;
if(null==view)
//未复用view的时候
linearLayout=createItemRowView(i,columnWidth,viewGroup);
else {
//复用view的时候
linearLayout = (LinearLayout) view;
//复用view之后,要更新数据
updateItemRowView(i,viewGroup,linearLayout);
}
return linearLayout;
}
/**
* 复用listView的item的时候
* 更新一行视图对应的数据
* @param position
* @param viewGroup
* @param linearLayout
*/
private void updateItemRowView(int position, ViewGroup viewGroup, LinearLayout linearLayout) {
for(int i=0;i<numColumns;i++){
int realposition=numColumns*position+i;
if(realposition<getItemCount()) {
View realItem=linearLayout.getChildAt(i);
//注意这里getItemView第二个参数传递的不是null,而是已经有了的realItem
getItemView(realposition,realItem,viewGroup);
}else
break;
}
}
/**
* 创建一行视图
* @param position
* @param columnWidth
* @param viewGroup
* @return
*/
LinearLayout createItemRowView(int position, int columnWidth, ViewGroup viewGroup){
LinearLayout linearLayout=new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
for(int i=0;i<numColumns;i++){
int realposition=numColumns*position+i;
if(realposition<getItemCount()){
View realItem;
//未复用listView的item,所以这里传递的第二个参数为null
realItem=getItemView(realposition,null,viewGroup);
//设置一行中每一小块的宽度
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.width=columnWidth;
realItem.setLayoutParams(params);
linearLayout.addView(realItem);
}else
break;
}
return linearLayout;
}
/**
* 用于在子类中获取总item数量
* @return
*/
public abstract int getItemCount();
/**
* 用于在子类中获取每个item的视图
* @param i
* @param view
* @param viewGroup
* @return
*/
public abstract View getItemView(int i, View view, ViewGroup viewGroup);
}
那么如何使用这个adapter呢?看代码吧,把ListAsGridBaseAdapter当作BaseAdapter一样使用就行了
GirlsAdapter.java
public class GirlsAdapter extends ListAsGridBaseAdapter {
private List<Girl> girlList = new ArrayList<Girl>();
private Context context;
public GirlsAdapter(Context context, List<Girl> girlList) {
super(context);
this.girlList = girlList;
this.context = context;
}
@Override
public int getItemCount() {
return girlList.size();
}
@Override
public Object getItem(int i) {
return girlList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getItemView(int i, View convertView, ViewGroup viewGroup) {
Log.i("msg","getItemView();");
Girl item = girlList.get(i);
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.girl, null);
viewHolder = new ViewHolder();
viewHolder.imgAvatar = (ImageView) convertView.findViewById(R.id.img_avatar);
viewHolder.tvName = (TextView) convertView.findViewById(R.id.tv_name);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.imgAvatar.setImageResource(item.getImgResourceId());
viewHolder.tvName.setText(item.getName());
return convertView;
}
private class ViewHolder {
ImageView imgAvatar;
TextView tvName;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
ListView listView;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context=this;
listView= (ListView) findViewById(R.id.listview);
initListView();
}
private void initListView() {
List<Girl> girlList=new ArrayList<>();
girlList.add(new Girl("小1",R.drawable.girl1));
girlList.add(new Girl("小2",R.drawable.girl2));
girlList.add(new Girl("小3",R.drawable.girl3));
girlList.add(new Girl("小4",R.drawable.girl4));
girlList.add(new Girl("小5",R.drawable.girl5));
GirlsAdapter adapter=new GirlsAdapter(context,girlList);
adapter.setNumColumns(2);
listView.setAdapter(adapter);
}
}