自动反弹的HorizontalScrollView

本文介绍了一种自定义的Android视图组件——ElasticHScrollView,该组件实现了水平滚动及边缘回弹效果。通过监听触摸事件,实现了手指滑动时跟随滚动,并在达到边界时进行平滑回弹。
package com.example.sy;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.HorizontalScrollView;

public class ElasticHScrollView extends HorizontalScrollView {

	private View inner;
	private float x;
	private Rect normal = new Rect();

	public ElasticHScrollView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public ElasticHScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onFinishInflate() {
		if (getChildCount() > 0) {
			inner = getChildAt(0);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		if (inner == null) {
			return super.onTouchEvent(ev);
		} else {
			commOnTouchEvent(ev);
		}
		return super.onTouchEvent(ev);
	}

	public void commOnTouchEvent(MotionEvent ev) {
		int action = ev.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			x = ev.getX();
			break;
		case MotionEvent.ACTION_UP:
			if (isNeedAnimation()) {
				animation();
			}
			break;
		case MotionEvent.ACTION_MOVE:
			final float preX = x;
			float nowX = ev.getX();
			int deltaX = (int) (preX - nowX);
			// 滚动
			scrollBy(deltaX, 0);
			x = nowX;
			// 当滚动到最上或最下时就不会再滚动,这是移动布局
			if (isNeedMove()) {
				if (normal.isEmpty()) {
					// 保存正常的布局位置
					normal.set(inner.getLeft(), inner.getTop(),
							inner.getRight(), inner.getBottom());

				}
				// 移动布局
				inner.layout(inner.getLeft() - deltaX, inner.getTop(),
						inner.getRight() - deltaX, inner.getBottom());
			}
			break;
		default:
			break;
		}
	}

	// 开启动画移动

	public void animation() {
		// 开启移动动画
		TranslateAnimation ta = new TranslateAnimation(inner.getLeft(),
				normal.left, 0, 0);
		ta.setDuration(50);
		inner.startAnimation(ta);
		// 设置回到正常的布局位置
		inner.layout(normal.left, normal.top, normal.right, normal.bottom);
		normal.setEmpty();
	}

	// 是否需要开启动画
	public boolean isNeedAnimation() {
		return !normal.isEmpty();
	}

	// 是否需要移动布局
	public boolean isNeedMove() {
		int offset = inner.getMeasuredWidth() - getWidth();
		int scrollX = getScrollX();
		if (scrollX == 0 || scrollX == offset) {
			return true;
		}
		return false;
	}

}

### ### HorizontalScrollView 是否支持自动滚动显示 `HorizontalScrollView` 本身并不直接提供“自动滚动显示”的功能,但可以通过编程方式实现类似的效果。例如,可以通过调用 `smoothScrollTo()` 或 `smoothScrollBy()` 方法,结合定时器或手势识别来实现自动滚动显示的需求。 在实际开发中,若需要实现自动滚动显示,可以通过 `Handler` 或 `ValueAnimator` 等方式控制滚动行为。以下是一个使用 `Handler` 实现自动水平滚动的示例: ```java final HorizontalScrollView scrollView = findViewById(R.id.horizontal_scroll_view); final Runnable autoScrollRunnable = new Runnable() { int scrollX = 0; @Override public void run() { scrollX += 10; if (scrollX > scrollView.getChildAt(0).getWidth()) { scrollX = 0; } scrollView.smoothScrollTo(scrollX, 0); new Handler(Looper.getMainLooper()).postDelayed(this, 50); } }; // 启动自动滚动 new Handler(Looper.getMainLooper()).post(autoScrollRunnable); ``` 上述代码通过不断修改 `scrollTo()` 的参数,实现水平方向上的自动滚动效果。此方法可以用于实现类似“跑马灯”或“自动轮播”的视觉效果。 此外,某些开发者在实际应用中对 `HorizontalScrollView` 进行了扩展,以支持自动滚动、滑动对齐等功能。例如,可以通过自定义 `HorizontalScrollView` 来实现“自动居中”或“无限滚动”的效果,这些功能通常需要结合 `Scroller` 或 `OverScroller` 来实现更精细的控制 [^1]。 若需要更复杂的自动滚动行为(如滑动对齐、循环滚动等),则推荐使用 `RecyclerView` 并结合 `SnapHelper` 来实现,因为 `RecyclerView` 在滑动控制和视图复用方面具有更强的灵活性和扩展性 [^1]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值