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);
    }


}

效果圖

這裏寫圖片描述

發佈了176 篇原創文章 · 獲贊 28 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章