用ListView实现GridView的效果

时间:2020-12-08 19:35:30

很多时候我们需要实现每列多项数据的ListView时,可以使用GridView,但GridView不能设置HeadView还不能很灵活,这时我们还是倾向使用ListView,当然RecyleView是更好的选择。用ListView实现GridView效果,最直接的是在布局里面就写多份,两列时还可以接受,如果三列四列就太难看了。我分享一种ListView的写法,用ListView实现GridView更方便。


@Override
public View getView(int position, View convertView, ViewGroup parent) {
List<ViewHolder> holderList;
if (convertView == null) {

LinearLayout linearLayout = new LinearLayout(mContext);

convertView = linearLayout;

linearLayout.setOrientation(LinearLayout.HORIZONTAL);

int width = DensityUtil.getScreenWidth(mContext);

int horizonDivide = DensityUtil.dip2px(mContext, 8);
// 行数
int itemWidth = (width - (columnNum+1) * horizonDivide) / columnNum;

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
itemWidth, -2);

LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(
horizonDivide, -1);

holderList = new ArrayList<HomeAppListAdapter.ViewHolder>();

for (int i = 0; i < columnNum; i++) {
ViewHolder holder = new ViewHolder();

if (i < columnNum ) {
View hDivide = new View(mContext);
hDivide.setBackgroundColor(mContext.getResources()
.getColor(R.color.gray_f4));
linearLayout.addView(hDivide, params2);
}

View view = infl.inflate(R.layout.item_block_app, parent, false);
holder.initView(view);
holderList.add(holder);
linearLayout.addView(view, params);

if (i == columnNum-1 ) {
View hDivide = new View(mContext);
hDivide.setBackgroundColor(mContext.getResources()
.getColor(R.color.gray_f4));
linearLayout.addView(hDivide, params2);
}


}
convertView.setTag(holderList);
} else {
holderList = (List<ViewHolder>) convertView.getTag();
}

for (int i = 0; i < columnNum && columnNum * position + i < data.size(); i++) {
final int pos = columnNum * position + i;
ViewHolder holder = holderList.get(i);
final AppInfo app = data.get(pos);
holder.bindView(app);

holder.view.setOnClickListener(itemOnClickListener);
holder.view.setTag(app);

}

return convertView;
}

protected OnClickListener itemOnClickListener=new OnClickListener(){
@Override
public void onClick(View v) {
AppInfo app=(AppInfo) v.getTag();
if (app != null) {
StatiseControler.getInstance(mContext)
.stRecommendListClick(app.getPackageName());
AppDetailFragment.showAppDetail(mContext, app);
}
}

};

一般的ContentView setTag()都是设置的ViewHolder,这里设置的是List<ViewHolder>,new ContentView时,也不是直接inflate 一个布局了,而是用一个LinearLayout根据列数inflate多个,添加进去。ContentView不为空时,也需要遍历下列数在里面操作啦。

这里要注意的一个是这样就不能设置ListView 的onItemClick了,只能在为每一个Item设置Listener了,但为每一个都设一个Listener太占资源了,可以用一个Listener,数据存在view的tag里面,这样就只需要new 一个Listener了。