展会信息港展会大全

扩展HorizontalScrollView实现整个屏幕滚动 android开发学习
来源:互联网   发布日期:2015-10-03 11:15:16   浏览:2074次  

导读:扩展HorizontalScrollView实现整个屏幕滚动import java.lang.reflect.Field; import android.content.Context; import android.util.AttributeSet; import android.view.animation.AnimationUtils; impo......

扩展HorizontalScrollView实现整个屏幕滚动

import java.lang.reflect.Field;

import android.content.Context;

import android.util.AttributeSet;

import android.view.animation.AnimationUtils;

import android.view.animation.Interpolator;

import android.view.animation.OvershootInterpolator;

import android.widget.HorizontalScrollView;

import android.widget.OverScroller;

import android.widget.Scroller;

public class HorizontalScrollViewEx extends HorizontalScrollView {

static final int ANIMATED_SCROLL_GAP = 250;

private long mLastScroll;

private Field mScrollerField;

ScrollerEx scrollerEx = null;

public HorizontalScrollViewEx(Context context) {

this(context, null);

}

public HorizontalScrollViewEx(Context context, AttributeSet attrs) {

super(context, attrs);

this.setSmoothScrollingEnabled(false);

initScroller();

}

public HorizontalScrollViewEx(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

this.setSmoothScrollingEnabled(false);

initScroller();

}

private void initScroller() {

try {

mScrollerField = HorizontalScrollView.class.getDeclaredField("mScroller");

mScrollerField.setAccessible(true);

String type = mScrollerField.getType().getSimpleName();

if ("OverScroller".equals(type)) {

scrollerEx = new ScrollerEx() {

private OverScroller mScroller = null;

public void startScroll(int startX, int startY, int dx, int dy, int duration) {

mScroller.startScroll(startX, startY, dx, dy, duration);

}

public boolean isFinished() {

return mScroller.isFinished();

}

public Object getScroller() {

return mScroller;

}

public void create(Context context, Interpolator interpolator) {

mScroller = new OverScroller(context, interpolator);

}

public void abortAnimation() {

if (mScroller != null) {

mScroller.abortAnimation();

}

}

};

} else {

scrollerEx = new ScrollerEx() {

private Scroller mScroller = null;

public void startScroll(int startX, int startY, int dx, int dy, int duration) {

mScroller.startScroll(startX, startY, dx, dy, duration);

}

public boolean isFinished() {

return mScroller.isFinished();

}

public Object getScroller() {

return mScroller;

}

public void create(Context context, Interpolator interpolator) {

mScroller = new Scroller(context, interpolator);

}

public void abortAnimation() {

if (mScroller != null) {

mScroller.abortAnimation();

}

}

};

}

} catch (Exception ex) {

}

}public final void smoothScrollBy(int dx, int dy, int addDuration) {

float tension = 0f;

scrollerEx.abortAnimation();

Interpolator ip = new OvershootInterpolator(tension);

scrollerEx.create(getContext(), ip);

try {

mScrollerField.set(this, scrollerEx.getScroller());

} catch (Exception e) {

}

long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;

if (duration > ANIMATED_SCROLL_GAP) {

scrollerEx.startScroll(getScrollX(), getScrollY(), dx, dy, addDuration);

awakenScrollBars();

// awakenScrollBars(mScroller.getDuration());

invalidate();

} else {

if (!scrollerEx.isFinished()) {

scrollerEx.abortAnimation();

}

scrollBy(dx, dy);

}

mLastScroll = AnimationUtils.currentAnimationTimeMillis();

}

public final void smoothScrollTo(int x, int y, int duration) {

smoothScrollBy(x - getScrollX(), y - getScrollY(), duration);

}

private interface ScrollerEx {

void create(Context context, Interpolator interpolator);

Object getScroller();

void abortAnimation();

void startScroll(int startX, int startY, int dx, int dy, int duration);

boolean isFinished();

}

}

核心部分是利用反射的方法取得父类的 mScroller对象,然后再使用 mScroller控制滚动。

然后在Activity里重写dispatchTouchEvent方法,使用GestureDetector控制滚动距离。 下面是部分代码

private HorizontalScrollViewEx hsvMain;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

hsvMain = (HorizontalScrollViewEx) findViewById(R.id.hsvMain);

}

// 监听屏幕动作事件

GestureDetector =gestureDetector = new GestureDetector(new OnGestureListener() {

private int LEFT_DISTANCE = -150;

private int RIGHT_DISTANCE = 150;

// 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发

public boolean onDown(MotionEvent e) {

return true;

}

// 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN,

// 多个ACTION_MOVE, 1个ACTION_UP触发

// e1:第1个ACTION_DOWN MotionEvent

// e2:最后一个ACTION_MOVE MotionEvent

// velocity X:X 轴上的移动速度,像素/秒

// velocity Y:Y 轴上的移动速度,像素/秒

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

float distanceX = e2.getX() - e1.getX();

if (distanceX < LEFT_DISTANCE) {

// left

setXPosition(true);

} else if (distanceX > RIGHT_DISTANCE) {

// right

setXPosition(false);

}

hsvMain.smoothScrollTo(xPosition, 0, speed);

return true;

}

// 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发

public void onLongPress(MotionEvent e) {

}

// 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发

public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

hsvMain.scrollBy((int) distanceX, 0);

return true;

}

// 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发

// 注意和onDown()的区别,强调的是没有松开或者拖动的状态

public void onShowPress(MotionEvent e) {

}

// 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发

public boolean onSingleTapUp(MotionEvent e) {

if (e.getY() < offsetOfBottom) {

return true;

}

if (e.getX() > halfOfWidth) {

setXPosition(true);

} else {

setXPosition(false);

}

hsvMain.scrollTo(xPosition, 0);

return true;

}

});

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

boolean result = gestureDetector.onTouchEvent(ev);

if (result == false) {

final int action = ev.getAction();

switch (action & MotionEvent.ACTION_MASK) {

case MotionEvent.ACTION_UP:

hsvMain.smoothScrollTo(xPosition, 0, speed);

result = true;

}

}

return true;

}

效果:

第一页

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港