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