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

来源:互联网 发布:新浪nba球员数据 编辑:程序博客网 时间:2024/06/01 08:57

这是一项挺复杂的工作

  • 重写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,主布局

<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);}

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

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

阅读全文
1 0
原创粉丝点击