栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android纵向的SeekBar(解决fromuser参数一直为false的问题)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android纵向的SeekBar(解决fromuser参数一直为false的问题)

package com.sidebar.pro.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ProgressBar;
import android.widget.SeekBar;

import com.sidebar.pro.R;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@SuppressLint("AppCompatCustomView")
public class VerticalSeekBar extends SeekBar {
    private static final String TAG = VerticalSeekBar.class.getSimpleName();

    public static final int ROTATION_ANGLE_CW_90 = 90;//从上到下
    public static final int ROTATION_ANGLE_CW_270 = 270;//从下到上

    private int mRotationAngle = ROTATION_ANGLE_CW_270;

    public VerticalSeekBar(Context context) {
        super(context);//注意是super 而不是调用其他构造函数
        initialize(context, null, 0, 0);
    }

    public VerticalSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context, attrs, 0, 0);
    }

    public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initialize(context, attrs, defStyle, 0);
    }

    private void initialize(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {

        if (attrs != null) {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalSeekBar, defStyleAttr, defStyleRes);
            final int rotationAngle = a.getInteger(R.styleable.VerticalSeekBar_seekBarRotation, 0);
            if (isValidRotationAngle(rotationAngle)) {
                mRotationAngle = rotationAngle;
            }
            a.recycle();
        }
    }

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

    protected void onDraw(Canvas c) {
        if (mRotationAngle == ROTATION_ANGLE_CW_270) {
            //从下到上
            c.rotate(270);
            c.translate(-getHeight(), 0);//注意旋转后需要移动才可显示出来
        } else if (mRotationAngle == ROTATION_ANGLE_CW_90) {
            //从上到下
            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:
                break;
            case MotionEvent.ACTION_MOVE:
                setPressed(true);//移动的时候设置按下效果,然后重新绘制thumb
                if (getThumb() != null) {
                    // This may be within the padding region.
                    invalidate(getThumb().getBounds());
                }
                calProgress(event);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                setPressed(false);//放手的时候取消按下效果,重新绘制thumb
                if (getThumb() != null) {
                    // This may be within the padding region.
                    invalidate(getThumb().getBounds());
                }
                calProgress(event);
                if (null != iUpEventListener) {
                    iUpEventListener.upEvent();
                }
                break;
        }
        return true;
    }

    private IUpEventListener iUpEventListener;

    public void setUpEvent(IUpEventListener iUpEventListener) {
        this.iUpEventListener = iUpEventListener;
    }

    public interface IUpEventListener {
        void upEvent();
    }

    private static boolean isValidRotationAngle(int angle) {
        return (angle == ROTATION_ANGLE_CW_90 || angle == ROTATION_ANGLE_CW_270);
    }

    //直接调用seekbar.setProgress()发现thumb图片位置一直不对,解决方法如下 重写setProgress
    @Override
    public void setProgress(int progress) {
        super.setProgress(progress);
        onSizeChanged(getWidth(), getHeight(), 0, 0);
    }


    //fromUser参数一直为false,利用反射
    private void reflectSetProgress(int progress) {
        //反射方法 boolean setProgressInternal(int progress, boolean fromUser, boolean animate)
        try {
            Class clazz = ProgressBar.class;
            Method method = clazz.getDeclaredMethod("setProgressInternal", int.class, boolean.class, boolean.class);
            method.setAccessible(true);
            method.invoke(this, progress, true, false);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private void calProgress(MotionEvent event) {
        if (mRotationAngle == ROTATION_ANGLE_CW_270) {
            //从下到上
            int progress = getMax() - (int) (event.getY() * (getMax() * 2 + 1) / (getHeight() * 2) + 0.5);
            Log.d(TAG, "set progress " + progress + " max " + getMax() + " getY " + event.getY() + " getHeight " + getHeight());
            progress = progress > 0 ? progress : 0;
            reflectSetProgress(progress);
        } else if (mRotationAngle == ROTATION_ANGLE_CW_90) {
            //从上到下
            reflectSetProgress((int) (getMax() * event.getY() / getHeight()));
        }
        onSizeChanged(getWidth(), getHeight(), 0, 0);
    }

}

第二份

package com.iflytek.myapplication.verticalsk;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import com.iflytek.myapplication.R;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@SuppressLint("AppCompatCustomView")
public class VerticalSeekBar extends SeekBar {
    private static final String TAG = VerticalSeekBar.class.getSimpleName();

    public static final int ROTATION_ANGLE_CW_90 = 90;//从上到下
    public static final int ROTATION_ANGLE_CW_270 = 270;//从下到上

    private int mRotationAngle = ROTATION_ANGLE_CW_270;

    public VerticalSeekBar(Context context) {
        super(context);//注意是super 而不是调用其他构造函数
        initialize(context, null, 0, 0);
    }

    public VerticalSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context, attrs, 0, 0);
    }

    public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initialize(context, attrs, defStyle, 0);
    }

    private void initialize(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {

        if (attrs != null) {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalSeekBar, defStyleAttr, defStyleRes);
            final int rotationAngle = a.getInteger(R.styleable.VerticalSeekBar_seekBarRotation, 0);
            if (isValidRotationAngle(rotationAngle)) {
                mRotationAngle = rotationAngle;
            }
            a.recycle();
        }
    }

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

    protected void onDraw(Canvas c) {
        if(mRotationAngle == ROTATION_ANGLE_CW_270) {
            //从下到上
            c.rotate(270);
            c.translate(-getHeight(), 0);//注意旋转后需要移动才可显示出来
        } else if(mRotationAngle == ROTATION_ANGLE_CW_90) {
            //从上到下
            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:
                break;
            case MotionEvent.ACTION_MOVE:
                setPressed(true);//移动的时候设置按下效果,然后重新绘制thumb
                if (getThumb() != null) {
                    // This may be within the padding region.
                    invalidate(getThumb().getBounds());
                }
                calProgress(event);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                setPressed(false);//放手的时候取消按下效果,重新绘制thumb
                if (getThumb() != null) {
                    // This may be within the padding region.
                    invalidate(getThumb().getBounds());
                }
                calProgress(event);
                break;
        }
        return true;
    }

    private static boolean isValidRotationAngle(int angle) {
        return (angle == ROTATION_ANGLE_CW_90 || angle == ROTATION_ANGLE_CW_270);
    }

    //直接调用seekbar.setProgress()发现thumb图片位置一直不对,解决方法如下 重写setProgress
    @Override
    public void setProgress(int progress) {
        super.setProgress(progress);
        onSizeChanged(getWidth(), getHeight(), 0, 0);
    }


    private void reflectSetProgress(int progress) {
        //反射方法 boolean setProgressInternal(int progress, boolean fromUser, boolean animate)
        try {
            Class clazz = ProgressBar.class;
            Method method = clazz.getDeclaredMethod("setProgressInternal",int.class,boolean.class,boolean.class);
            method.setAccessible(true);
            method.invoke(this,progress,true,false);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private void calProgress(MotionEvent event) {
        if(mRotationAngle == ROTATION_ANGLE_CW_270) {
            //从下到上
            int progress =  getMax() - (int)(event.getY()*(getMax()*2+1)/(getHeight()*2)+0.5);
            Log.d(TAG,"set progress "+progress + " max "+getMax() + " getY "+event.getY() +" getHeight "+getHeight());
            progress = progress>0?progress:0;
            reflectSetProgress(progress);
        } else if(mRotationAngle == ROTATION_ANGLE_CW_90) {
            //从上到下
            reflectSetProgress((int) (getMax() * event.getY() / getHeight()));
        }
        onSizeChanged(getWidth(), getHeight(), 0, 0);
    }
}

theme--styles


        
            
            
        
    

bg_seek_bar



    
    
    
        
            
            
        
    
    
    
        
            
                
                
            
        
    

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/318484.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号