基本绘画view
2016-07-15 11:23
411 查看
我们将举例说明怎么自定义一个组件,怎么样在一个视图上画各种图形和路径还有怎么处理用户的触摸交互。
步骤
1. 创建一个继承View的自定义view类
2. 在布局XML文件中加入我们新建的view
3. 在类中定义画布和线条的各种属性,其中最后的实现是用的是
要点:新建一个点对象的集合合存储相应触摸的点的坐标
在
设置
是一种常用的模式
自定义一个
使用:
步骤
1. 创建一个继承View的自定义view类
2. 在布局XML文件中加入我们新建的view
3. 在类中定义画布和线条的各种属性,其中最后的实现是用的是
onDraw()方法
//为了绘制新建一个view类 public class SimpleDrawingView extends View { //建立首个颜色 private final int paintColor = Color.BLACK; //定义油漆和画布 private Paint drawPaint; public SimpleDrawingView(Context context, AttributeSet attrs) { super(context, attrs); setFocusable(true); setFocusableInTouchMode(true); setupPaint(); } //设置笔画的颜色和风格 private void setupPaint() { drawPaint = new Paint(); drawPaint.setColor(paintColor);//设置为黑色 drawPaint.setAntiAlias(true);//设置抗锯齿 drawPaint.setStrokeWidth(5);//设置笔画粗细 drawPaint.setStyle(Paint.Style.STROKE);//绘画风格为线条 drawPaint.setStrokeJoin(Paint.Join.ROUND);//笔画形状 drawPaint.setStrokeCap(Paint.Cap.ROUND); } @Override protected void onDraw(Canvas canvas) { canvas.drawCircle(50, 50, 20 ,drawPaint);//参数中心的x,y坐标以及圆和使用的线条 drawPaint.setColor(Color.GREEN); canvas.drawCircle(50, 150, 20, drawPaint); drawPaint.setColor(Color.BLUE); canvas.drawCircle(50, 250, 20 ,drawPaint); } }
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
处理触摸交互
如果我们想要用户每次触摸在绘画视图上的时候都可以画出一个点,这要求我们跟踪一系列的点,当onTouch事件触发的时候获得那个点,然后绘制出来
要点:新建一个点对象的集合合存储相应触摸的点的坐标
在
onDraw()方法中绘制出集合中的点
//每当用户触摸屏幕时会触发我们之前存储的圆 private List<Point> circlePoints; public SimpleDrawingView(Context context, AttributeSet attrs) { super(context, attrs); setFocusable(true); setFocusableInTouchMode(true); setupPaint(); circlePoints = new ArrayList<Point>(); } //设置笔画的颜色和风格 private void setupPaint() { drawPaint = new Paint(); drawPaint.setColor(paintColor);//设置为黑色 drawPaint.setAntiAlias(true);//设置抗锯齿 drawPaint.setStrokeWidth(5);//设置笔画粗细 drawPaint.setStyle(Paint.Style.FILL);//绘画风格为填充 drawPaint.setStrokeJoin(Paint.Join.ROUND);//笔画形状 drawPaint.setStrokeCap(Paint.Cap.ROUND); } //在view上绘制集合中的点 @Override protected void onDraw(Canvas canvas) { for (Point p : circlePoints) { canvas.drawCircle(p.x, p.y, 5, drawPaint); } } //设置点击事件 @Override public boolean onTouchEvent(MotionEvent event) { float touchX = event.getX();//获得点击点的x坐标 float touchY = event.getY();//获得点击点的Y坐标 //将点的坐标存储到集合中 circlePoints.add(new Point(Math.round(touchX), Math.round(touchY))); //重新绘制view,表明无效 postInvalidate(); return true; }
路径绘制
Path类是一个允许用户在屏幕上绘制的理想的类,一个路径可以包括很多的线条图像轮廓甚至形状,首先让我们创建一个
path的变量。然后通过点击事件的类型来获得相应的动作
public class SimpleDrawingView extends View { private Path path = new Path(); // Get x and y and append them to the path public boolean onTouchEvent(MotionEvent event) { float pointX = event.getX(); float pointY = event.getY(); // Checks for the event that occurs switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // Starts a new line in the path path.moveTo(pointX, pointY); break; case MotionEvent.ACTION_MOVE: // Draws line between last point and this point path.lineTo(pointX, pointY); break; default: return false; } postInvalidate(); // Indicate view should be redrawn return true; // Indicate we've consumed the touch } }
设置
onDraw方法
public class SimpleDrawingView extends View { // ... onTouchEvent ... // Draws the path created during the touch events @Override protected void onDraw(Canvas canvas) { canvas.drawPath(path, drawPaint); } private void setupPaint() { // same as before drawPaint.setStyle(Paint.Style.STROKE); // change back to stroke // ... } }
使用bitmap的缓存高效绘制
当在帆布上绘制时,我们可以通过将图像缓存为bitmap来改善渲染时间是一种常用的模式
Bitmap mField = null; public void init() { mField = new Bitmap(...dimensions...); Canvas c = new Canvas(mField); c.drawRect(...); ... } public void onDraw(Canvas c) { c.drawBitmap(mField); }
使用DIP绘制
当我们进行绘制或可以帮我呢keyidad者动画时候,为了支持更多的屏幕我们需要使用dp,使用这个工具类可以帮我们达成测量屏幕宽高和将dp转换为px的目的自定义一个
DeviceDimensionsHelper.java类:
public class DeviceDimensionsHelper { // DeviceDimensionsHelper.getDisplayWidth(context) => (用像素表示宽度) public static int getDisplayWidth(Context context) { DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); return displayMetrics.widthPixels; } // DeviceDimensionsHelper.getDisplayHeight(context) => (像素表示高度) public static int getDisplayHeight(Context context) { DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); return displayMetrics.heightPixels; } // DeviceDimensionsHelper.convertDpToPixel(25f, context) => (25dp converted to pixels) public static float convertDpToPixel(float dp, Context context){ Resources r = context.getResources(); return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()); } // DeviceDimensionsHelper.convertPixelsToDp(25f, context) => (25px converted to dp) public static float convertPixelsToDp(float px, Context context){ Resources r = context.getResources(); DisplayMetrics metrics = r.getDisplayMetrics(); float dp = px / (metrics.densityDpi / 160f); return dp; }
使用:
// Get height or width of screen int screenHeight = DeviceDimensionsHelper.getDisplayHeight(this); int screenWidth = DeviceDimensionsHelper.getDisplayWidth(this); // Convert dp to pixels float px = DeviceDimensionsHelper.convertDpToPixel(25f, this); // Convert pixels to dp float dp = DeviceDimensionsHelper.convertPixelsToDp(25f, this);
相关文章推荐
- 使用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