• Android 垂直SeekBar


      

      Android自带的SeekBar是水平的,要垂直的,必须自己写一个类,继承SeekBar。

    一个简单的垂直SeekBar的例子

      (但是它其实是存在一些问题的。不过要是满足基本需要还是可以凑合的)

    package com.example.helloverticalseekbar;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.widget.SeekBar;
    
    public class VerticalSeekBar extends SeekBar
    {
    
        public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
        }
    
        public VerticalSeekBar(Context context, AttributeSet attrs)
        {
            super(context, attrs);
        }
    
        public VerticalSeekBar(Context context)
        {
            super(context);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh)
        {
            super.onSizeChanged(h, w, oldh, oldw);
        }
    
        @Override
        protected synchronized void onMeasure(int widthMeasureSpec,
                int heightMeasureSpec)
        {
            super.onMeasure(heightMeasureSpec, widthMeasureSpec);
            setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
        }
    
        @Override
        protected synchronized void onDraw(Canvas canvas)
        {
            canvas.rotate(-90);
            canvas.translate(-getHeight(), 0);
            super.onDraw(canvas);
        }
    
        @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(getMax()
                            - (int) (getMax() * event.getY() / getHeight()));
                    onSizeChanged(getWidth(), getHeight(), 0, 0);
                    break;
    
                case MotionEvent.ACTION_CANCEL:
                    break;
            }
    
            return true;
        }
    
    }

      Demo中加上一个水平SeekBar作为对比,代码如下:

    Activity:

    HelloSeekBarActivity
    package com.example.helloverticalseekbar;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.util.Log;
    import android.view.Menu;
    import android.widget.SeekBar;
    import android.widget.TextView;
    import android.widget.SeekBar.OnSeekBarChangeListener;
    
    public class HelloSeekBarActivity extends Activity
    {
        private SeekBar horiSeekBar = null;    
        private TextView horiText = null;
        
        private VerticalSeekBar verticalSeekBar = null;
        private TextView verticalText = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            Log.d(AppConstants.LOG_TAG, "onCreate");
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_hello_seek_bar);
            
            horiSeekBar = (SeekBar) findViewById(R.id.horiSeekBar);
            horiText = (TextView)findViewById(R.id.horiText);        
            horiSeekBar.setOnSeekBarChangeListener(horiSeekBarListener);
            
            verticalSeekBar = (VerticalSeekBar)findViewById(R.id.verticalSeekBar);
            verticalText = (TextView)findViewById(R.id.verticalText);
            verticalSeekBar.setOnSeekBarChangeListener(verticalSeekBarChangeListener);
        
            
            
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu)
        {
            getMenuInflater().inflate(R.menu.hello_seek_bar, menu);
            return true;
        }
        
        
        private OnSeekBarChangeListener horiSeekBarListener = new OnSeekBarChangeListener()
        {
            
            @Override
            public void onStopTrackingTouch(SeekBar seekBar)
            {
                
            }
            
            @Override
            public void onStartTrackingTouch(SeekBar seekBar)
            {
                
            }
            
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser)
            {
                Log.d(AppConstants.LOG_TAG, "Horizontal SeekBar --> onProgressChanged");
                horiText.setText(Integer.toString(progress));
                
            }
        };
        
        private OnSeekBarChangeListener verticalSeekBarChangeListener = new OnSeekBarChangeListener()
        {
            
            @Override
            public void onStopTrackingTouch(SeekBar seekBar)
            {
                
            }
            
            @Override
            public void onStartTrackingTouch(SeekBar seekBar)
            {
                
            }
            
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser)
            {
                Log.d(AppConstants.LOG_TAG, "Vertical SeekBar --> onProgressChanged");
                verticalText.setText(Integer.toString(progress));
                
            }
        };
    
    }

    布局:

    activity_hello_seek_bar.xml
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".HelloSeekBarActivity" >
    
        <TextView
            android:id="@+id/myTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:text="@string/hello_world" />
    
        <SeekBar
            android:id="@+id/horiSeekBar"
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:layout_below="@id/myTextView" />
    
        <TextView
            android:id="@+id/horiText"
            android:layout_width="wrap_content"
            android:layout_height="20dp"
            android:layout_below="@id/horiSeekBar"
            android:text="horizontal" />
    
        <com.example.helloverticalseekbar.VerticalSeekBar
            android:id="@+id/verticalSeekBar"
            android:layout_width="wrap_content"
            android:layout_height="200dp"
            android:layout_below="@id/horiText" />
    
        <TextView
            android:id="@+id/verticalText"
            android:layout_width="wrap_content"
            android:layout_height="20dp"
            android:layout_below="@id/verticalSeekBar"
            android:text="vertical" />
    
    </RelativeLayout>

    运行截图:

     

    一个改进版的SeekBar

      

    package com.example.helloverticalseekbarv2;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.view.ViewGroup;
    import android.view.ViewParent;
    import android.widget.SeekBar;
    
    public class VerticalSeekBar extends SeekBar
    {
        private boolean mIsDragging;
        private float mTouchDownY;
        private int mScaledTouchSlop;
        private boolean isInScrollingContainer = false;
    
        public boolean isInScrollingContainer()
        {
            return isInScrollingContainer;
        }
    
        public void setInScrollingContainer(boolean isInScrollingContainer)
        {
            this.isInScrollingContainer = isInScrollingContainer;
        }
    
        /**
         * On touch, this offset plus the scaled value from the position of the
         * touch will form the progress value. Usually 0.
         */
        float mTouchProgressOffset;
    
        public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
            mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    
        }
    
        public VerticalSeekBar(Context context, AttributeSet attrs)
        {
            super(context, attrs);
        }
    
        public VerticalSeekBar(Context context)
        {
            super(context);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh)
        {
    
            super.onSizeChanged(h, w, oldh, oldw);
    
        }
    
        @Override
        protected synchronized void onMeasure(int widthMeasureSpec,
                int heightMeasureSpec)
        {
            super.onMeasure(heightMeasureSpec, widthMeasureSpec);
            setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
        }
    
        @Override
        protected synchronized void onDraw(Canvas canvas)
        {
            canvas.rotate(-90);
            canvas.translate(-getHeight(), 0);
            super.onDraw(canvas);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
            if (!isEnabled())
            {
                return false;
            }
    
            switch (event.getAction())
            {
                case MotionEvent.ACTION_DOWN:
                    if (isInScrollingContainer())
                    {
    
                        mTouchDownY = event.getY();
                    }
                    else
                    {
                        setPressed(true);
    
                        invalidate();
                        onStartTrackingTouch();
                        trackTouchEvent(event);
                        attemptClaimDrag();
    
                        onSizeChanged(getWidth(), getHeight(), 0, 0);
                    }
                    break;
    
                case MotionEvent.ACTION_MOVE:
                    if (mIsDragging)
                    {
                        trackTouchEvent(event);
    
                    }
                    else
                    {
                        final float y = event.getY();
                        if (Math.abs(y - mTouchDownY) > mScaledTouchSlop)
                        {
                            setPressed(true);
    
                            invalidate();
                            onStartTrackingTouch();
                            trackTouchEvent(event);
                            attemptClaimDrag();
    
                        }
                    }
                    onSizeChanged(getWidth(), getHeight(), 0, 0);
                    break;
    
                case MotionEvent.ACTION_UP:
                    if (mIsDragging)
                    {
                        trackTouchEvent(event);
                        onStopTrackingTouch();
                        setPressed(false);
    
                    }
                    else
                    {
                        // Touch up when we never crossed the touch slop threshold
                        // should
                        // be interpreted as a tap-seek to that location.
                        onStartTrackingTouch();
                        trackTouchEvent(event);
                        onStopTrackingTouch();
    
                    }
                    onSizeChanged(getWidth(), getHeight(), 0, 0);
                    // ProgressBar doesn't know to repaint the thumb drawable
                    // in its inactive state when the touch stops (because the
                    // value has not apparently changed)
                    invalidate();
                    break;
            }
            return true;
    
        }
    
        private void trackTouchEvent(MotionEvent event)
        {
            final int height = getHeight();
            final int top = getPaddingTop();
            final int bottom = getPaddingBottom();
            final int available = height - top - bottom;
    
            int y = (int) event.getY();
    
            float scale;
            float progress = 0;
    
            // 下面是最小值
            if (y > height - bottom)
            {
                scale = 0.0f;
            }
            else if (y < top)
            {
                scale = 1.0f;
            }
            else
            {
                scale = (float) (available - y + top) / (float) available;
                progress = mTouchProgressOffset;
            }
    
            final int max = getMax();
            progress += scale * max;
    
            setProgress((int) progress);
    
        }
    
        /**
         * This is called when the user has started touching this widget.
         */
        void onStartTrackingTouch()
        {
            mIsDragging = true;
        }
    
        /**
         * This is called when the user either releases his touch or the touch is
         * canceled.
         */
        void onStopTrackingTouch()
        {
            mIsDragging = false;
        }
    
        private void attemptClaimDrag()
        {
            ViewParent p = getParent();
            if (p != null)
            {
                p.requestDisallowInterceptTouchEvent(true);
            }
        }
    
        @Override
        public synchronized void setProgress(int progress)
        {
    
            super.setProgress(progress);
            onSizeChanged(getWidth(), getHeight(), 0, 0);
    
        }
    
    }
  • 相关阅读:
    CSS清除浮动的方法
    JS获取元素属性、样式getComputedStyle()和currentStyle方法兼容性问题
    数据类型真假的问题
    数据类型——方法总结(可能有不对的)
    attr()与setAttribute()的区别
    wampserver 2.5多站点配置
    php常用函数(持续中)
    php中环境变量
    编码转换
    php中rsa加密及解密和签名及验签
  • 原文地址:https://www.cnblogs.com/mengdd/p/3008482.html
Copyright © 2020-2023  润新知