自定义侧滑菜单

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义侧滑菜单相关的知识,希望对你有一定的参考价值。

类似于QQ侧滑菜单的效果,这个最重要的就是改变摆放方式,从而达到自己想要的效果,首先先弄明白onLayout方法里的参数

技术分享

这个自定义里最主要的就是通过touch事件来移动显示的范围,移动viewgroup主要有几个方法,onLayout

offsetTopAndBottom(offset)和offsetLeftAndRight(offset);
scrollTo和scrollBy方法;
注意:滚动的并不是viewgroup内容本身,而是它的矩形边框
它是瞬间移动,

这里我们用的是scrollTo。

开始上代码:侧滑菜单布局

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:background="@drawable/menu_bg"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_news"
            android:text="新闻" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_read"
            android:text="订阅" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_ties"
            android:text="跟帖" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_pics"
            android:text="图片" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_ugc"
            android:text="话题" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_pics"
            android:text="图片" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_vote"
            android:text="投票" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_vote"
            android:text="投票" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_vote"
            android:text="投票" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_vote"
            android:text="投票" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_vote"
            android:text="投票" />

        <TextView
            style="@style/TabMenu"
            android:drawableLeft="@drawable/tab_vote"
            android:text="投票" />
    </LinearLayout>

</ScrollView>

主布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#D3D3D3"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@drawable/top_bar_bg"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/img"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:src="@drawable/main_back" />

        <TextView
            style="@style/TabMenu"
            android:text="新闻主页" />
    </LinearLayout>

</LinearLayout>

父布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.slidemenu.MainActivity" >

    <com.example.slidemenu.view.SlideMenu
        android:id="@+id/slide"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <!--侧滑菜单-->
        <include layout="@layout/menu_layout"/>
        
        <!--主布局-->
        <include layout="@layout/main_layout"/>
    </com.example.slidemenu.view.SlideMenu>

</RelativeLayout>

代码

package com.example.slidemenu.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

public class SlideMenu extends RelativeLayout{
    private View menuView;
    private View mainView;

    public SlideMenu(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public SlideMenu(Context context) {
        super(context);
        init();
    }

    private void init() {
        // TODO Auto-generated method stub

    }

    /**
     * 完成一级布局的加载,在这里进行布局的初始化
     */
    @Override
    protected void onFinishInflate() {

        menuView = getChildAt(0);

        mainView = getChildAt(1);
    }

    /**
     * 参数是xml里定义的,都是match_parent,一般自定义viewGroup都不会重写此方法,继承已经有的layout就可以了
     */
//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        // TODO Auto-generated method stub
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        // 侧滑菜单的测量,所有参数封装在LayoutParams里
//        System.out.println(menuView.getLayoutParams().width+">>>>>>>>>");
//        menuView.measure(menuView.getLayoutParams().width, heightMeasureSpec);
//        // 主界面的测量
//        mainView.measure(widthMeasureSpec, heightMeasureSpec);
//    }

    @Override
    protected void onLayout(boolean arg0, int l, int t, int r, int b) {
        // 进行放置,菜单布局在屏幕的左侧
        menuView.layout(-menuView.getLayoutParams().width, 0, 0, b);
        mainView.layout(l, t, r, b);

    }

    private int downX = 0;
    private int newScrollX=0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downX = (int) event.getX();
            break;
        case MotionEvent.ACTION_MOVE:
            int moveX = (int) event.getX();
            // 移动距离
            int detalX = (int) moveX - downX;
            newScrollX = getScrollX() - detalX;
            System.out.println(newScrollX + "-----------");
            if (newScrollX < -menuView.getLayoutParams().width) {
                newScrollX = -menuView.getLayoutParams().width;
            }
            if (newScrollX > 0) {
                newScrollX = 0;
            }
            // 并不是内容移动,而是这个窗口在移动,所以这个内容相对窗体来说是相反的方向
            scrollTo(newScrollX, 0);
            downX = moveX;
            break;
        case MotionEvent.ACTION_UP:
            if (newScrollX < -menuView.getLayoutParams().width/2) {
                newScrollX = -menuView.getLayoutParams().width;
            }
            if (newScrollX > -menuView.getLayoutParams().width/2) {
                newScrollX = 0;
            }
            scrollTo(newScrollX, 0);
            break;
        }
        return true;
    }
    /**
     * 打开菜单方法
     */
    public void open(){
        scrollTo(-menuView.getLayoutParams().width, 0);
    }
}

 

以上是关于自定义侧滑菜单的主要内容,如果未能解决你的问题,请参考以下文章

Android自定义View之仿QQ侧滑菜单实现

android自定义ViewGroup(侧滑菜单)

自定义侧滑菜单

Android高仿网易新闻客户端之侧滑菜单

Android自定义ListView实现侧滑子菜单

HarmonyOS ArkUI之自定义组件侧滑菜单(JS)