您的位置:首页 > 移动开发 > Android开发

Android Custom View --- Continuous Slider(连续滑动器)

2015-09-27 19:46 465 查看

Android Custom View — Continuous slider

先上一张Continuous slider的图片吧



官方链接

先从最简单的开始实现

在实现的过程中,我是将圆形和线分成两个View来实现,包括进一个ViewGroup里

第一步我们先定义大体框架,如下

public class Continuousslider extends ViewGroup {
public Continuousslider(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {

}

class Line extends View {

public Line(Context context) {
super(context);
}
}

class Circle extends View {

public Circle(Context context) {
super(context);
}
}

}


接下来我们绘制 Circle 和 Line,在这儿只贴出Circle的代码了,Line 的代码可以去github上看,网址会在文末放出

class Circle extends View {
Paint paint;
float x;//x轴坐标
public void moveto(float x){
this.x=x;
invalidate();
}

public Circle(Context context) {
super(context);
paint=new Paint();
paint.setColor(getResources().getColor(R.color.blue));
paint.setStyle(Paint.Style.FILL);
x=getLeft()+20;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(x>getRight()-20)x=getRight()-20;
else if(x<=getLeft()+20) {//超出左边界时加以限制,并设置灰色
x = getLeft() + 20;
paint.setColor(getResources().getColor(R.color.gray));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
}else{
paint.setColor(getResources().getColor(R.color.blue));
paint.setStyle(Paint.Style.FILL);

}
canvas.drawCircle(x, (getTop()+getBottom())/2 , 15, paint);
}

}


定义好了Line后我们就要来完善 Continuousslider 了,这一步就是简单的把 Circle 和 Line 添加进 Continuousslider ,并且计算一下大小, 很简单

Line line;
Circle circle;
public Continuousslider(Context context) {
super(context);
init();
}
public Continuousslider(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
void init(){
line=new Line(getContext());
circle=new Circle(getContext());
addView(line);
addView(circle);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
float xpad = (float) (getPaddingLeft() + getPaddingRight());
float ypad = (float) (getPaddingTop() + getPaddingBottom());
float ww = (float) w - xpad;
float hh = (float) h - ypad;
circle.layout(0, 0, (int) ww, (int) hh);
line.layout(0, 0, (int) ww, (int) hh);
}


现在我们得到了这样的一个东西



但是它对我们的拖动还不会有任何的响应,所以接下来的一步就是添加点击事件了

@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d("AAA",event.toString());
if(event.getAction()==MotionEvent.ACTION_MOVE||event.getAction()==MotionEvent.ACTION_UP||
event.getAction()==MotionEvent.ACTION_DOWN
){
moveto(event.getX());
return true;
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}

void moveto(float x){
line.moveto(x);
circle.moveto(x);
}


这儿的moveto就是移动组件的代码,接下来会给出。

Circle 和 Line 的moveto()都很简单,只需要改变一下横坐标值,然后重新绘制一下就行了

public void moveto(float x){
this.x=x;
invalidate();
}


现在我们已经基本实现了拖动的功能了


;

但是感觉这样有点儿单调,我们希望可以给它加一点动画效果,让它看起来更酷炫,就像第一张图里的focus那样

我们采用了ValueAnimator来实现Circle 的动画效果,先上代码

class Circle extends View implements ValueAnimator.AnimatorUpdateListener{
Paint paint;
Paint bg;//透明外圈
float x;
int radius;
int radius2;//外圈半径
boolean temp;//temp 为true则圆圈变大,否则变小
ValueAnimator animator;
public void moveto(float x){ this.x=x; invalidate(); }
public Circle(Context context) {
super(context);
paint=new Paint();
paint.setColor(getResources().getColor(R.color.blue));
bg=new Paint();
bg.setStyle(Paint.Style.FILL);
bg.setColor(getResources().getColor(R.color.blue));
bg.setAlpha(26);
paint.setStyle(Paint.Style.FILL);
x=getLeft()+20;
radius=15;
radius2=15;
animator=new ValueAnimator();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(x>getRight()-30)x=getRight()-30;
else if(x<=getLeft()+30) {
x = getLeft() + 30;
paint.setColor(getResources().getColor(R.color.gray));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
bg.setColor(getResources().getColor(R.color.gray));
bg.setAlpha(80);
}else{
paint.setColor(getResources().getColor(R.color.blue));
paint.setStyle(Paint.Style.FILL);
bg.setColor(getResources().getColor(R.color.blue));
bg.setAlpha(80);
}
canvas.drawCircle(x, (getTop()+getBottom())/2 , radius2, bg);
canvas.drawCircle(x, (getTop()+getBottom())/2 , radius, paint);
}
public void scalel() {
temp=true;
}
public void scales() {
temp=false;
}
public void startAnimation(int duration){
ValueAnimator v=ValueAnimator.ofInt(0,100);
v.setStartDelay(0);
v.setDuration(duration);
v.addUpdateListener(this);
v.start();
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int test = (int) animation.getAnimatedValue();//0-100中的一个数字,会不断的增加,进行重新绘制
if(temp){
radius=15+(15*test)/100;
radius2=15+(35*test)/100;
}else{
radius2=50-(35*test)/100;
radius=30-(15*test)/100;
}
invalidate();
}
}


在Continuousslider中调用 startAnimation方法

circle.startAnimation(200);


好了,到此所有的工作都完成了,我们已经实现了想要的结果





源码可以到我的github上查看,别忘了给个星 点击进入

转载请注明出处
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android ui