定制的弧形导杆

Mav*_*ick 3 eclipse android seekbar android-custom-view eclipse-adt

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

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

    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);
        }
    
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

这是我的布局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>
Run Code Online (Sandbox Code Playgroud)
  1. 如果我使用画布类绘制弧形或任何形状,那么这是一个很好的起点吗?

eclipse adt究竟出了什么问题?如何使用onDraw方法为该搜索栏赋予形状?

Car*_*les 6

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

  1. 划清界线
  2. 如果你愿意,画出可拖动的拇指.
  3. 处理用户交互

您必须将其视为在矩形内绘制的弧.所以第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());

    }

 }
Run Code Online (Sandbox Code Playgroud)

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

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

右下角的一个圆圈

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

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

UPDATE

我上传了一个运行的例子给github