ListView实现GridView的效果

为什么不直接使用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);
    }


}

效果图

这里写图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页