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上查看,别忘了给个星 点击进入
转载请注明出处相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories