Android自定义Seekbar有两个拇指查看问题

时间:2013-11-27 19:45:01

标签: android view android-fragments seekbar layout-inflater

我一直在使用this site

中的自定义Seekbar(带有两个拇指)

我已经对代码做了一些修改,以使其适应我的需要,并且更加模块化(拇指定位,绘图等)。我注意到创建活动时有点小问题。以下是我的问题的症状。

  1. 用于活动时(Android 4.0.3 - 华硕变压器)
    没有问题,100%工作
  2. 用于片段(Android 4.0.3 - 华硕变压器)时 灰色和蓝色(进度)线居中,拇指位于搜索栏框架的顶部。 (切一半)。它们仍在工作(从左到右滑动,中间有适当的进度线)
  3. 与#1相同的应用程序和活动(Android 4.2.2 - Galaxy Tab 3 10.1)
    两个拇指都在屏幕的中央,你无法移动它们。奇怪的是,当您选择一个并将其从一侧移动到另一侧时,将调用搜索条值更改的接口并返回正确的值。当您释放拇指的选择时,发送给侦听器的值将返回到中心值。
  4. 新应用程序中的空白活动(Android 4.2.2 - Galaxy Tab 3 10.1)
    搜索栏工作100%
  5. 在Android 4.3.1上使用Google Nexus 7 LTE(2013)的#1和#2行为相同 通过这些信息,我可以注意到,根据其中包含的“内容”的数量,行为会因活动而异。我很确定它与视图的测量有关。如果正确完成初始化,则可能会禁止整个Init()方法,从而覆盖在创建活动或片段中的所有视图期间调用的正确方法。
  6. 有什么想法吗?

    感谢您的帮助!

    这是完整的课程:

    public class SeekBarWithTwoThumb extends View {
    
    
        // ***************
        //     Members
        // ***************
    
    // Drawing resources
    private Bitmap thumb = BitmapFactory.decodeResource(getResources(),R.drawable.seek_thumb_normal);
    private Bitmap thumb_pressed = BitmapFactory.decodeResource(getResources(),R.drawable.seek_thumb_pressed);
    private Bitmap thumb_dissabled = BitmapFactory.decodeResource(getResources(),R.drawable.seek_thumb_dissabled);
    
    // Thumb's X coordinates and Y common coordinate
    private int thumb1X, thumb2X;
    private int thumbY;
    
    // Thumb's return values
    private int thumb1Value, thumb2Value;
    
    // Thumb's dimensions
    private int thumbHalfWidth;
    private int thumbWidth;
    
    // Selected thumb
    private int selectedThumb;
    private int lastSelectedThumb = 1;
    
    // Paint object and listener
    private Paint paint = new Paint();
    private SeekBarChangeListener scl;
    
    // Max value returned to listener
    private int maxValue = 100;
    
    // Thumb's enabled status
    private boolean thumb1Enabled = true;
    private boolean thumb2Enabled = false;
    
    // Before init happens (not drawn in UI)
    private boolean initDone = false;
    private int thumb1Xpreset = 0, thumb2Xpreset = 50;
    
    // ****************
    //   Constructors
    // ****************
    public SeekBarWithTwoThumb(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    public SeekBarWithTwoThumb(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public SeekBarWithTwoThumb(Context context) {
        super(context);
    }
    
    
    // ***************
    //    Overrides
    // ***************
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if ((widthMeasureSpec != 0) && (heightMeasureSpec != 0)) {
            init();
        }
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    
        // Print the gray line in the back
        paint.setStrokeWidth(1);
        paint.setColor(Color.GRAY);
        canvas.drawLine(thumbHalfWidth, getHeight() / 2, getWidth() - thumbHalfWidth, getHeight() / 2, paint);
    
        // Print the progress line according seekbar settings
        paint.setStrokeWidth(3);
        paint.setColor(0xFF33B5E5); // Hollow blue
        int drawThumbFirst = 0;     // Variable used declare which thumb will be drawn first
        if(thumb1Enabled && !thumb2Enabled) {
            canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb1X, getHeight() / 2, paint);
            drawThumbFirst = 2;
        } else if (!thumb1Enabled && thumb2Enabled){
            canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb2X, getHeight() / 2, paint);
            drawThumbFirst = 1;
        } else if (!thumb1Enabled && !thumb2Enabled) {
            // Do not draw, both are disabled
        } else if (selectedThumb == 1){
            canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb1X, getHeight() / 2, paint);
        } else if (selectedThumb == 2){
            canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb2X, getHeight() / 2, paint);
        } else if (lastSelectedThumb == 1){
            canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb1X, getHeight() / 2, paint);
        } else if (lastSelectedThumb == 2){
            canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb2X, getHeight() / 2, paint);
        }
    
        if (drawThumbFirst == 2){
            if (!thumb2Enabled) {
                canvas.drawBitmap(thumb_dissabled, thumb2X - thumbHalfWidth, thumbY,paint);
            } else if(selectedThumb == 2){
                canvas.drawBitmap(thumb_pressed, thumb2X - thumbHalfWidth, thumbY,paint);
            } else {
                canvas.drawBitmap(thumb, thumb2X - thumbHalfWidth, thumbY,paint);
            }
    
            if (!thumb1Enabled) {
                canvas.drawBitmap(thumb_dissabled, thumb1X - thumbHalfWidth, thumbY,paint);
            } else if(selectedThumb == 1){
                canvas.drawBitmap(thumb_pressed, thumb1X - thumbHalfWidth, thumbY,paint);
            } else {
                canvas.drawBitmap(thumb, thumb1X - thumbHalfWidth, thumbY,paint);
            }
        } else { // drawThumbFirst == 1 or 0 (0 has no importance since both thumbs either enabled or disabled)
            if (!thumb1Enabled) {
                canvas.drawBitmap(thumb_dissabled, thumb1X - thumbHalfWidth, thumbY,paint);
            } else if(selectedThumb == 1){
                canvas.drawBitmap(thumb_pressed, thumb1X - thumbHalfWidth, thumbY,paint);
            } else {
                canvas.drawBitmap(thumb, thumb1X - thumbHalfWidth, thumbY,paint);
            }
    
            if (!thumb2Enabled) {
                canvas.drawBitmap(thumb_dissabled, thumb2X - thumbHalfWidth, thumbY,paint);
            } else if(selectedThumb == 2){
                canvas.drawBitmap(thumb_pressed, thumb2X - thumbHalfWidth, thumbY,paint);
            } else {
                canvas.drawBitmap(thumb, thumb2X - thumbHalfWidth, thumbY,paint);
            }
        }
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Get X coordinate of event
        int mx = (int) event.getX();
    
        switch (event.getAction()) {
    
        // Check if one of the thumbs are selected
        case MotionEvent.ACTION_DOWN:
            if (mx >= thumb1X - thumbHalfWidth &&
                mx <= thumb1X + thumbHalfWidth &&
                thumb1Enabled) {
                selectedThumb = 1;
            } else if (mx >= thumb2X - thumbHalfWidth &&
                       mx <= thumb2X + thumbHalfWidth &&
                       thumb2Enabled) {
                selectedThumb = 2;
            }
            break;
    
        // If one of the thumbs are selected, move it
        case MotionEvent.ACTION_MOVE:
    
            // Prevent thumb to get out of frame
            if(mx < thumbHalfWidth){
                mx = thumbHalfWidth;
            } else if(mx > (getWidth() - thumbHalfWidth)) {
                mx = getWidth() - thumbHalfWidth;
            }
    
            // Move the selected thumb to location
            if (selectedThumb == 1) {
                thumb1X = mx;
            } else if (selectedThumb == 2) {
                thumb2X = mx;
            }
            break;
    
        // Remove selection, if any
        case MotionEvent.ACTION_UP:
            lastSelectedThumb = selectedThumb;
            selectedThumb = 0;
            break;
        }
    
        // Refresh
        invalidate();
    
        // Call listener if set
        if(scl != null){
            calculateThumbValue();
            scl.SeekBarValueChanged(thumb1Value,thumb2Value);
        }
        return true;
    }
    
    
    // ***************
    //     Methods
    // ***************
    private void init() {
        // Fix layout if thumb image is to big
        Log.d("Custom Seekbars", "Height: " + thumb.getHeight() + ", " + getHeight());
    
        if (thumb.getHeight() > getHeight()){
            getLayoutParams().height = thumb.getHeight();
        }
    
        // Set the thumb's dimensions
        thumbHalfWidth = thumb.getWidth()/2;
        thumbWidth = thumb.getWidth();
    
        // Set the thumb's coordinates
        float workingWidth = getWidth() - thumbWidth;
        float scale1 = ((float)(thumb1Xpreset))/((float)(maxValue));
        float scale2 = ((float)(thumb2Xpreset))/((float)(maxValue));
        thumb1X = Math.round((scale1*workingWidth) + thumbHalfWidth);
        thumb2X = Math.round((scale2*workingWidth) + thumbHalfWidth);
        thumbY = (getHeight() / 2) - (thumb.getHeight() / 2);
    
        initDone = true;
    
        // Refresh
        invalidate();
    }
    
    public void setSeekBarChangeListener(SeekBarChangeListener scl){
        this.scl = scl;
    }
    
    private void calculateThumbValue(){
        thumb1Value = getThumb1Value();
        thumb2Value = getThumb2Value();
    }
    
    public interface SeekBarChangeListener{
        void SeekBarValueChanged(int Thumb1Value,int Thumb2Value);
    }
    
    public void setMax(int maxValue){
        if(initDone){
            int thumb1val = getThumb1Value();
            int thumb2val = getThumb1Value();
            this.maxValue = maxValue;
            setThumbValues(thumb1val, thumb2val);
        } else {
            this.maxValue = maxValue;
        }
    }
    
    // Disable & enable methods
    public void setEnable(boolean value){
        thumb1Enabled = value;
        thumb2Enabled = value;
    }
    public void setDisable(boolean value){
        thumb1Enabled = !value;
        thumb2Enabled = !value;
    }
    public void setEnable(boolean thumb1, boolean thumb2){
        thumb1Enabled = thumb1;
        thumb2Enabled = thumb2;
    }
    public void setDisable(boolean thumb1, boolean thumb2){
        thumb1Enabled = !thumb1;
        thumb2Enabled = !thumb2;
    }
    
    // Thumb value setters and getters
    public void setThumbValues(int thumb1, int thumb2){
        if(initDone){
            if(thumb1 >= maxValue){
                thumb1X = getWidth() - thumbHalfWidth;
            } else if(thumb1 <= 0) {
                thumb1X = thumbHalfWidth;
            } else {
                float workingWidth = getWidth() - thumbWidth;
                float scale = ((float)(thumb1))/((float)(maxValue));
                thumb1X = Math.round((scale*workingWidth) + thumbHalfWidth);
            }
            if(thumb2 >= maxValue){
                thumb2X = getWidth() - thumbHalfWidth;
            } else if(thumb2 <= 0) {
                thumb2X = thumbHalfWidth;
            } else {
                float workingWidth = getWidth() - thumbWidth;
                float scale = ((float)(thumb2))/((float)(maxValue));
                thumb2X = Math.round((scale*workingWidth) + thumbHalfWidth);
            }
    
            // Refresh
            invalidate();
    
            // Call listener if set
            if(scl != null){
                calculateThumbValue();
                scl.SeekBarValueChanged(thumb1Value,thumb2Value);
            }
        } else {
            if(thumb1 >= maxValue){
                thumb1Xpreset = maxValue;
            } else if(thumb1 <= 0) {
                thumb1Xpreset = 0;
            } else {
                thumb1Xpreset = thumb1;
            }
    
            if(thumb2 >= maxValue){
                thumb2Xpreset = maxValue;
            } else if(thumb2 <= 0) {
                thumb2Xpreset = 0;
            } else {
                thumb2Xpreset = thumb2;
            }
        }
    }
    public void setThumb1Value(int value){
        if(initDone){
            if(value >= maxValue){
                thumb1X = getWidth() - thumbHalfWidth;
            } else if(value <= 0) {
                thumb1X = thumbHalfWidth;
            } else {
                float workingWidth = getWidth() - thumbWidth;
                float scale = ((float)(value))/((float)(maxValue));
                thumb1X = Math.round((scale*workingWidth) + thumbHalfWidth);
            }
    
            // Refresh
            invalidate();
    
            // Call listener if set
            if(scl != null){
                calculateThumbValue();
                scl.SeekBarValueChanged(thumb1Value,thumb2Value);
            }
        } else {
            if(value >= maxValue){
                thumb1Xpreset = maxValue;
            } else if(value <= 0) {
                thumb1Xpreset = 0;
            } else {
                thumb1Xpreset = value;
            }
        }
    }
    public void setThumb2Value(int value){
        if(initDone){
            if(value >= maxValue){
                thumb2X = getWidth() - thumbHalfWidth;
            } else if(value <= 0) {
                thumb2X = thumbHalfWidth;
            } else {
                float workingWidth = getWidth() - thumbWidth;
                float scale = ((float)(value))/((float)(maxValue));
                thumb2X = Math.round((scale*workingWidth) + thumbHalfWidth);
            }
    
            // Refresh
            invalidate();
    
            // Call listener if set
            if(scl != null){
                calculateThumbValue();
                scl.SeekBarValueChanged(thumb1Value,thumb2Value);
            }
        } else {
            if(value >= maxValue){
                thumb2Xpreset = maxValue;
            } else if(value <= 0) {
                thumb2Xpreset = 0;
            } else {
                thumb2Xpreset = value;
            }
        }
    }
    public int getThumb1Value(){
        if(initDone){
            float workingWidth = getWidth() - thumbWidth;
            return Math.round((float)maxValue * ((float)(thumb1X - thumbHalfWidth)/workingWidth));
        } else {
            return thumb1Xpreset;
        }
    }
    public int getThumb2Value(){
        if(initDone){
            float workingWidth = getWidth() - thumbWidth;
            return Math.round((float)maxValue * ((float)(thumb2X - thumbHalfWidth)/workingWidth));
        } else {
            return thumb2Xpreset;
        }
    }
    
    }
    

0 个答案:

没有答案