SlidingMenu 左侧滑动菜单

1.MainActivity

package loveworld.slidingmenu;

import java.util.ArrayList;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 左侧视图
        View leftViewGroup = createLeftListView();

        // 右侧视图
        View listView = createRightListView();

        final SlidingMenu mSlidingMenu = new SlidingMenu(this);
        mSlidingMenu.addLeftView(leftViewGroup);
        mSlidingMenu.addRightView(listView);

        setContentView(mSlidingMenu);
    }

	private View createLeftListView() {
		LinearLayout linearLayout = new LinearLayout(getBaseContext());
		linearLayout.setLayoutParams(new LayoutParams(300, LayoutParams.FILL_PARENT));
		linearLayout.setOrientation(LinearLayout.VERTICAL);

		TextView textViewOne = createTextView("俺是首页", Color.BLUE);
		TextView textViewTwo = createTextView("。。。。。。", Color.GRAY);
		TextView textViewThree = createTextView("俺是导航", Color.BLUE);
		TextView textViewFour = createTextView("俺有点丑", Color.GRAY);
		TextView textViewFive = createTextView("俺是设置", Color.BLUE);
		linearLayout.addView(textViewOne);
		linearLayout.addView(textViewTwo);
		linearLayout.addView(textViewThree);
		linearLayout.addView(textViewFour);
		linearLayout.addView(textViewFive);

		return linearLayout;
	}

	private TextView createTextView(final String text, final int color) {
		TextView textView = new TextView(getBaseContext());
		textView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
		textView.setText( text );
		textView.setPadding(0, 50, 0, 50);
		textView.setGravity(Gravity.CENTER);
		textView.setBackgroundColor(color);
		textView.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				Toast.makeText(getBaseContext(), "click  " + text, Toast.LENGTH_SHORT).show();
			}
		});
		return textView;
	}

	private View createRightListView() {
		ListView listView = new ListView(this);
        ArrayList<String> arrayList = new ArrayList<String>();
        for (int i = 0; i < 30; i++) {
			arrayList.add("World " + i);
		}
        CustomBaseAdapter customBaseAdapter = new CustomBaseAdapter(getBaseContext(), arrayList);
        listView.setAdapter(customBaseAdapter);
        listView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        listView.setDivider( new ColorDrawable(Color.BLACK) );
        listView.setDividerHeight(1);
        listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int position,
					long id) {
				Toast.makeText(getBaseContext(), "World position = " + position, Toast.LENGTH_SHORT).show();
			}
		});
		return listView;
	}

}

2.SlidingMenu

package loveworld.slidingmenu;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

public class SlidingMenu extends ViewGroup {

	private View mRightView;
	private View mLeftView;
	private ScrollRunnable mScrollRunnable;
	private int mTouchSlop;

	// 记录按下位置,用于判断当前滚动时向左还是向右
	private int mInterceptMotionX = 0;

	// 记录一次移动位置,用于计算移动偏移量
	private int mLastX;

	public SlidingMenu(Context context) {
		super(context);
		initSlidingMenu(context);
	}

	public SlidingMenu(Context context, AttributeSet attrs) {
		super(context, attrs);
		initSlidingMenu(context);
	}

	public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initSlidingMenu(context);
	}

	public void addLeftView(View leftView) {
		mLeftView = leftView;
		// 由于Touch分发机制,即使右侧视图盖住当前视图
		// 只要VISIBLE状态,都会先接收到Touch Event
		mLeftView.setVisibility(View.INVISIBLE);
		addView(leftView);
	}

	/**
	 * 提供右侧显示视图
	 *
	 * @param rightView
	 */
	public void addRightView(View rightView) {
		mRightView = rightView;

		addView(rightView);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		measureChildren(widthMeasureSpec, heightMeasureSpec);

		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightSize = MeasureSpec.getSize(heightMeasureSpec);

		setMeasuredDimension(widthSize, heightSize);
	}

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

		if (!changed) {
			return;
		}

		int childCount = getChildCount();
		for (int i = 0; i < childCount; i++) {
			View childView = getChildAt(i);

			int measuredWidth = childView.getMeasuredWidth();
			int measuredHeight = childView.getMeasuredHeight();

			childView.layout(l, 0, l + measuredWidth, measuredHeight);
		}
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {

		final int actioin = ev.getAction();
		final int x = (int) ev.getX();

		switch (actioin) {
		case MotionEvent.ACTION_DOWN:
			mInterceptMotionX = x;
			break;

		case MotionEvent.ACTION_MOVE:
			final int deltaX = x - mInterceptMotionX;
			final int distance = Math.abs(deltaX);
			// 点击区域必须在右侧视图,因为仅右侧视图可移动
			// 横向移动超过一定距离,可以自己根据需求改动
			if ( canSliding(ev) && distance > mTouchSlop * 2) {

				// 置为初始值
				mLastX = x;
				if (mScrollRunnable != null) {
					mScrollRunnable.endScroll();
					mScrollRunnable = null;
				}

				// 拦截Touch Event 交由当前ViewGruop onTouchEvent处理
				return true;
			}

			break;

		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			mInterceptMotionX = 0;
			break;
		}

		return false;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		final int x = (int) event.getX();

		switch (event.getAction()) {
		case MotionEvent.ACTION_MOVE:

			scrollIfNeed(x);
			return true;

		case MotionEvent.ACTION_UP:

			autoScrollIfNeed(x);
			break;
		}

		return false;
	}

	private void initSlidingMenu(Context context) {
		final ViewConfiguration configuration = ViewConfiguration.get(context);
        mTouchSlop = configuration.getScaledTouchSlop();
	}

	/**
	 * 当前手指点击位置是否在右侧视图区域内
	 *
	 * @param event
	 * @return true 可以滚动
	 */
	private boolean canSliding(MotionEvent event) {

		final int scrolledXInt = (int) (event.getX() + getScrollX());
		final int scrolledYInt = (int) (event.getY() + getScrollY());

		Rect frame = new Rect();
		mRightView.getHitRect(frame);
		if (frame.contains(scrolledXInt, scrolledYInt)) {
			return true;
		}

		return false;
	}

	private void scrollIfNeed(final int x) {
		// 计算与上次的偏移量
		int deltaX = x - mLastX;

		// 减少移动次数
		if (x != mLastX) {
			// 显示
			if (mLeftView.getVisibility() != View.VISIBLE) {
				mLeftView.setVisibility(View.VISIBLE);
			}

			int l = mRightView.getLeft();
			int t = mRightView.getTop();
			int b = mRightView.getBottom();

			// 右侧视图的滑动区域,只能在左侧视图范围内滑动
			int rightViewLeft = Math.max(mLeftView.getLeft(), l + deltaX);
			rightViewLeft = Math.min(mLeftView.getRight(), rightViewLeft);

			// 控制随手指滑动
			mRightView.layout(rightViewLeft, t, rightViewLeft + mRightView.getWidth(), b);
		}

		// 滑动到最左侧
		if (mRightView.getLeft() == mLeftView.getLeft()) {
			mLeftView.setVisibility(View.INVISIBLE);
		}

		// 记录当前值供下次计算
		mLastX = x;
	}

	private void autoScrollIfNeed(final int x) {
		mScrollRunnable = new ScrollRunnable();

		// 用于判断滑动方向
		final int deltaX = x - mInterceptMotionX;
		// x轴向右是依次递增与手指落下点差值,小于0说明是手指向左滑动
		boolean moveLeft = deltaX <= 0;

		// 滑动距离超过左侧视图一半,才会沿着手指方向滚动
		final int distance = Math.abs(deltaX);
		if (distance < mLeftView.getWidth() / 2) {
			// 从哪来回哪去
			moveLeft = !moveLeft;
		}

		// 启动自动滚动
		mScrollRunnable.startScroll(moveLeft);
	}

	private class ScrollRunnable implements Runnable {
		// 滚动辅助类,提供起始位置,移动偏移,移动总时间,可以获取每次滚动距离
		private Scroller mScroller = new Scroller(getContext());

		@Override
		public void run() {
			final Scroller scroller = mScroller;
			// 计算滚动偏移,返回是否可以接着滚动
			boolean more = scroller.computeScrollOffset();
			// 计算后获取需要滚动到的位置
			final int x = scroller.getCurrX();

			if (more) {
				// 与手动滚动调用的方法相同
				scrollIfNeed(x);
				// 当前子线程已经执行完,但是需要接着滚动
				// 所以把当前Runnable再次添加到消息队列中
				post(this);
			} else {
				// 不需要滚动
				endScroll();
			}

		}

		private void startScroll(boolean moveLeft) {
			// 滚动前设置初始值
			mLastX = mRightView.getLeft();

			int dx = 0;

			// 计算移动总距离
			if (moveLeft) {
				// 当前到左视图左侧边界距离
				dx = mLeftView.getLeft() - mRightView.getLeft();
			} else {
				// 到右侧边界
				dx = mLeftView.getRight() - mRightView.getLeft();
			}

			// 开始滚动
			mScroller.startScroll(mRightView.getLeft(), 0, dx, 0, 300);
			// 把当前Runnable添加到消息队列中
			post(this);
		}

		private void endScroll() {
			// 从消息队列中把当前Runnable删除,即停止滚动
			removeCallbacks(this);
		}

	}
}

3.CustomBaseAdapter

package loveworld.slidingmenu;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

/**
 *
 * getView第一个参数position从0开始
 *
 * date: 2011-11-10
 *
 */
public class CustomBaseAdapter extends BaseAdapter
{

    private Context mContext;
    private ArrayList<String> mArrayList;
    private LayoutInflater mLayoutInflater;

    public CustomBaseAdapter(Context context, ArrayList<String> pData)
    {
        mContext = context;
        mArrayList = pData;

        mLayoutInflater = LayoutInflater.from(mContext);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {

        // 常见的优化ViewHolder
        ViewHolder viewHolder = null;
        if (null == convertView)
        {
            convertView = mLayoutInflater.inflate(R.layout.listview_item, null);

            viewHolder = new ViewHolder();
            viewHolder.content = (TextView) convertView
                    .findViewById(R.id.content);
            viewHolder.contentIcon = (ImageView) convertView
                    .findViewById(R.id.content_icon);

            convertView.setTag(viewHolder);
        }
        else
        {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        // 获取数据
        viewHolder.content.setText(mArrayList.get(position));
        viewHolder.contentIcon.setImageResource(R.drawable.ic_launcher);

        return convertView;
    }

    @Override
    public int getCount()
    {
        if (null != mArrayList)
        {
            return mArrayList.size();
        }
        else
        {
            return 0;
        }
    }

    @Override
    public Object getItem(int position)
    {
        if (null != mArrayList && position < mArrayList.size())
        {
            return mArrayList.get(position);
        }
        else
        {
            return null;
        }
    }

    @Override
    public long getItemId(int position)
    {
        return position;
    }

    private class ViewHolder
    {
        TextView content;
        ImageView contentIcon;
    }

}

4.listview_item

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/list_item_selector"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/content_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left"/>

    <TextView
        android:id="@+id/content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_gravity="center"
        android:layout_marginLeft="10dip"
        android:textColor="@color/content_color" />

</LinearLayout>

SlidingMenu 左侧滑动菜单,布布扣,bubuko.com

时间: 2024-12-13 10:59:08

SlidingMenu 左侧滑动菜单的相关文章

Android UI(三)SlidingMenu实现滑动菜单(详细 官方)

Jeff Lee blog:   http://www.cnblogs.com/Alandre/  (泥沙砖瓦浆木匠),retain the url when reproduced ! Thanks 效果图: 求资源到首页上部加群即可. 一. SlidingMenu简介 github:https://github.com/jfeinstein10/SlidingMenu 官网上面的简介上翻译的: SlidingMenu是能让开发者很容易的开发有滑动菜单App(像Google+,YouTube,F

安卓开发之左侧滑动菜单学习

左侧滑动窗口是很多app应用经常用到的,学习它也是很有必要的. 左侧滑动xml的布局: <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:lay

左侧滑动菜单

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Typ

Android 学习笔记之AndBase框架学习(七) SlidingMenu滑动菜单的实现

PS:努力的往前飞..再累也无所谓.. 学习内容: 1.使用SlidingMenu实现滑动菜单..   SlidingMenu滑动菜单..滑动菜单在绝大多数app中也是存在的..非常的实用..Github有位牛人将这个东西书写成了一个简单的框架..我们只需要通过引用相关的资源就能够完成一个滑动菜单的实现..有了这一层的基础..那么滑动菜单就很容易实现了..就拿我们最为熟悉的QQ来说吧..当我们进行滑动操作的时候..会有一个新的View去覆盖原本的View..我们可以通过触发新的视图上的控件来执行

Android 滑动菜单SlidingMenu

首先我们看下面视图: 这种效果大家都不陌生,网上好多都说是仿人人网的,估计人家牛逼出来的早吧,我也参考了一一些例子,实现起来有三种方法,我下面简单介绍下: 方法一:其实就是对GestureDetector手势的应用及布局文件的设计. 布局文件main.xml    采用RelativeLayout布局. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=&quo

Android开源库--SlidingMenu左右侧滑菜单

如果说我比别人看得更远些,那是因为我站在了巨人的肩上. github地址:https://github.com/jfeinstein10/SlidingMenu 设置: 1.下载之后以依赖项的形式添加到项目中即可. 2.如果要集成ActionBarSherlock,以依赖项的形式添加到SlidingMenu,然后使用的时候继承SherlockActivities即可. 使用: 1.直接通过代码方式实现. 2.通过继承SlidingActivity实现. 3.直接在XML布局里面使用. 以上示例都

Android 3D滑动菜单完全解析,实现推拉门式的立体特效

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/10471245 在上一篇文章中,我们学习了Camera的基本用法,并借助它们编写了一个例子,实现了类似于API Demos里的图片中轴旋转功能.不过那个例子的核心代码是来自于API Demos中带有的Rotate3dAnimation这个类,是它帮助我们完成了所有的三维旋转操作,所有Matrix和Camera相关的代码也是封装在这个类中. 这样说来的话,大家心里会不会痒痒的呢?虽然

Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9671609 记得在很早之前,我写了一篇关于Android滑动菜单的文章,其中有一个朋友在评论中留言,希望我可以帮他将这个滑动菜单改成双向滑动的方式.当时也没想花太多时间,简单修改了一下就发给了他,结果没想到后来却有一大批的朋友都来问我要这份双向滑动菜单的代码.由于这份代码写得很不用心,我发了部分朋友之后实在不忍心继续发下去了,于是决定专门写一篇文章来介绍更好的Android双向滑

【转】Android双向滑动菜单完全解析,教你如何一分钟实现双向滑动特效

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9671609 记得在很早之前,我写了一篇关于Android滑动菜单的文章,其中有一个朋友在评论中留言,希望我可以帮他将这个滑动菜单改成双向滑动的方式.当时也没想花太多时间,简单修改了一下就发给了他,结果没想到后来却有一大批的朋友都来问我要这份双向滑动菜单的代码.由于这份代码写得很不用心,我发了部分朋友之后实在不忍心继续发下去了,于是决定专门写一篇文章来介绍更好的Android双向滑