package loveworld.slidingmenu;
import android.content.Context;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
public class SlidingMenu extends ViewGroup {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private View mRightView;
private View mLeftView;
private ScrollRunnable mScrollRunnable;
/**
* 记录一次移动位置,用于计算移动偏移量
*/
private int mLastX;
/**
* 按下时记录,用于判断当前滚动时向左还是向右
*/
private int mMotionX;
// ===========================================================
// Constructors
// ===========================================================
public SlidingMenu(Context context) {
super(context);
}
public SlidingMenu(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
// ===========================================================
// Public Methods
// ===========================================================
public void addLeftView(View leftView) {
mLeftView = leftView;
addView(leftView);
}
/**
* 提供右侧显示视图
*
* @param rightView
*/
public void addRightView(View rightView) {
mRightView = rightView;
addView(rightView);
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@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) {
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 onTouchEvent(MotionEvent event) {
final int x = (int) event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastX = x;
mMotionX = x;
if (mScrollRunnable != null) {
mScrollRunnable.endScroll();
mScrollRunnable = null;
}
boolean inRegion = canSliding(event);
return inRegion;
case MotionEvent.ACTION_MOVE:
scrollIfNeed(x);
return true;
case MotionEvent.ACTION_UP:
autoScrollIfNeed(x);
break;
}
return true;
}
// ===========================================================
// Private Methods
// ===========================================================
/**
* 只有右侧视图可以移动
*
* @param event
* @return true 可以滚动
*/
private boolean canSliding(MotionEvent event) {
int[] location = new int[2];
// 获取右侧视图相对于屏幕坐标值
mRightView.getLocationOnScreen(location);
RectF region = new RectF();
region.set(location[0] , location[1] ,
location[0] + mRightView.getWidth(),
location[1] + mRightView.getHeight());
// 当前手指点击位置是否在右侧视图区域内
boolean inRegion = region.contains(event.getRawX(), event.getRawY());
return inRegion;
}
private void scrollIfNeed(final int x) {
// 计算与上次的偏移量
int deltaX = x - mLastX;
// 减少移动次数
if (x != mLastX) {
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);
}
// 记录当前值供下次计算
mLastX = x;
}
private void autoScrollIfNeed(final int x) {
mScrollRunnable = new ScrollRunnable();
// 用于判断滑动方向
final int deltaX = x - mMotionX;
// x轴向右是依次递增与手指落下点差值,小于0说明是手指向左滑动
boolean moveLeft = deltaX <= 0;
// 滑动距离超过左侧视图一半,才会沿着手指方向滚动
final int distance = Math.abs(deltaX);
if (distance < mLeftView.getWidth() / 2) {
// 从哪来回哪去
moveLeft = !moveLeft;
}
// 启动自动滚动
mScrollRunnable.startScroll(moveLeft);
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
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);
}
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
Android滑动菜单 - 实现手动、自动滚动视图
共13个文件
java:4个
png:3个
xml:2个
4星 · 超过85%的资源 需积分: 16 343 下载量 163 浏览量
2013-03-20
11:17:07
上传
评论 2
收藏 27KB ZIP 举报
温馨提示
Android滑动菜单 - 实现手动、自动滚动视图,供大家一起共同分享学习。
资源推荐
资源详情
资源评论
收起资源包目录
Android滑动菜单 - 实现手动、自动滚动视图.zip (13个子文件)
SlidingMenu
bin
res
drawable-ldpi
ic_launcher.png 3KB
drawable-hdpi
ic_launcher.png 10KB
values
strings.xml 120B
drawable-mdpi
ic_launcher.png 5KB
layout
gen
loveworld
slidingmenu
BuildConfig.java 163B
R.java 502B
proguard.cfg 1KB
src
loveworld
slidingmenu
SlidingMenu.java 6KB
MainActivity.java 3KB
.project 847B
.classpath 364B
project.properties 360B
AndroidManifest.xml 737B
共 13 条
- 1
战歌IT
- 粉丝: 122
- 资源: 2409
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
- 5
- 6
前往页