我想要实现的是制作弧形的搜索栏。我知道有很多库可以用来实现这一点,但我只是尝试自定义视图。 我遇到了几个问题:
我有一个扩展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);
}
}
这是我的布局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>
eclipse adt究竟出了什么问题?如何使用onDraw方法为该搜索栏赋予形状?
答案 0 :(得分:6)
绘制任何形状的ProgressBar非常简单。使用SeekBar你会有一些复杂性,因为你必须实现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());
}
}
当然,您可以并且您应该使所有内容都可配置,使用构造函数,或者使用一些开头和结束角度,包含矩形的尺寸,笔划宽度,颜色等等。
另外,请注意,弧从0绘制到getProgress,这个数字是相对于x轴的一个角度,随着时间的推移逐渐增长,因此,如果从0到90度,它将是:
当然你可以改变这个:canvas.drawArc得到任何数字作为一个角度,它不被视为模块360,但你可以做数学并让它以你想要的任何点开始和结束。
在我的例子中,开始时钟是9,而时钟是3,它需要180度。
更新
我将正在运行的示例上传到github