博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义ViewGroup,实现Android的侧滑菜单
阅读量:6411 次
发布时间:2019-06-23

本文共 6544 字,大约阅读时间需要 21 分钟。

之前写过一片文章是关于使用Android的DrawerLayout来实现侧滑菜单的——。

本文直接使用自定义的ViewGroup来实现Android侧滑菜单。

用到的技术: 1、Android自定义控件; 2、Android 的事件拦截onInterceptTouchEvent和触摸事件onTouchEvent处理。 3、Scroller的使用。

效果图:

不多说,马上上代码,自定义的MyViewGroup:

public class MyViewGroup extends ViewGroup {    private int mMostRecentX; // 最新的x轴偏移量    private final int MENU_SCREEN = 0; // 菜单界面    private final int MAIN_SCREEN = 1; // 主界面    private int currentScreen = MAIN_SCREEN; // 当前屏幕, 默认为: 主界面    private Scroller mScroller; // 模拟数据对象    public MyViewGroup(Context context, AttributeSet attrs) {        super(context, attrs);        mScroller = new Scroller(context);    }    /**     * 此方法是SlideMenu控件测量宽和高时回调.     * widthMeasureSpec 宽度测量规格: 整个屏幕的宽     * heightMeasureSpec 高度测量规格: 整个屏幕的高     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        // 测量菜单的宽和高        View menuView = getChildAt(0);        menuView.measure(menuView.getLayoutParams().width, heightMeasureSpec);        // 测量主界面的宽和高        View mainView = getChildAt(1);        // 主界面的宽度是整个屏幕的宽.        mainView.measure(widthMeasureSpec, heightMeasureSpec);    }    /**     * 布置SlideMenu中包含的子控件的位置.     * left = 0;     * top = 0;     * right = 整个屏幕的宽度;     * bottom = 整个屏幕的高度;     */    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        // 布置菜单界面的位置: left=-菜单的宽度, top=0, right=0, bottom=整个屏幕的高度        View menuView = getChildAt(0);        menuView.layout(-menuView.getMeasuredWidth(), 0, 0, b);        // 布置主界面的位置: left=0, top=0, right=整个屏幕的宽度, bottom=整个屏幕的高度;        View mainView = getChildAt(1);        mainView.layout(l, t, r, b);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                mMostRecentX = (int) event.getX();                break;            case MotionEvent.ACTION_MOVE:                int moveX = (int) event.getX();                // 1. 计算差值: mMostRecentX - moveX = 48 - 42 = 6;                int diff = mMostRecentX - moveX;                // 2. 限定左右边界                int currentX = getScrollX() + diff;                if(currentX < -getChildAt(0).getMeasuredWidth()) {                    // 超出了左边界, 已经移动超过-240                    scrollTo(-getChildAt(0).getMeasuredWidth(), 0);                } else if(currentX > 0) {                    scrollTo(0, 0);                } else {                    // 3. 根据差值, 使用scrollBy方法移动屏幕. scrollBy(6, 0);                    scrollBy(diff, 0);                }                // 4. 需要把mMostRecentX重新赋值, 赋值为moveX.    mMostRecentX = 48;                mMostRecentX = moveX;                break;            case MotionEvent.ACTION_UP:                // 取出当前x轴的偏移量                int scrollX = getScrollX();                if(scrollX > (-getChildAt(0).getMeasuredWidth() / 2)) {                    // 当前应该切换到主界面                    currentScreen = MAIN_SCREEN;                } else {                    // 当前应该切换到菜单界面                    currentScreen = MENU_SCREEN;                }                switchScreen();                break;            default:                break;        }        return true; // 完全自己处理事件    }    /**     * 根据currentScreen来切换屏幕显示的界面     */    private void switchScreen() {        int startX = getScrollX();        int dx = 0;        if(currentScreen == MAIN_SCREEN) {            // 切换到主界面//			scrollTo(0, 0);            // 算法: 目地的值 - startX            dx = 0 - startX;        } else if(currentScreen == MENU_SCREEN) {//			scrollTo(-getChildAt(0).getMeasuredWidth(), 0);            dx = -getChildAt(0).getMeasuredWidth() - startX;        }        // 开始模拟数据了, 只模拟数据        mScroller.startScroll(startX, 0, dx, 0, Math.abs(dx) * 2);        // 重绘刷新.        invalidate(); // invalidate -> drawChild -> child.draw -> computeScroll    }    @Override    public void computeScroll() {        // 更新scrollX或者scrollY的值.        if(mScroller.computeScrollOffset()) {            // 当前正在模拟数据, 取出x轴模拟的值, 设置给scrollTo方法.            int currX = mScroller.getCurrX();//			System.out.println("currX: " + currX);            scrollTo(currX, 0);            invalidate(); // 递归        }    }    /**     * 是否显示菜单     * @return     */    public boolean isShowMenu() {        return currentScreen == MENU_SCREEN;    }    /**     * 隐藏菜单     */    public void hideMenu() {        currentScreen = MAIN_SCREEN;        switchScreen();    }    /**     * 显示菜单     */    public void showMenu() {        currentScreen = MENU_SCREEN;        switchScreen();    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {            case MotionEvent.ACTION_DOWN:                mMostRecentX = (int) ev.getX();                break;            case MotionEvent.ACTION_MOVE:                int moveX = (int) ev.getX();                // 如果移动的偏移量的距离超过了10                int diff = moveX - mMostRecentX;                if(Math.abs(diff) > 10) {//				System.out.println("横着滑动了");                    return true;                }                break;            default:                break;        }        return super.onInterceptTouchEvent(ev);    }}复制代码

希望读者可以认真的看下注释,注释已经标注得很明白了。

使用的时候,在xml中使用,需要布局侧滑菜单栏和主界面

activity_custom_view_group:

复制代码

slidemenu_menu.xml:

复制代码

slidemenu_main.xml

复制代码

Activity:

public class CustomViewGroupActivity extends AppCompatActivity implements View.OnClickListener {    private MyViewGroup myViewGroup;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_custom_view_group);        findViewById(R.id.ib_slidemenu_main_back).setOnClickListener(this);        myViewGroup = (MyViewGroup) findViewById(R.id.slidemenu);    }    @Override    public void onClick(View v) {        // 切换当前屏幕显示的状态        if(myViewGroup.isShowMenu()) {            // 显示菜单, 切换到主界面            myViewGroup.hideMenu();        } else {            // 显示主界面, 切换到菜单            myViewGroup.showMenu();        }    }    public void clickTab(View v) {        TextView tv = (TextView) v;        Toast.makeText(this, tv.getText(), Toast.LENGTH_SHORT).show();    }}复制代码

这就是自定义ViewGroup实现Android的侧滑菜单以及使用,希望大家喜欢!!!

转载地址:http://ikkra.baihongyu.com/

你可能感兴趣的文章
centos7 设置开机启动服务
查看>>
【Java基础】序列化与反序列化深入分析
查看>>
浏览器跨域问题(jsonp)——jsonp详解
查看>>
Spring 注解总结
查看>>
4K加速普及,8K近在咫尺,下一个是?
查看>>
Application security
查看>>
主键生成策略
查看>>
django admin中保存添加的数据提示need string or buffer, int found
查看>>
Autofac.Integration.Mvc分析
查看>>
[Spring框架]Spring开发实例: XML+注解.
查看>>
java.lang.NoClassDefFoundError: javax/transaction/Synchronization
查看>>
黑客与画家——读后感
查看>>
实参时丢弃了类型 discards qualifiers discards qualifiers问题
查看>>
bzoj-2115 Xor
查看>>
gridcontrol复选框功能实现(超具体)
查看>>
Java面试题集(二)
查看>>
C#使用UUID生成ID
查看>>
图像处理就在身边
查看>>
Java-Maven(八):IDEA使用本地maven,并配置远程中央仓库
查看>>
ftp主动模式与被动模式交互过程分析
查看>>