定制的弧形导杆

时间:2014-01-02 14:15:39

标签: android eclipse android-custom-view seekbar eclipse-adt

我想要实现的是制作弧形的搜索栏。我知道有很多库可以用来实现这一点,但我只是尝试自定义视图。 我遇到了几个问题:

  1. 我有一个扩展SeekBar的类,我也实现了onDraw和onMeasure方法,但我无法在eclipse的布局编辑器中查看,这里是自定义视图类的代码: / p>

    package com.custom.android.views;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.Path.Direction;
    import android.graphics.PathMeasure;
    
    
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    import android.widget.SeekBar;
    import android.widget.Toast;
    
    
    
    public class CustomSeekBar extends SeekBar {
    
        public CustomSeekBar(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
    
        }
    
        public CustomSeekBar(Context context, AttributeSet attrs) {
            this(context, attrs,0);
    
        }
    
        public CustomSeekBar(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
    
        }
    
        @Override
        public void draw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.draw(canvas);
        }
    
        @Override
        protected synchronized void onMeasure(int widthMeasureSpec,
                int heightMeasureSpec) {
            // TODO Auto-generated method stub
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
    
    }
    
  2. 这是我的布局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=".MainActivity" >
    
        <com.custom.android.views.CustomSeekBar
             android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/seekBar"/>
    
    </RelativeLayout>
    
    1. 如果我使用画布类绘制弧形或任何形状,那么这是一个很好的起点吗?
    2. eclipse adt究竟出了什么问题?如何使用onDraw方法为该搜索栏赋予形状?

1 个答案:

答案 0 :(得分:6)

绘制任何形状的ProgressBar非常简单。使用SeekBar你会有一些复杂性,因为你必须实现3个不同的东西:

  1. 画线
  2. 如果你愿意,可以画出可拖动的拇指。
  3. 处理用户互动
  4. 您必须将其视为在矩形内绘制的弧。所以第3点可能很简单:只需让用户在水平线上移动手指,或者在弧线上移动手指,但只考虑触摸事件的x坐标。简而言之,这是什么意思?好的,好消息:你不必做任何事情,因为这是基础SeekBar的正常行为。

    对于第二点,您可以为处理程序选择一个图像,并使用一些小数学将其写入相应的位置。或者你可以忘记知道的处理程序,只需将搜索栏绘制为代表完整轨道的线,并在其上绘制另一条代表进度的线。当你有这个工作时,如果你想要你可以添加处理程序。

    第一点,这是主要的一点,但并不难实现。您可以使用以下代码:

    更新:我在代码中做了一些改进

    public class ArcSeekBar extends SeekBar {
    
    
        public ArcSeekBar(Context context, AttributeSet attrs) {
                super(context, attrs);
    
        }
    
        public ArcSeekBar(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
    
        }
    
        private Paint mBasePaint;
        private Paint mProgressPaint;
        private RectF mOval = new RectF(5, 5, 550, 550);
        private int defaultmax = 180;
        private int startAngle=180;
        private int strokeWidth=10;
    
        private int trackColor=0xFF000000;
        private int progressColor=0xFFFF0000;
    
    
    
        public void setOval(RectF mOval) {
                this.mOval = mOval;
        }
    
    
    
        public void setStartAngle(int startAngle) {
                this.startAngle = startAngle;
        }
    
        public void setStrokeWidth(int strokeWidth) {
                this.strokeWidth = strokeWidth;
        }
    
        public void setTrackColor(int trackColor) {
                this.trackColor = trackColor;
        }
    
        public void setProgressColor(int progressColor) {
                this.progressColor = progressColor;
        }
    
        public ArcSeekBar(Context context) {
                super(context);
                mBasePaint = new Paint();
                mBasePaint.setAntiAlias(true);
                mBasePaint.setColor(trackColor);
                mBasePaint.setStrokeWidth(strokeWidth);
                mBasePaint.setStyle(Paint.Style.STROKE);
    
                mProgressPaint = new Paint();
                mProgressPaint.setAntiAlias(true);
                mProgressPaint.setColor(progressColor);
                mProgressPaint.setStrokeWidth(strokeWidth);
                mProgressPaint.setStyle(Paint.Style.STROKE);
    
                setMax(defaultmax);// degrees
    
    
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
                canvas.drawArc(mOval, startAngle, getMax(), false, mBasePaint);
                canvas.drawArc(mOval, startAngle, getProgress(), false, mProgressPaint);
                invalidate();
                //Log.i("ARC", getProgress()+"/"+getMax());
    
        }
    
     }
    

    当然,您可以并且您应该使所有内容都可配置,使用构造函数,或者使用一些开头和结束角度,包含矩形的尺寸,笔划宽度,颜色等等。

    另外,请注意,弧从0绘制到getProgress,这个数字是相对于x轴的一个角度,随着时间的推移逐渐增长,因此,如果从0到90度,它将是:

    bottom-right cuarter of a circle

    当然你可以改变这个:canvas.drawArc得到任何数字作为一个角度,它不被视为模块360,但你可以做数学并让它以你想要的任何点开始和结束。

    在我的例子中,开始时钟是9,而时钟是3,它需要180度。

    更新

    我将正在运行的示例上传到github