Android 实现类似美团的菜单效果

参考 :http://blog.csdn.net/qq_20785431/article/details/52528404

这里写图片描述

滑动后
这里写图片描述

每次滑动都会显示不同的菜单,下面介绍下如何实现这个效果

实现原理:

将GridView通过Adapter设置给Viewpager,使用Viewpager滑动时动态进行选择相应的GridView,每个GridView数据源有所不同.

MainActivity代码如下:


public class MainActivity extends AppCompatActivity {

    private static final String TAG = "LOGGER";
    private ViewPager mVpContainer;
    private LinearLayout mLlDots;
    private GridView mGvGrid;
    private LayoutInflater mInflater;
    private static final int DEFAULT_PAGE_COUNT = 10;


    private String[] mTitles = {"美食", "电影", "酒店住宿", "休闲娱乐", "外卖", "自助餐", "KTV", "机票/火车票", "周边游", "美甲美睫",
            "火锅", "生日蛋糕", "甜品饮品", "水上乐园", "汽车服务", "美发", "丽人", "景点", "足疗按摩", "运动健身", "健身", "超市", "买菜",
            "今日新单", "小吃快餐", "面膜", "洗浴/汗蒸", "母婴亲子", "生活服务", "婚纱摄影", "学习培训", "家装", "结婚", "全部分配"};
    private List<MenuItem> mMenus = new ArrayList<>();
    private List<View> mViews = new ArrayList<>();
    private int mRemain;
    private int mPageCount;
    private int mCurpage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mInflater = LayoutInflater.from(this.getApplicationContext());
        mVpContainer = (ViewPager) findViewById(R.id.id_vp_container);
        mLlDots = (LinearLayout) findViewById(R.id.id_ll_dots);

        // 动态创建GridView
        mRemain = mTitles.length % DEFAULT_PAGE_COUNT;
        mPageCount = mTitles.length / DEFAULT_PAGE_COUNT;
        if (mRemain != 0) {
            ++mPageCount;
        }
        setupDatas();
        // 初始化多个GridView
        Log.d(TAG, "onCreate: pageCount " + mPageCount);
        for (int i = 0; i < mPageCount; i++) {
            mGvGrid = (GridView) mInflater.inflate(R.layout.view_grid, mVpContainer, false);
            mGvGrid.setAdapter(new GridViewAdapter(this, mMenus, i, i == mPageCount - 1 ? mRemain : DEFAULT_PAGE_COUNT));
            mViews.add(mGvGrid);
        }
        setupDots();


        /**
         * 设置ViewPager的Adapter
         */
        mVpContainer.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return mViews.size();
            }

            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }


            // 初始化每个View
            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                container.addView(mViews.get(position));
                return mViews.get(position);
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView(mViews.get(position));
            }
        });
    }


    private void setupDatas() {
        // 动态获取mipmapId
        for (int i = 0; i < mTitles.length; i++) {
            MenuItem item = new MenuItem();
            item.setTitle(mTitles[i]);
            item.setIconId(getResources().getIdentifier("ic_category_" + i, "mipmap", getPackageName()));
            mMenus.add(item);
        }
    }

    private void setupDots() {
        for (int i = 0; i < 4; i++) {
            mLlDots.addView(mInflater.inflate(R.layout.view_dots, null));
        }
        // 默认显示第一页
        mLlDots.getChildAt(0).setSelected(true);
        mVpContainer.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                // 取消原点选中
                mLlDots.getChildAt(mCurpage).setSelected(false);
                // 原点选中
                mLlDots.getChildAt(position).setSelected(true);
                mCurpage = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

}
对GridView的Adapter进行一下处理

/**
 * Created by shixi_tianrui1 on 16-10-16.
 * 在GridView内部设置要显示的菜单项
 */
public class GridViewAdapter extends BaseAdapter {

    private static final int DEFAULT_PAGE_COUNT = 10;
    private List<MenuItem> mMenus;
    private Context mContext;

    private int mCurPage;
    private int mPageSize;


    public GridViewAdapter(Context context, List<MenuItem> menus, int currentPage, int pageSize) {
        mMenus = menus;
        mContext = context;
        mCurPage = currentPage;
        mPageSize = pageSize;
    }

    @Override
    public int getCount() {
        return mPageSize;
    }

    @Override
    public Object getItem(int position) {
        return mMenus.get(position + DEFAULT_PAGE_COUNT * mCurPage);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(mContext).inflate(R.layout.item_menu, parent, false);
            viewHolder.mIvIcon = (ImageView) convertView.findViewById(R.id.id_item_icon);
            viewHolder.mTvTitle = (TextView) convertView.findViewById(R.id.id_item_title);
            convertView.setTag(viewHolder);
        }
        viewHolder = (ViewHolder) convertView.getTag();

        // 计算正确的position
        int pos = position + mCurPage * DEFAULT_PAGE_COUNT;
        viewHolder.mIvIcon.setImageResource(mMenus.get(pos).getIconId());
        viewHolder.mTvTitle.setText(mMenus.get(pos).getTitle());


        return convertView;
    }

    private static class ViewHolder {
        private TextView mTvTitle;
        private ImageView mIvIcon;
    }
}
对小原点的处理

设置一个pageChangeListener,监听ViewPager的滑动,每次滑动时,将对应位置的小圆点设置为选中

private void setupDots() {
        for (int i = 0; i < 4; i++) {
            mLlDots.addView(mInflater.inflate(R.layout.view_dots, null));
        }
        // 默认显示第一页
        mLlDots.getChildAt(0).setSelected(true);
        mVpContainer.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                // 取消原点选中
                mLlDots.getChildAt(mCurpage).setSelected(false);
                // 原点选中
                mLlDots.getChildAt(position).setSelected(true);
                mCurpage = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }
原点的样式
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true">
        <shape android:shape="oval">
            <solid android:color="@color/colorAccent" />
            <corners android:radius="8dp" />
        </shape>
    </item>
    <item android:state_selected="false">
        <shape android:shape="oval">
            <solid android:color="@color/colorPrimary" />
            <corners android:radius="8dp" />
        </shape>
    </item>
</selector>
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值