可以监听滚动状态的HorizontalScrollView
package com.trs.v7.home.view;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;
/**
* 可以监听滚动状态的HorizontalScrollView
*/
public class WZHorizontalScrollView extends HorizontalScrollView {
public WZHorizontalScrollView(Context context) {
super(context);
}
public WZHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public interface ScrollViewListener {
void onScrollChanged(ScrollType scrollType);
}
private Handler mHandler;
private ScrollViewListener scrollViewListener;
//滚动状态:
// IDLE 滚动停止 TOUCH_SCROLL 手指拖动滚动 FLING滚动
public enum ScrollType{IDLE,TOUCH_SCROLL,FLING};
/**
* 记录当前滚动的距离
*/
private int currentX = -9999999;
/**
* 当前滚动状态
*/
private ScrollType scrollType = ScrollType.IDLE;
/**
* 滚动监听间隔
*/
private int scrollDealy = 50;
/**
* 滚动监听runnable
*/
private Runnable scrollRunnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if(getScrollX()==currentX){
//滚动停止 取消监听线程
scrollType = ScrollType.IDLE;
if(scrollViewListener!=null){
scrollViewListener.onScrollChanged(scrollType);
}
mHandler.removeCallbacks(this);
return;
}else{
//手指离开屏幕 view还在滚动的时候
scrollType = ScrollType.FLING;
if(scrollViewListener!=null){
scrollViewListener.onScrollChanged(scrollType);
}
}
currentX = getScrollX();
mHandler.postDelayed(this, scrollDealy);
}
};
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
this.scrollType = ScrollType.TOUCH_SCROLL;
scrollViewListener.onScrollChanged(scrollType);
//手指在上面移动的时候 取消滚动监听线程
mHandler.removeCallbacks(scrollRunnable);
break;
case MotionEvent.ACTION_UP:
//手指移动的时候
mHandler.post(scrollRunnable);
break;
}
return super.onTouchEvent(ev);
}
/**
* 必须先调用这个方法设置Handler 不然会出错
* 2014-12-7 下午3:55:39
* @author DZC
* @return void
* @param handler
* @TODO
*/
public void setHandler(Handler handler){
this.mHandler = handler;
}
/**
* 设置滚动监听
* 2014-12-7 下午3:59:51
* @author DZC
* @return void
* @param listener
* @TODO
*/
public void setOnScrollStateChangedListener(ScrollViewListener listener){
this.scrollViewListener = listener;
}
}
自动内容居中的HorizontalScrollView 继承自上一个HorizontalScrollView
package com.trs.v7.home.view;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
/**
* <pre>
* Created by zhuguohui
* Date: 2023/4/20
* Time: 17:50
* Desc:在滚动结束以后可以自动停留在居中位置的WZHorizontalScrollView
* </pre>
*/
public class AutoCenterHorizontalScrollView extends WZHorizontalScrollView {
public AutoCenterHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
setHandler(new Handler());
setOnScrollStateChangedListener(scrollViewListener);
}
ScrollViewListener scrollViewListener = new ScrollViewListener() {
@Override
public void onScrollChanged(ScrollType scrollType) {
if (scrollType == ScrollType.IDLE) {
//滑动停止
//判断是否是有内容
int childCount = getChildCount();
if (childCount == 0) {
return;
}
ViewGroup viewGroup = (ViewGroup) getChildAt(0);
autoScroll(viewGroup);
}
}
private void autoScroll(ViewGroup viewGroup) {
View middleView = getMiddleView(viewGroup);
//尝试将middleView显示在中央
int targetX = middleView.getLeft() - ((getWidth() - middleView.getWidth()) / 2);
//对targetX进行约束
targetX = Math.max(targetX, 0);
targetX = Math.min(viewGroup.getWidth() - getWidth(), targetX);
int dx = targetX-getScrollX();
smoothScrollBy(dx, 0);
}
private View getMiddleView(ViewGroup viewGroup) {
//获取view中心点距离HorizontalScrollView中心点最近的view
int hCenterX = getScrollX() + getWidth() / 2;
View middleView = null;
int minDistance = Integer.MAX_VALUE;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
int vCenterX = child.getLeft() + child.getWidth() / 2;
int distance = Math.abs(vCenterX - hCenterX);
if (distance < minDistance) {
middleView = child;
minDistance = distance;
}
}
return middleView;
}
};
}
和正常的HorizontalScrollView一样使用