侧滑菜单

Posted 猫叔聊技术

tags:

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

自定义viewgroup->sildeMenu.java

package com.xuhao.sliding.view;

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

public class SildeMenu extends FrameLayout 
	private View menuView, mainView;
	private int menuWidth = 0;
	private Scroller scroller;

	public SildeMenu(Context context) 
		super(context);
		init();
	

	public SildeMenu(Context context, AttributeSet attrs) 
		super(context, attrs);
		init();
	

	private void init() 
		scroller = new Scroller(getContext());
	

	/**
	 * 当1级的子view全部加载完调用,可以用初始化子view的引用 注意,这里无法获取子view的宽高
	 */
	@Override
	protected void onFinishInflate() 
		super.onFinishInflate();
		menuView = getChildAt(0);
		mainView = getChildAt(1);
		menuWidth = menuView.getLayoutParams().width;
		// Log.e("Main", menuWidth + "");

	

	/**
	 * widthMeasureSpec和heightMeasureSpec是系统测量SlideMenu时传入的参数
	 * 这2个参数测kiang出来的宽高能让slidemenu充满船体,其实是正好等于屏幕的宽高
	 */

	// @Override
	// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
	// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	// int measureSpec = MeasureSpec.makeMeasureSpec(menuWidth,
	// MeasureSpec.EXACTLY);
	// // Log.e("Main", measureSpec + "measureSpec");
	// // 测量所有子view的宽高
	// // 通过getLayoutParams方法可以获取到布局文件中指定宽高
	// menuView.measure(measureSpec, heightMeasureSpec);
	// // 直接使用slidemenu的测量参数,以为他的狂傲就是充满父窗体
	// mainView.measure(widthMeasureSpec, heightMeasureSpec);
	// 

	// dispatchTouchEvent(MotionEvent ev)

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) 
		switch (ev.getAction()) 
		case MotionEvent.ACTION_DOWN:
			downX = (int) ev.getX();
			break;
		case MotionEvent.ACTION_MOVE:
			int deltaX = (int) (ev.getX() - downX);
			
			if(Math.abs(deltaX)>8)
				//如果左右滑动大于8就让slidemenu处理
				return true;
			
			break;
		
		return super.onInterceptTouchEvent(ev);
	

	/**
	 * l:当前子view的左边在父view的坐标系中的x坐标 t:当前子view的顶边在父view坐标系中的y坐标
	 */

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) 

		menuView.layout(-menuWidth, 0, 0, menuView.getMeasuredHeight());
		mainView.layout(0, 0, r, b);
	

	private int downX;

	@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 = moveX - downX;
			int newScrollX = getScrollX() - detalX;
			if (newScrollX < -menuWidth)
				newScrollX = -menuWidth;
			if (newScrollX > 0)
				newScrollX = 0;
			scrollTo(newScrollX, 0);
			downX = moveX;
			break;
		case MotionEvent.ACTION_UP:
			// ScrollAnimation animation;
			// if (getScrollX() > -menuWidth / 2) 
			// // 关闭菜单
			// animation = new ScrollAnimation(this, 0);
			// // scrollTo(0, 0);
			//  else 
			// // 打开菜单
			// animation = new ScrollAnimation(this, -menuWidth);
			// // scrollTo(-menuWidth, 0);
			// 
			// startAnimation(animation);
			if (getScrollX() > -menuWidth / 2) 
				// 关闭菜单
				closeMenu();
			 else 
				// 打开菜单
				openMenu();
			
			break;
		
		return true;
	

	/**
	 * 打开惨淡
	 */
	private void openMenu() 
		scroller.startScroll(getScrollX(), 0, -menuWidth - getScrollX(), 0, 400);
		invalidate();
	

	/**
	 * 关闭菜单
	 */
	private void closeMenu() 
		scroller.startScroll(getScrollX(), 0, 0 - getScrollX(), 0, 400);
		invalidate();
	

	/**
	 * Scroller不主动去掉用此方法 invalidate()可以调用这个方法 invalidate->draw->computeScroll
	 */
	@Override
	public void computeScroll() 
		super.computeScroll();
		if (scroller.computeScrollOffset()) // 返回true表示动画没有结束
			scrollTo(scroller.getCurrX(), 0);
			invalidate();
		
	
	
	public void switchMenu()
		if(getScrollX()==0)
			//需要打开
			openMenu();
		else
			//需要关闭
			closeMenu();
		
	

activity_main.xml

<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" >

    <com.xuhao.sliding.view.SildeMenu
        android:id="@+id/sildemenu"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <!-- 菜单布局 -->

        <include layout="@layout/layout_menu" />
        <!-- 主界面布局 -->

        <include layout="@layout/layout_main" />
    </com.xuhao.sliding.view.SildeMenu>

</RelativeLayout>


layout_menu.xml

<?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" >

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

        <TextView
            style="@style/MenuTabStyle"
            android:background="#33ababab"
            android:drawableLeft="@drawable/tab_news"
            android:text="新闻" />

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

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

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

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

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

        <TextView
            style="@style/MenuTabStyle"
            android:drawableLeft="@drawable/tab_focus"
            android:text="聚合阅读" />
    </LinearLayout>

</ScrollView>


layout_main.xml


<?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="#ccc"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:gravity="center_vertical"
        android:background="@drawable/top_bar_bg" >

        <ImageView
            android:id="@+id/iv_menu"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/main_back" />

        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:layout_marginBottom="5dp"
            android:layout_marginTop="5dp"
            android:background="@drawable/top_bar_divider" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dp"
            android:text="序号新闻"
            android:textColor="#ffffff"
            android:textSize="22sp" />
    </LinearLayout>
    <TextView android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textColor="#000000"
            android:textSize="30sp"
            android:gravity="center"
            android:text="钓鱼岛是中国的..."/>

</LinearLayout>

自定义的动画ScrollAnimation.java


package com.xuhao.sliding.view;

import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;

public class ScrollAnimation extends Animation 
	private View view;
	private int startScrollX;
	private int totalValue;
	private int targetScrollX;

	public ScrollAnimation(View view, int targetScrollX) 
		super();
		this.view = view;
		this.targetScrollX = targetScrollX;

		startScrollX = view.getScrollX();

		totalValue = targetScrollX - startScrollX;
		int time = Math.abs(totalValue);
		setDuration(time);
	

	/**
	 * 在指定的时间内一直执行该方法,一直到动画结束 interpolatedTime:0-1 标识动画执行的进度或者百分比 time:0 - 0.5 -
	 * 0.7 - 1 value:10 - 60 - 80 - 110 当前的值=起始值+总的差值*interpolatedTime
	 */

	@Override
	protected void applyTransformation(float interpolatedTime, Transformation t) 
		super.applyTransformation(interpolatedTime, t);
		int currentScrollX = (int) (startScrollX + totalValue
				* interpolatedTime);
		view.scrollTo(currentScrollX, 0);
	


mainactiviy.java


package com.xuhao.sliding;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ImageView;

import com.xuhao.sliding.view.SildeMenu;
import comxuhao.sliding.R;

public class MainActivity extends Activity 
	private ImageView iv;
	private SildeMenu sildeMenu;

	@Override
	protected void onCreate(Bundle savedInstanceState) 
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		iv=(ImageView) findViewById(R.id.iv_menu);
		sildeMenu=(SildeMenu) findViewById(R.id.sildemenu);
		iv.setOnClickListener(new OnClickListener() 
			
			@Override
			public void onClick(View v) 
				sildeMenu.switchMenu();
			
		);
	




项目源码: https://github.com/xh2015/sildeMenu.git

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

Python|MUI侧滑菜单-a标签跳转

侧滑菜单

IOS开发UI篇--一个侧滑菜单SlidingMenu

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

MUI - 侧滑菜单

android:QQ多种侧滑菜单的实现