相信大家对于菜单应该不陌生了吧,有上下文菜单,自定义菜单,而我今天讲的是自定义GridView+ViewPager实现仿美团菜单效果下面废话不多说直接上效果图,别闭眼哈哈!
接下讲一些思路以及一些细节处理
- GridView分页处理
- 具体步骤和实现
GridView分页处理你每页显示的多少个GridView item以及当前页数,还有总页数,可能有些不能取整因此需要做一些简单算法处理具体代码实现如下
//总的页数=总数/每页数量,并取整
pageCount = (int) Math.ceil(mLists.size() * 1.0 / pageSize);
mPagerList = new ArrayList<View>();
for (int i = 0; i < pageCount; i++) {
//每个页面都是inflate出一个新实例
GridView gridView = (GridView) minflater.inflate(R.layout.gridview, mViewPager, false);
gridView.setAdapter(new GridViewAdapter(GridViewActivity.this, mLists, i, pageSize));
mPagerList.add(gridView);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int pos = position + curIndex * pageSize;
Toast.makeText(GridViewActivity.this, mLists.get(pos).getName(), Toast.LENGTH_SHORT).show();
}
});
}
//设置适配器
mViewPager.setAdapter(new ViewPageAdapter(mPagerList));
//设置圆点
setOvalLayout();
}
具体步骤包括以下几步
1、首先创建一个主GridViewActivity 里面主要包括GridView显示的标题以及ImageView显示的图片资源然后实现下面的小点左右滑动切换位置销毁之前的View
2、创建一个GridViewAdapter里面包括当前显示的页数以及每页现实的PageSize大小,然后将存放的数据通过ImageView和TextView显示出来显示在GridView中然后将它与BViewPager关联
3、创建一个MeiTuan bean实体类 里面包括显示的标题名称以及图片资源生成对应的get/set方法或者构造方法等
4、最后通过在主Activity调用相应的方法实现最终的效果
主Activity初始化代码如下
private void initView() {
// 初始化UI组件
mViewPager = (ViewPager) findViewById(R.id.vp);
mLlDot = (LinearLayout) findViewById(R.id.ll_dot);
}
加载数据代码如下
/**
* 初始化数据源
*/
private void initDatas() {
mLists = new ArrayList<MeiTuan>();
for (int i = 0; i < titles.length; i++) {
//动态获取资源ID,第一个参数是资源名,第二个参数是资源类型例如drawable,mipmap string等,第三个参数包名
int imageId = getResources().getIdentifier("ic_category_" + i, "drawable", getPackageName());
/**需要注意的是我这里用的是IDE所以是res目录下的drawable否则会报错如果你用的是idea就是mipmap**/
mLists.add(new MeiTuan(titles[i], imageId));
}
}
显示标题数组具体代码如下
private String[] titles = {"美食", "电影", "酒店住宿", "休闲娱乐", "外卖", "自助餐", "KTV", "机票/火车票", "周边游", "美甲美睫",
"火锅", "生日蛋糕", "甜品饮品", "水上乐园", "汽车服务", "美发", "丽人", "景点", "足疗按摩", "运动健身", "健身", "超市", "买菜",
"今日新单", "小吃快餐", "面膜", "洗浴/汗蒸", "母婴亲子", "生活服务", "婚纱摄影", "学习培训", "家装", "结婚", "全部分类"};
设置圆点是否选中具体实现如下
/**
* 设置圆点
*/
public void setOvalLayout() {
/**遍历所有的GridView显示的总页数**/
for (int i = 0; i < pageCount; i++) {
mLlDot.addView(minflater.inflate(R.layout.dot, null));
}
// 默认显示第一页
// mPager.setCurrentItem(0);
// mLlDot.getChildAt(0).setEnabled(true);
mLlDot.getChildAt(0).findViewById(R.id.v_dot)
.setBackgroundResource(R.drawable.dot_selected);
/**添加一个onPageChangeListener**/
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageSelected(int position) {
// 取消圆点选中
mLlDot.getChildAt(curIndex)
.findViewById(R.id.v_dot)
.setBackgroundResource(R.drawable.dot_normal);
// 圆点选中
mLlDot.getChildAt(position)
.findViewById(R.id.v_dot)
.setBackgroundResource(R.drawable.dot_selected);
curIndex = position;
}
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
public void onPageScrollStateChanged(int arg0) {
}
});
}
接下来是GridViewAdapter适配器实现
public class GridViewAdapter extends BaseAdapter {
/**用来存放list集合**/
private List<MeiTuan> mList;
/**上下文对象**/
private Context mContext;
/**布局文件**/
private LayoutInflater mLayoutInflater;
/**当前页**/
private int curIndex;
/**每页大小**/
private int pageSize;
public GridViewAdapter(Context mContext,List<MeiTuan> mList,int curIndex,int pageSize) {
//初始化
mLayoutInflater=LayoutInflater.from(mContext);
this.mList=mList;
this.mContext=mContext;
this.curIndex=curIndex;
this.pageSize=pageSize;
}
@Override
public int getCount() {
//当前item条目
return mList.size()>(curIndex+1)*pageSize?pageSize:(mList.size()-curIndex*pageSize);
}
@Override
public Object getItem(int position) {
// 当前item的position+curIndex*pageSize
return mList.get(position+curIndex*pageSize);
}
@Override
public long getItemId(int position) {
return position+curIndex*pageSize;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
/**判断是否为空
* 是 创建一个ViewHolder对象
* 否则返回
* **/
if(convertView==null){
/**加载布局文件**/
convertView=mLayoutInflater.inflate(R.layout.item_gridview, null);
holder=new ViewHolder();
holder.iv_iconRes=(ImageView) convertView.findViewById(R.id.imageView);
holder.tv_name=(TextView) convertView.findViewById(R.id.textView);
/**设置一个Tag标记**/
convertView.setTag(holder);
}else{
/**获取一个Tag标记**/
holder=(ViewHolder) convertView.getTag();
}
/**获取当前位置**/
int pos=position+curIndex*pageSize;
// String name=mList.get(position).getName();
// int iconRes=mList.get(position).getIconRes();
/**将对应的图片显示在ImageView中**/ holder.iv_iconRes.setImageResource(mList.get(pos).getIconRes());
/**将标题显示的TextView中**/ holder.tv_name.setText(mList.get(pos).getName());
return convertView;
}
/**创建一个ViewHolder对象**/
static class ViewHolder{
TextView tv_name;
ImageView iv_iconRes;
}
}
到这里可能用的人会问哪里的图片标题要不要创建一个实体类,这个问题问的好,那继续?MeiTuan实体类代码
public class MeiTuan {
/**显示标题**/
private String name;
/**显示图片资源**/
private int iconRes;
public String getName() {
return name;
}
public MeiTuan(String name, int iconRes) {
this.name = name;
this.iconRes = iconRes;
}
public void setName(String name) {
this.name = name;
}
public int getIconRes() {
return iconRes;
}
public void setIconRes(int iconRes) {
this.iconRes = iconRes;
}
}
到这里差不多了,但是还要创建一个
ViewPageAdapter用来切换不同的GridView视图随着小圆点的移动位置不同代码如下我就不再赘述
public class ViewPageAdapter extends PagerAdapter{
private List<View> mList;
public ViewPageAdapter(List<View> mList) {
this.mList=mList;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// 销毁之前的view
container.removeView(mList.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// 添加view
container.addView(mList.get(position));
return mList.get(position);
}
@Override
public int getCount() {
/**判断list集合是否为空**/
if(mList==null){
return 0;
}
return mList.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0==arg1;
}
}
最后就是GridViewActivity全部代码
public class GridViewActivity extends Activity {
private static final String TAG="GridViewActivity";
private String[] titles = {"美食", "电影", "酒店住宿", "休闲娱乐", "外卖", "自助餐", "KTV", "机票/火车票", "周边游", "美甲美睫",
"火锅", "生日蛋糕", "甜品饮品", "水上乐园", "汽车服务", "美发", "丽人", "景点", "足疗按摩", "运动健身", "健身", "超市", "买菜",
"今日新单", "小吃快餐", "面膜", "洗浴/汗蒸", "母婴亲子", "生活服务", "婚纱摄影", "学习培训", "家装", "结婚", "全部分类"};
private ViewPager mViewPager;
private List<View> mPagerList;
private List<MeiTuan> mLists;
private LinearLayout mLlDot;
private LayoutInflater minflater;
/**
* 总的页数
*/
private int pageCount;
/**
* 每一页显示的个数
*/
private int pageSize = 10;
/**
* 当前显示的是第几页
*/
private int curIndex = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initView();
//初始化数据源
initDatas();
minflater = LayoutInflater.from(this);
//总的页数=总数/每页数量,并取整
pageCount = (int) Math.ceil(mLists.size() * 1.0 / pageSize);
mPagerList = new ArrayList<View>();
for (int i = 0; i < pageCount; i++) {
//每个页面都是inflate出一个新实例
GridView gridView = (GridView) minflater.inflate(R.layout.gridview, mViewPager, false);
gridView.setAdapter(new GridViewAdapter(GridViewActivity.this, mLists, i, pageSize));
mPagerList.add(gridView);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int pos = position + curIndex * pageSize;
Toast.makeText(GridViewActivity.this, mLists.get(pos).getName(), Toast.LENGTH_SHORT).show();
}
});
}
//设置适配器
mViewPager.setAdapter(new ViewPageAdapter(mPagerList));
//设置圆点
setOvalLayout();
}
private void initView() {
// 初始化UI组件
mViewPager = (ViewPager) findViewById(R.id.vp);
mLlDot = (LinearLayout) findViewById(R.id.ll_dot);
}
/**
* 初始化数据源
*/
private void initDatas() {
mLists = new ArrayList<MeiTuan>();
for (int i = 0; i < titles.length; i++) {
//动态获取资源ID,第一个参数是资源名,第二个参数是资源类型例如drawable,min_mapstring等,第三个参数包名
int imageId = getResources().getIdentifier("ic_category_" + i, "drawable", getPackageName());
mLists.add(new MeiTuan(titles[i], imageId));
}
}
/**
* 设置圆点
*/
public void setOvalLayout() {
for (int i = 0; i < pageCount; i++) {
mLlDot.addView(minflater.inflate(R.layout.dot, null));
}
// 默认显示第一页
// mPager.setCurrentItem(0);
// mLlDot.getChildAt(0).setEnabled(true);
mLlDot.getChildAt(0).findViewById(R.id.v_dot)
.setBackgroundResource(R.drawable.dot_selected);
/**添加一个onPageChangeListener左右滑动切换监听事件**/
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageSelected(int position) {
// 取消圆点选中
mLlDot.getChildAt(curIndex)
.findViewById(R.id.v_dot)
.setBackgroundResource(R.drawable.dot_normal);
// 圆点选中
mLlDot.getChildAt(position)
.findViewById(R.id.v_dot)
.setBackgroundResource(R.drawable.dot_selected);
curIndex = position;
}
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
public void onPageScrollStateChanged(int arg0) {
}
});
}
}
到这里是不是感觉不是很难,需要注意点是如何分页显示而且规定每页显示的pageSize有的不够该如何处理,另外就是处理圆点的是否选中等。布局文件我就不贴了需要的加群扫码,另外转载请注明出处!谢谢!