这篇文章主要介绍ScrollView与SeekBar绑定如何实现滑动时出现小滑块效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
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、主布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="io.dcloud.H5B79C397.testActivity.Slider_Text">
<io.dcloud.H5B79C397.view.ObservableScrollView
android:id="@+id/scrollView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="15">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="asdfasdfasdfff" />
</io.dcloud.H5B79C397.view.ObservableScrollView >
<io.dcloud.H5B79C397.view.VerticalSeekbar
android:id="@+id/seekbar"
android:layout_width="0dp"
android:visibility="gone"
android:layout_height="match_parent"
android:layout_weight="1"
android:progressDrawable="@drawable/seek"
android:thumbTint="@color/green" />
</LinearLayout>
5、SeekBar样式
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dp"/>
<solid android:color="#FFFFFF"/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dp"/>
<solid android:color="#FFFFFF"/>
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dp"/>
<solid android:color="#FFFFFF" />
</shape>
</clip>
</item>
</layer-list>
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);
}
上图
跟着屏幕的滑动右边的小点会跟着滑动,点击滑动右边的小点可以控制屏幕的滑动,屏幕滑动结束后,小点自动隐藏。
以上是“ScrollView与SeekBar绑定如何实现滑动时出现小滑块效果”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。