侧滑菜单---方案一 普通侧滑菜单

整理自慕课网  实现菜单布局

总体思路:

以HorizontalScrollView为基础。将menu和content从左至右都布局在上面,这样横向的moveEvent就由HorizontalScrollView

代为完成。这样我们就只需要判断横向的偏移量来决定up的时候是显示menu还是content

布局文件就不写了  大致效果就图片上这样


额  还是写一下menu的布局吧

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:background="@drawable/img_frame_background">
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    >
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ImageView
            android:layout_centerVertical="true"
            android:id="@+id/imag1"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="20dp"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/img_1"
            />

        <TextView
            android:layout_centerVertical="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:layout_toRightOf="@id/imag1"
            android:text="第一个Item"
            android:textColor="#ffffff"
            android:layout_marginLeft="20dp"

            />
    </RelativeLayout>
    <多个RelativeLayout/>
 
</LinearLayout>

</RelativeLayout>


总体布局:自定义的HorizontalScrollView控件,包裹一个横向的ListView,这样当ListView的宽度大于屏幕宽度时,

由于ScrollView的存在就可以实现左右滑动的效果。listView包含一个左边默认隐藏的menu,和右边的一个屏幕大小的content

<?xml version="1.0" encoding="utf-8"?>
<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="jintong.slidemenu1.MainActivity">

    <jintong.slidemenu1.SlidingMenu1
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none">

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

            <include layout="@layout/leftmenu" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/qq">

            </LinearLayout>
        </LinearLayout>
    </jintong.slidemenu1.SlidingMenu1>
</RelativeLayout>


重点:自定义的Horizontal ScrollView;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

/**
 * 
 * 
 * 自定义ViewGroup重点要实现的方法
 * 1.onMeasure
 * 决定内部View(子View)以及自身的宽和高
 * 2.onLayout
 * 决定子View的放置的位置
 * 3.onTouchEvent
 */
public class SlidingMenu1 extends HorizontalScrollView {


    private LinearLayout mWrapper;//包裹菜单和内容
    private ViewGroup mMenu;//菜单
    private ViewGroup mContent;//内容

    private int mScreenWidth;//屏幕宽度
    private int mMenuRightPadding;//菜单右侧距离屏幕右侧的距离
    private int mMenuWidth;//menu的宽度

    //设置一个标记,防止onMeasure多次测量
    private boolean once = true;


    /**
     * 未使用自定义属性时,会调用这个两个参数的构造函数
     */
    public SlidingMenu1(Context context, AttributeSet attrs) {
        super(context, attrs);
        WindowManager wm = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);
        //DisplayMetrics经过getMetrics()方法后 ,宽高就被赋值了
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);

        mScreenWidth = outMetrics.widthPixels;

        //把布局使用的dp转为计算时使用的px,padding值是150dp
        mMenuRightPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 150, context.getResources().getDisplayMetrics());

    }

    /**
     * 设置子View和自身的宽和高
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        //如果是第一次,进行测量,并且在测量设置完成后,once=false
        if (once) {
            //取出HorizontalScrollView的第一个元素也就是LineaLayout
            mWrapper = (LinearLayout) getChildAt(0);
            //LineaLayout的第一个元素menu
            mMenu = (ViewGroup) mWrapper.getChildAt(0);
            mContent = (ViewGroup) mWrapper.getChildAt(1);

            //宽度的设置,menu和content的宽度就可以决定wrapper的宽度,就不用设置了
            mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuRightPadding;
            mContent.getLayoutParams().width = mScreenWidth;

            once = false;

        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 在不做任何偏移的起始情况下,menu是完全显示的
     * 所以要通过设置偏移量,先将menu隐藏
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        if (changed) {
            //整个布局偏移一个菜单的宽度,使菜单完全隐藏
            // 这个偏移是瞬间完成的
            this.scrollTo(mMenuWidth, 0);
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_UP:

                /**
                 *  这里的ScrollX表示用户在滑动抬起之后 未拉出的菜单宽度
                 *  就是仍然隐藏的宽度
                 *  当这个宽度小于菜单宽度的一半时,应让菜单显示
                 *  多于菜单的一半时,让菜单继续隐藏
                 */

                int scrollX = getScrollX();
                if (scrollX >= mMenuWidth / 2) {//完全隐藏
                    this.smoothScrollTo(mMenuWidth, 0);
                } else {//完全显示,就是不做偏移的起始位置
                    this.smoothScrollTo(0, 0);


                }
                return true;


        }


        return super.onTouchEvent(ev);
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值