周末啦!闲来无事就写写吧,要实现的效果大概如下图:
这个效果,美团里是存在的,ViewPager可以滚动,每页里面又是GridView填充的网格数据。假如,项目中没有特殊要求,这部分数据是死的,那在xml里直接布局图片和文字写死就可以了,但是,如果这部分数据是动态获取的呢?首先,不确定后台会返回几条,既然不知道返回了几条,那么就不知道ViewPager该用几页来装载数据。虽然我做过的项目中都还没遇到过这种需求,但是学习一下也是有必要的,万一以后遇到了呢?我也是看了网上的文章才明白的,下面我就放出核心代码。
声明初始化:
private ViewPager mViewPager;
private List<View> mViewPagerGridList;//GridView的集合
private LinearLayout ll_point;//装载小圆点的布局
private List<ImageView> pointsList = new ArrayList<>();//小圆点集合
mViewPager = view.findViewById(R.id.id_vp);//为啥是view.find...因为我这个效果是在Dialog里
ll_point = view.findViewById(R.id.ll_point);
mViewPagerGridList = new ArrayList<>();
getGridData();//去后台获取数据解析
填充数据,从后台获取数据解析成一个mDatas集合,然后
pageCount = (int) Math.ceil(mDatas.size() * 1.0 / 8);//根据返回的数量先算出需要几页去装载
pointsList.clear();//因为我这个效果是在弹窗里,所以每次弹出弹窗时先清空一下小圆点集合
for (int index = 0; index < pageCount; index++) {
GridView gridView = (GridView) getLayoutInflater().inflate(R.layout.gridview_layout, mViewPager, false);
gridView.setAdapter(new MiddleAdapter(HomeActivity.this, mDatas, index));
mViewPagerGridList.add(gridView);
ImageView imageView = new ImageView(HomeActivity.this);
if (index == 0) {
imageView.setBackgroundResource(R.drawable.point_focus);
} else {
imageView.setBackgroundResource(R.drawable.point_un_focus);
}
//设置小原点间距
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(20, 0, 0, 0);
pointsList.add(imageView);
ll_point.addView(imageView, params);
}
mViewPager.setAdapter(new MyViewPagerAdapter(mViewPagerGridList));
layout.gridview_layout的布局:
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="4"/>
适配器:一共2个,一个是给ViewPager用的,一个是给gridView用的
gridView用的:
public class MiddleAdapter extends BaseAdapter {
private List<MiddleMianBanBean.DataBean> mDatas;
private Context context;
private int mIndex;//下标
private int mPageSize = 8;//每页显示最大条目数
public MiddleAdapter(Context context, List<MiddleMianBanBean.DataBean> mDatas, int index) {
this.context = context;
this.mDatas = mDatas;
this.mIndex = index;
}
@Override
public int getCount() {
return mDatas.size() > (mIndex + 1) * mPageSize ? mPageSize : (mDatas.size() - mIndex * mPageSize);
}
@Override
public Object getItem(int position) {
return mDatas.get(position + mIndex * mPageSize);
}
@Override
public long getItemId(int position) {
return position + mIndex * mPageSize;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder vh = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.girdview_item, parent, false);
vh = new ViewHolder();
vh.tv = (TextView) convertView.findViewById(R.id.id_tv_title);
vh.iv = (CircleImageView) convertView.findViewById(R.id.id_iv_icon);
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
/**
* 在给View绑定显示的数据时,计算正确的position = position + mIndex * mPageSize,
*/
int pos = position + mIndex * mPageSize;
vh.tv.setText(mDatas.get(pos).getName());
Picasso.with(context).load(mDatas.get(pos).getImg()).into(vh.iv);
//点击事件
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
return convertView;
}
class ViewHolder {
public TextView tv;
public CircleImageView iv;
}
}
在里面引进girdview_item控制图片和文字属性。
ViewPager用的:
public class MyViewPagerAdapter extends PagerAdapter {
private List<View> mViewList;
public MyViewPagerAdapter(List<View> mViewList) {
this.mViewList = mViewList;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mViewList.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mViewList.get(position));
return (mViewList.get(position));
}
@Override
public int getCount() {
if (mViewList == null)
return 0;
return mViewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
最后,监听ViewPager滚动来改变小圆点
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
for (int i = 0; i < pointsList.size(); i++) {
if (position == i) {
pointsList.get(i).setBackgroundResource(R.drawable.point_focus);
} else {
pointsList.get(i).setBackgroundResource(R.drawable.point_un_focus);
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});