4-14-侧滑菜单继承HorizontalScrollView思路

继承HorizontalScrollView实现侧滑菜单 :主界面缩放动画

package com.example.zxtext.diyUi;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;

import com.example.zxtext.R;

import androidx.core.view.ViewCompat;

public class SlidingMenu extends HorizontalScrollView {
    private View mMenuView;//侧滑菜单布局
    private View mContentView;//主内容界面
    private int mMenuWidth;//菜单的宽度

    private boolean mMenuIsOpen = false;//菜单是否打开
    private GestureDetector mGestureDetector;//手势处理类,处理屏幕的手势动作

    public SlidingMenu(Context context) {
        this(context,null);
    }

    public SlidingMenu(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu);
        float rightPadding = array.getDimension(R.styleable.SlidingMenu_SlidingMenu_rightPadding,dip2px(50));
        // 计算菜单的宽度 = 屏幕的宽度 - 自定义右边留出的宽度
        mMenuWidth = (int) (getScreenWidth() - rightPadding);
        array.recycle();

        //实例化手势类
        mGestureDetector  = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                // 当手指快速滑动时候回调的方法
                // Log.e("TAG",velocityX+"");
                // 如果菜单打开 并且是向左快速滑动 切换菜单的状态
                if(mMenuIsOpen){
                    if(velocityX<-500){
                        toggleMenu();
                        return true;
                    }
                }else{
                    // 如果菜单关闭 并且是向右快速滑动 切换菜单的状态
                    if(velocityX>500){
                        toggleMenu();
                        return true;
                    }
                }
                return false;
            }
        });

    }

    private float dip2px(int dip) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dip,getResources().getDisplayMetrics());
    }

    /*而onFinishInflate方法是在setContentView之后、onMeasure之前
    * Activity中调用setContentView之后就会调用onFinishInflate这个方法,
    * 这个方法就代表自定义控件中的子控件映射完成了,然后可以进行一些初始化控件的操作
    * */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        // 1.获取根View也就是外层的LinearLayout
        ViewGroup container = (ViewGroup) this.getChildAt(0);

        int containerChildCount = container.getChildCount();
        if(containerChildCount>2){
            // 里面只允许放置两个布局  一个是Menu(菜单布局) 一个是Content(主页内容布局)
            throw new IllegalStateException("SlidingMenu 根布局LinearLayout下面只允许两个布局,菜单布局和主页内容布局");
        }
        // 2.获取菜单和内容布局
        mMenuView = container.getChildAt(0);
        mContentView = container.getChildAt(1);
        // 3.指定内容和菜单布局的宽度
        // 3.1 菜单的宽度 = 屏幕的宽度 - 自定义的右边留出的宽度
        mMenuView.getLayoutParams().width = mMenuWidth;
        // 3.2 内容的宽度 = 屏幕的宽度
        mContentView.getLayoutParams().width = getScreenWidth();
        //mMenuView.setVisibility(View.GONE);
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        // 布局指定后会从新摆放子布局,当其摆放完毕后,让菜单滚动到不可见状态
        if (changed) {
            scrollTo(mMenuWidth, 0);
        }
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        //mMenuView.setTranslationX(l*0.8f);
        float scale = (1f*l)/mMenuWidth;
        //右边的缩放:最小是0.7f,最大是1f
        float rightScale = (float) (0.7f + 0.3*scale);
        //设置缩放的原点和大小
        ViewCompat.setPivotX(mContentView,0);
        ViewCompat.setPivotY(mContentView,getMeasuredHeight()/2);
        ViewCompat.setScaleX(mContentView,rightScale);
        ViewCompat.setScaleY(mContentView,rightScale);

        //左边的缩放:最小是0.7f,最大是1f; 透明度:最小是0f,最大是1f
        float leftScale = (float) (1 - 0.3*scale);
        float alphaScale = (float) (1 - 1*scale);
        //设置缩放的原点和大小和透明度
//        ViewCompat.setPivotX(mMenuView,mMenuWidth);
//        ViewCompat.setPivotY(mMenuView,getMeasuredHeight()/2);
        ViewCompat.setScaleX(mMenuView,leftScale);
        ViewCompat.setScaleY(mMenuView,leftScale);
        ViewCompat.setAlpha(mMenuView,alphaScale);

        //平移,抽屉效果
        ViewCompat.setTranslationX(mMenuView,l*0.3f);
    }

    /**
     * 获取屏幕的宽度
     */
    public int getScreenWidth() {
        Resources resources = this.getResources();
        DisplayMetrics dm = resources.getDisplayMetrics();
        return dm.widthPixels;
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //处理手机快速滑动
        if(mGestureDetector.onTouchEvent(ev)){
            return mGestureDetector.onTouchEvent(ev);
        }
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP:
                // 手指抬起获取滚动的位置
                int currentScrollX = getScrollX();
                if (currentScrollX > mMenuWidth / 2) {
                    // 关闭菜单
                    closeMenu();
                } else {
                    // 打开菜单
                    openMenu();
                }
                return false;
        }
        return super.onTouchEvent(ev);
    }

    private void openMenu() {
        smoothScrollTo(0,0);
        mMenuIsOpen = true;
    }

    private void closeMenu() {
        smoothScrollTo(mMenuWidth,0);
        mMenuIsOpen = false;
    }
    /**
     * 切换菜单的状态
     */
    private void toggleMenu() {
        if(mMenuIsOpen){
            closeMenu();
        }else{
            openMenu();
        }
    }
}

 <!--上面的最后2行是为了去除滚动条和阴影效果-->
    <com.example.zxtext.diyUi.SlidingMenu
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:scrollbars="none"
        android:fadingEdge="none"
        >
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal" >
            <include layout="@layout/sliding_item" />
            <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/ic_launcher_background">
            </LinearLayout>
        </LinearLayout>
    </com.example.zxtext.diyUi.SlidingMenu>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值