ScrollView与SeekBar绑定实现滑动时出现小滑块效果

这篇文章主要为大家详细介绍了ScrollView与SeekBar绑定实现滑动时出现小滑块效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

这是一项挺复杂的工作

重写SeekBar
重写ScroView
主工程
布局
SeekBar样式修改
绑定SeekBar和ScrollView
监听ScrollView的滑动状态

1、重写SeekBar

 public class VerticalSeekbar extends SeekBar { public VerticalSeekbar(Context context) { super(context); } public VerticalSeekbar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public VerticalSeekbar(Context context, AttributeSet attrs) { super(context, attrs); } protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(h, w, oldh, oldw); } @Override public synchronized void setProgress(int progress) // it is necessary for calling setProgress on click of a button { super.setProgress(progress); onSizeChanged(getWidth(), getHeight(), 0, 0); } @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); } protected void onDraw(Canvas c) { c.rotate(90);//旋转 c.translate(0, -getWidth());//旋转,这两行不可去掉 super.onDraw(c); } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_UP: setProgress((int) (getMax() * event.getY() / getHeight())); onSizeChanged(getWidth(), getHeight(), 0, 0); break; case MotionEvent.ACTION_CANCEL: break; } return true; } } 

2、重写SccrollView

 public class ObservableScrollView extends ScrollView { public ScrollViewListener scrollViewListener = null; public ObservableScrollView (Context context) { super(context); } public ObservableScrollView (Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public interface ScrollViewListener { void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy); } public ObservableScrollView (Context context, AttributeSet attrs) { super(context, attrs); } public void setScrollViewListener(ScrollViewListener scrollViewListener) { this.scrollViewListener = scrollViewListener; } @Override public void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (scrollViewListener != null) { scrollViewListener.onScrollChanged(this, x, y, oldx, oldy); } } } 

3、主工程

 public class Slider_Text extends Activity { private TextView textView; private Context context=this; private Scroller scroller; private ScrollBindHelper scrollBindHelper; private VerticalSeekbar seekBar; private ObservableScrollView scrollView; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_slider__text); scroller=new Scroller(context); textView=(TextView)findViewById(R.id.text); textView.setText("也许是在用这种方式告诉我,分开了就不要怀抱希望,现实,梦中都不能。\n" + "\n" + "  了,那些无处安放的情感就让它各自归位,你别来,"); seekBar = (VerticalSeekbar) findViewById(R.id.seekbar); scrollView = (ObservableScrollView) findViewById(R.id.scrollView); scrollBindHelper=new ScrollBindHelper(seekBar,scrollView); scrollBindHelper.bind(seekBar,scrollView); scrollView.setOnTouchListener(new View.OnTouchListener() { private int lastY = 0; private int touchEventId = -9983761; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); View scroller = (View) msg.obj; if (msg.what == touchEventId) { if (lastY == scroller.getScrollY()) { handleStop(scroller); } else { handler.sendMessageDelayed(handler.obtainMessage(touchEventId, scroller), 5); lastY = scroller.getScrollY(); } } } }; public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { handler.sendMessageDelayed(handler.obtainMessage(touchEventId, v), 5); } return false; } //处理真正的事件 private void handleStop(Object view) { ScrollView scroller = (ScrollView) view; int scrollY = scroller.getScrollY(); System.out.println("scrollY"+scrollY); seekBar.setVisibility(View.GONE);//滑动停止后,自动隐藏seekbar } }); } } 

4、主布局

  

5、SeekBar样式

          

6、绑定SeekBar和ScrollView

 public class ScrollBindHelper implements SeekBar.OnSeekBarChangeListener,ObservableScrollView.ScrollViewListener{ private final VerticalSeekbar seekBar; private final ObservableScrollView scrollView; private final View scrollContent; /** * 使用静态方法来绑定逻辑,代码可读性更高。 */ public ScrollBindHelper(VerticalSeekbar seekBar, ObservableScrollView scrollView) { this.seekBar = seekBar; this.scrollView = scrollView; this.scrollContent = scrollView.getChildAt(0); // System.out.println("scrollContent------->"+scrollView.getChildAt(0)); } /*继承*/ private boolean isUserSeeking; private int getContentRange() { seekBar.setMax(scrollContent.getHeight() - scrollView.getHeight()); int Range=scrollView.getScrollY(); //System.out.println("content----->"+Range); return Range; } private int getScrollRange() { System.out.println(scrollContent.getHeight() - scrollView.getHeight()); return scrollContent.getHeight() - scrollView.getHeight(); } public ScrollBindHelper bind(VerticalSeekbar seekBar, ObservableScrollView scrollView) { //初始化工具类 ViewUtil.init(seekBar.getContext().getApplicationContext()); ScrollBindHelper helper = new ScrollBindHelper(seekBar, scrollView); seekBar.setOnSeekBarChangeListener(helper); scrollView.setScrollViewListener(helper); return helper; } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { //当不是用户操作,也就是ScrollView的滚动隐射过来时不执行操作 if (!fromUser) { // seekBar.setProgress(); //将拖动的换百分比算成Y值,并映射到SrollView上。 int range=getContentRange(); scrollView.scrollTo(0, progress); //  System.out.println("scroll----"+progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { isUserSeeking = true; handler.clearAll(); } @Override public void onStopTrackingTouch(SeekBar seekBar) { isUserSeeking = false; handler.reset(); } /*动画*/ public static final long DEFAULT_TIME_OUT = 10L; @Override public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) { showScroll(); //用户拖动SeekBar时不触发ScrollView的回调 if (isUserSeeking) { return; } //计算当前滑动位置相对于整个范围的百分比,并映射到SeekBar上 int range = getContentRange(); seekBar.setProgress(range != 0 ? range : 0); //System.out.println("seekBar------"+ range); } private static class VisibleHandler extends LastMsgHandler { private ScrollBindHelper helper; public VisibleHandler(ScrollBindHelper helper) { this.helper = helper; } public void reset() { sendMsgDelayed(DEFAULT_TIME_OUT); } @Override protected void handleLastMessage(Message msg) { helper.hideScroll(); } } private VisibleHandler handler = new VisibleHandler(this); private void hideScroll() { seekBar.setVisibility(View.GONE); } private void showScroll() { seekBar.setVisibility(View.VISIBLE); } } 

7、工具类

 public class ViewUtil { private ViewUtil() { } /*视图参数*/ private static float density; private static float scaledDensity; private static int widthPixels; private static int heightPixels; private static boolean isInit = false; private static void confirmInit() { if (!isInit) { throw new IllegalStateException("ViewUtil还未初始化"); } } public static void init(Context context) { if (isInit) { return; } DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); density = displayMetrics.density; scaledDensity = displayMetrics.scaledDensity; widthPixels = displayMetrics.widthPixels; heightPixels = displayMetrics.heightPixels; isInit = true; } public static float getDisplayMetricsDensity() { confirmInit(); return density; } public static float getDisplayMetricsScaledDensity() { confirmInit(); return scaledDensity; } public static int getScreenWidthPx() { confirmInit(); return widthPixels; } public static int getScreenHeightPx() { confirmInit(); return heightPixels; } /* 单位转换 */ public static int dpToPx(float dpValue) { confirmInit(); return (int) (dpValue * getDisplayMetricsDensity() + 0.5F); } public static int pxToDp(float pxValue) { confirmInit(); return (int) (pxValue / getDisplayMetricsDensity() + 0.5F); } public static int pxToSp(float pxValue) { confirmInit(); return (int) (pxValue / getDisplayMetricsScaledDensity() + 0.5f); } public static int spToPx(float spValue) { confirmInit(); return (int) (spValue * getDisplayMetricsScaledDensity() + 0.5f); } } 

8、线程工具

 public abstract class LastMsgHandler extends android.os.Handler { private int count = 0; /** * 增加Count数。你必须先调用该方法后再使用sendMessageXXX */ public synchronized final void increaseCount() { count++; } public final void sendMsg() { sendMsgDelayed(0); } public final void sendMsgDelayed(long delay) { increaseCount(); if (delay <= 0) { sendEmptyMessage(0); } else { sendEmptyMessageDelayed(0, delay); } } public synchronized final void clearAll() { count = 0; removeCallbacksAndMessages(null); } @Override public synchronized final void handleMessage(Message msg) { super.handleMessage(msg); count--; if (count <0) { throw new IllegalStateException("count数异常"); } if (count == 0) { handleLastMessage(msg); } } /*回调*/ protected abstract void handleLastMessage(Message msg); } 

上图


跟着屏幕的滑动右边的小点会跟着滑动,点击滑动右边的小点可以控制屏幕的滑动,屏幕滑动结束后,小点自动隐藏。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持html中文网。

以上就是ScrollView与SeekBar绑定实现滑动时出现小滑块效果的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 移动