我与Android美团主菜单有个约定<->

相信大家对于菜单应该不陌生了吧,有上下文菜单,自定义菜单,而我今天讲的是自定义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有的不够该如何处理,另外就是处理圆点的是否选中等。布局文件我就不贴了需要的加群扫码,另外转载请注明出处!谢谢!
这里写图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值