ScrollView與SeekBar綁定實(shí)現(xiàn)滑動(dòng)時(shí)出現(xiàn)小滑塊效果
這是一項(xiàng)挺復(fù)雜的工作
重寫SeekBar
重寫ScroView
主工程
布局
SeekBar樣式修改
綁定SeekBar和ScrollView
監(jiān)聽ScrollView的滑動(dòng)狀態(tài)
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);//旋轉(zhuǎn) c.translate(0, -getWidth());//旋轉(zhuǎn),這兩行不可去掉 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("也許是在用這種方式告訴我,分開了就不要懷抱希望,現(xiàn)實(shí),夢(mèng)中都不能。\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);//滑動(dòng)停止后,自動(dòng)隱藏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; /** * 使用靜態(tài)方法來綁定邏輯,代碼可讀性更高。 */ 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) { //當(dāng)不是用戶操作,也就是ScrollView的滾動(dòng)隱射過來時(shí)不執(zhí)行操作 if (!fromUser) { // seekBar.setProgress(); //將拖動(dòng)的換百分比算成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(); } /*動(dòng)畫*/ public static final long DEFAULT_TIME_OUT = 10L; @Override public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) { showScroll(); //用戶拖動(dòng)SeekBar時(shí)不觸發(fā)ScrollView的回調(diào) if (isUserSeeking) { return; } //計(jì)算當(dāng)前滑動(dòng)位置相對(duì)于整個(gè)范圍的百分比,并映射到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() { } /*視圖參數(shù)*/ 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; } /* 單位轉(zhuǎn)換 */ 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數(shù)。你必須先調(diào)用該方法后再使用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數(shù)異常"); } if (count == 0) { handleLastMessage(msg); } } /*回調(diào)*/ protected abstract void handleLastMessage(Message msg); }
上圖
跟著屏幕的滑動(dòng)右邊的小點(diǎn)會(huì)跟著滑動(dòng),點(diǎn)擊滑動(dòng)右邊的小點(diǎn)可以控制屏幕的滑動(dòng),屏幕滑動(dòng)結(jié)束后,小點(diǎn)自動(dòng)隱藏。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android中實(shí)現(xiàn)監(jiān)聽ScrollView滑動(dòng)事件
- Android ScrollView滑動(dòng)實(shí)現(xiàn)仿QQ空間標(biāo)題欄漸變
- Android中ScrollView實(shí)現(xiàn)滑動(dòng)距離監(jiān)聽器的方法
- Android編程開發(fā)ScrollView中ViewPager無法正?;瑒?dòng)問題解決方法
- Android使用自定義控件HorizontalScrollView打造史上最簡單的側(cè)滑菜單
- Android中ScrollView 滑到頭部或尾部可伸縮放大效果
- Android中Toolbar隨著ScrollView滑動(dòng)透明度漸變效果實(shí)現(xiàn)
- ScrollView嵌套ListView滑動(dòng)沖突的解決方法
- android scrollview 滑動(dòng)到頂端或者指定位置的實(shí)現(xiàn)方法
- Android HorizontalScrollView左右滑動(dòng)效果
相關(guān)文章
Android使用selector修改TextView中字體顏色和背景色的方法
這篇文章主要介紹了Android使用selector修改TextView中字體顏色和背景色的方法,實(shí)例分析了selector方法的相關(guān)使用技巧,需要的朋友可以參考下2016-01-01android隱式意圖激活自定義界面和系統(tǒng)應(yīng)用界面的實(shí)例
下面小編就為大家?guī)硪黄猘ndroid隱式意圖激活自定義界面和系統(tǒng)應(yīng)用界面的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06Android為TextView添加字體庫和設(shè)置描邊的方法
本篇文章主要介紹了Android為TextView添加字體庫和設(shè)置描邊的方法,具有一定的參考價(jià)值,有興趣的可以了解一下2017-09-09Android 6.0區(qū)別U盤和SD卡設(shè)備的方法詳解
今天小編就為大家分享一篇Android 6.0區(qū)別U盤和SD卡設(shè)備的方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08詳解Android中使用Notification實(shí)現(xiàn)進(jìn)度通知欄(示例三)
這篇文章主要介紹了詳解Android中使用Notification實(shí)現(xiàn)進(jìn)度通知欄(示例三),具有一定的參考價(jià)值,有興趣的可以了解一下。2016-12-12Android中絕對(duì)音量和相對(duì)音量設(shè)置
大家好,本篇文章主要講的是Android中絕對(duì)音量和相對(duì)音量設(shè)置,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01解決Android SurfaceView繪制觸摸軌跡閃爍問題的方法
這篇文章主要為大家詳細(xì)介紹了解決Android SurfaceView繪制觸摸軌跡閃爍問題的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03Kotlin Service服務(wù)組件開發(fā)詳解
這幾天分析了一下的啟動(dòng)過程,于是乎,今天寫一下Service使用; 給我的感覺是它并不復(fù)雜,千萬不要被一坨一坨的代碼嚇住了,雖然彎彎繞繞不少,重載函數(shù)一個(gè)接著一個(gè),就向走迷宮一樣,但只要抓住主線閱讀,很快就能找到出口2022-12-12