当前位置:   article > 正文

android 自定义view,绘制与onTouchEvent事件(一)_android canvas.drawrect 点击事件

android canvas.drawrect 点击事件

绘制

构造方法

自定义view需要继承View类,重写两个构造方法

  1. //用在代码new该view对象,初始化
  2. public MyView(Context context) {
  3. super(context);
  4. init();
  5. }
  6. //一般添加构造---》view放进布局,系统实例化
  7. public MyView(Context context, AttributeSet attrs) {
  8. super(context, attrs);
  9. init();
  10. }

Paint对象

绘制view需要使用Paint对象,相当于画笔。初始化需要给这个画笔设置一些属性。



对Paint实例化,注释写的很清楚了,有三个常用的初始化方法:

  1. private void init() {
  2. paint=new Paint();
  3. //设置画笔的颜色
  4. paint.setColor(Color.GREEN);
  5. //抗锯齿,画图质量提高
  6. paint.setAntiAlias(true);
  7. //设置画笔样式,空心
  8. paint.setStyle(Style.STROKE);
  9. }

重写onDraw()

常用图像绘制

 要画图形,最起码要有三个对象:
1.颜色对象 Color
  2.画笔对象 Paint
  3.画布对象 Canvas


为了绘制自定义View,需要重写onDraw()方法,参数:(Canvas canvas)是个画布对象,就是在这个canvas绘制的。

以下展示了绘制矩形,圆形,文本,图片,直线,弧线的过程,其中弧线的绘制过程依赖于矩形,这个有点有别于其他的。


  1. //声明矩形对象(为了绘制弧线)
  2. private RectF rectF;
  3. @Override
  4. protected void onDraw(Canvas canvas) {
  5. super.onDraw(canvas);
  6. rectF=new RectF(10, 10, 70, 60);//实例化矩形
  7. //画矩形
  8. <span style="white-space:pre"> </span>//canvas.drawRect(10, 10, 70, 60, paint);两种方式,如果第一句没有声明RecF,就要按多个参数的构造方法绘制。<span style="white-space:pre"> </span>
  9. canvas.drawRect(rectF, paint);
  10. //画弧线
  11. canvas.drawArc(rectF, 0, 290, true, paint);
  12. //画圆:参数1、2:圆心的坐标 参数3:半径
  13. canvas.drawCircle(100, 100, 30, paint);
  14. //画图片<span style="white-space:pre"> </span>图片资源<span style="white-space:pre"> </span>图片左上角的坐标(X,Y)
  15. canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), 200, 200, paint);
  16. //画文本<span style="white-space:pre"> </span>文本左上角的坐标
  17. canvas.drawText("nihaohao", 200, 300, paint);
  18. //画线<span style="white-space:pre"> </span>起点坐标 重点坐标 paint对象
  19. canvas.drawLine(205, 305, 255, 355, paint);
  20. }

画<shape>对象

Shape对象的绘制

  1. <shape xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:shape="oval">
  3. <size android:width="60px"
  4. android:height="60px"></size>
  5. <stroke
  6. android:color="#ff0000"
  7. android:width="2px"></stroke>
  8. <gradient
  9. android:startColor="#ff0000"
  10. android:centerColor="#00ff00"
  11. android:endColor="#0000ff"></gradient>
  12. </shape>


初始化方法初始drawable,这个get到的是一个Drawable对象
  1. private void init() {
  2. drawable = getResources().getDrawable(R.drawable.cir);
  3. }
ondraw()方法里,注释已经很清楚了

  1. protected void onDraw(Canvas canvas) {
  2. super.onDraw(canvas);
  3. // 设置 drawable bounds 指定 x,y
  4. Rect bounds = drawable.getBounds();
  5. bounds.left = (int)x;
  6. bounds.top = (int)y;
  7. bounds.right = bounds.left + 60;//只是保证离边界有一定距离
  8. bounds.bottom =bounds.top + 60;
  9. drawable.setBounds(bounds);
  10. //画到canvas上
  11. drawable.draw(canvas);
  12. }

画Bitmap对象

init()方法里

bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

onDraw()方法里,需要注意的是,drawBitmap()方法里传的参数,参数一:bitmap对象参数二:bitmap左上角x坐标 参数三:bitmap左上角y坐标。所以如果想要坐标指定在图片中间,需要x-bitmap.getWidth()/2, y-bitmap.getHeight()/2。这样做的好处是:在onTouchEvent()事件中,定义的x,y坐标可以定在图片中间,完成一定的手势动作。

canvas.drawBitmap(bitmap, x-bitmap.getWidth()/2, y-bitmap.getHeight()/2, paint);

还要注意:顺序不要反了。是在canvas(画布)上画,而不是这个canvas画别的对象。canvas都是处在一个 被动的角度。


OnTouchEvent

这个方法响应了触摸屏幕发生的事件,包括按下、抬起、移动等等,都可以被监听到。

可以实现一定的拖动,绘图功能。通过event能get到这些动作和当前X,Y坐标等等。

  1. public boolean onTouchEvent(MotionEvent event) {
  2. //这个方法里往往需要重绘界面,使用这个方法可以自动调用onDraw()方法。(主线程)
  3. invalidate();
  4. //非UI线程用
  5. postInvalidate();
  6. //使系统响应事件,返回true
  7. return true
  8. }

三种事件的判断和处理方式:

  1. public boolean onTouchEvent(MotionEvent event) {
  2. //获取手指在屏幕上的坐标
  3. float x = event.getX();
  4. float y = event.getY();
  5. //获取手指的操作--》按下、移动、松开
  6. int action = event.getAction();
  7. switch (action) {
  8. case MotionEvent.ACTION_DOWN://按下
  9. Log.i(TAG, "ACTION_DOWN");
  10. break;
  11. case MotionEvent.ACTION_MOVE://移动
  12. Log.i(TAG, "ACTION_MOVE");
  13. break;
  14. case MotionEvent.ACTION_UP://松开
  15. Log.i(TAG, "ACTION_UP");
  16. break;
  17. }
  18. return true;
  19. }

并且通过X,Y坐标可以判断滑动的方向,从而做出一些判断,可以响应动画,ScrollView的滑动等等,可以做的事情非常多。但是一些复杂的手势操作,需要用Android的Gesturedetector。例如双击、fling等较为复杂的手势。这个类过两天再总结。在处理触摸事件时,activity首先会响应onTouchEvent()。


一个Demo:画板


  1. public class WritePadView extends View{
  2. //视图放置在布局中,,,实例化
  3. public WritePadView(Context context, AttributeSet attrs) {
  4. super(context, attrs);
  5. init();
  6. }
  7. //代码new控件
  8. public WritePadView(Context context) {
  9. super(context);
  10. init();
  11. }
  12. private void init() {
  13. linesX=new ArrayList<ArrayList<Float>>();
  14. linesY=new ArrayList<ArrayList<Float>>();
  15. paint=new Paint();
  16. //设置颜色
  17. paint.setColor(Color.GREEN);
  18. //设置抗锯齿
  19. paint.setAntiAlias(true);
  20. //设置画笔的样式
  21. paint.setStyle(Style.FILL);
  22. }
  23. //绘制视图
  24. @Override
  25. protected void onDraw(Canvas canvas) {
  26. super.onDraw(canvas);
  27. for(int j=0;j<linesX.size();j++){
  28. //连点成线 3
  29. for(int i=0;i<linesX.get(j).size()-1;i++){
  30. canvas.drawLine(linesX.get(j).get(i), linesY.get(j).get(i),linesX.get(j).get(i+1), linesY.get(j).get(i+1), paint);
  31. }
  32. }
  33. }
  34. /**两个集合--》记录手指的轨迹的点---》一个线段*/
  35. private ArrayList<Float> xs , ys;
  36. private Paint paint;
  37. //装所有线段的集合
  38. private List<ArrayList<Float>> linesX,linesY;
  39. //手指触摸屏幕
  40. @Override
  41. public boolean onTouchEvent(MotionEvent event) {
  42. //获取手指的位置
  43. float x = event.getX();
  44. float y = event.getY();
  45. if(event.getAction()==MotionEvent.ACTION_DOWN){//按下--》一个新的线段开始了
  46. xs=new ArrayList<Float>();
  47. ys=new ArrayList<Float>();
  48. linesX.add(xs);
  49. linesY.add(ys);
  50. }
  51. //把手指的位置记录下来
  52. xs.add(x);
  53. ys.add(y);
  54. //通知视图重绘制、
  55. invalidate();
  56. return true;
  57. }
  58. }



自定义View加载到视图

在布局xml里,使用自定义视图要用 包名.类名引用。

  1. <com.bless.myViewDemo.MyView
  2. android:layout_width="wrap_content"
  3. android:layout_height="wrap_content" />


附Paint对象一些属性方法:

Paint:
void setARGB(int a, int r, int g, int b) 设置Paint对象颜色,参数一为alpha透明通道

void setAlpha(int a) 设置alpha不透明度,范围为0~255

void setAntiAlias(boolean aa) //是否抗锯齿

void setColor(int color) //设置颜色,这里Android内部定义的有Color类包含了一些常见颜色定义

void setFakeBoldText(boolean fakeBoldText) //设置伪粗体文本

void setLinearText(boolean linearText) //设置线性文本

PathEffect setPathEffect(PathEffect effect) //设置路径效果

Rasterizer setRasterizer(Rasterizer rasterizer) //设置光栅化

Shader setShader(Shader shader) //设置阴影

void setTextAlign(Paint.Align align) //设置文本对齐

void setTextScaleX(float scaleX) //设置文本缩放倍数,1.0f为原始

void setTextSize(float textSize) //设置字体大小

Typeface setTypeface(Typeface typeface) //设置字体,Typeface包含了字体的类型,粗细,还有倾斜、颜色等。

void setUnderlineText(boolean underlineText) //设置下划线


附Canvas属性

Canvas:
void drawRect(RectF rect, Paint paint) //绘制区域,参数一为RectF一个区域

void drawPath(Path path, Paint paint) //绘制一个路径,参数一为Path路径对象

void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) //贴图,参数一就是我们常规的Bitmap对象,参数二是源区域(这里是bitmap),参数三是目标区域(应该在 canvas的位置和大小),参数四是Paint画刷对象,因为用到了缩放和拉伸的可能,当原始Rect不等于目标Rect时性能将会有大幅损失。

void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) //画线,参数一起始点的x轴位置,参数二起始点的y轴位置,参数三终点的x轴水平位置,参数四y轴垂直位置,最后一个参数为Paint画刷对象。

void drawPoint(float x, float y, Paint paint) //画点,参数一水平x轴,参数二垂直y轴,第三个参数为Paint对象。

void drawText(String text, float x, float y, Paint paint) //渲染文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。

void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) //在路径上绘制文本,相对于上面第二个参数是Path路径对象

附录的原博地址:http://blog.csdn.net/listening_music/article/details/6859229
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/254512
推荐阅读
相关标签
  

闽ICP备14008679号