Android绘图技巧使用详解

本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下

XML绘图

Bitmap

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
 android:src="@drawable/giao"/>

Shape

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="rectangle">
 <gradient
  android:startColor="#FF5DA2FF"
  android:endColor="#805FBBEF"
  android:angle="45"/>
 <padding
  android:bottom="7dp"
  android:top="7dp"
  android:left="7dp"
  android:right="7dp"/>
 <corners android:radius="8dp"/>
</shape>

Layer(实现Photoshop中类似图层的概念)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:drawable="@drawable/default_head"/>
 <item android:drawable="@drawable/default_head"
  android:left="10dip"
  android:right="10dip"
  android:top="10dip"
  android:bottom="10dip"/>
 <item android:drawable="@drawable/giao"
  android:left="200dp"
  android:right="200dp"
  android:top="200dp"
  android:bottom="200dp"/>
<!-- 图层效果-->
</layer-list>

Selector(帮助开发者实现静态绘图中的时间反馈)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_pressed="true">
  <shape android:shape="rectangle">
   <solid android:color="#33FD0000"/>
   <corners android:radius="5dp"/>
   <padding android:left="10dp"
    android:right="10dp"
    android:top="10dp"
    android:bottom="10dp"/>
  </shape>
 </item>
 <item>
  <shape android:shape="rectangle">
   <solid android:color="#ffffffff"/>
   <corners android:radius="5dp"/>
   <padding android:left="10dp"
    android:right="10dp"
    android:top="10dp"
    android:bottom="10dp"/>
  </shape>
 </item>
<!-- 点击反馈效果-->
</selector>

Android绘图技巧

Canvas(作为绘制图形的直接对象)

Canvas.save();

可以理解为保存画布,作用是将之前的所有已经绘制图像保存起来,让后续的操作就好像在一个新的图层上操作一样

Canvas.restore();

可以理解为Photoshop中的合并图层操作,作用是将save()之后绘制的所有的图像与save()之前的图像进行合并

Canvas.translate();

坐标系的平移

Canvas.rotate();

坐标系的旋转

Layer图层

特别注意的是 saveLayerAlpha()与restore()要同时使用,才能够在canvas 画出多个层次,就是花多少层就要有多少对两个函数!

@Override
 protected void onDraw(Canvas canvas) {
  //super.onDraw(canvas);
  drawLayer(canvas);
  //图层同样是基于栈的结构进行管理的
  @SuppressLint("DrawAllocation")
  Paint paint=new Paint();
  canvas.drawColor(Color.WHITE);
  paint.setColor(Color.BLUE);
  canvas.drawCircle(150,150,100,paint);

  canvas.saveLayerAlpha(0,0,400,400,127);//入栈(创建新图层)
  paint.setColor(Color.RED);
  canvas.drawCircle(200,200,100,paint);
  canvas.restore();//出栈
 }

像素点分析

bitmap.getPixels(pixels,offset,stride,x,y,width,height);

参数含义如下:

  • pixels:接受位图颜色值的数组
  • offset:写入到pixels[]中的第一个索引值
  • stride:pixels[]的行间距
  • x:从位图中读取的第一个像素的x坐标值
  • y:从位图中读取的第一个像素的y坐标值
  • width:每一行中读取的像素宽度
  • height:读取的行数

画笔特效处理

PorterDuffXfermode

public class FilletView extends View {
 private Bitmap bitmap,out;
 private Paint paint;
 public FilletView(Context context) {
  super(context);
  inView();
 }

 public FilletView(Context context, @Nullable AttributeSet attrs) {
  super(context, attrs);
  inView();
 }

 public FilletView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  inView();
 }
 private void inView(){
  bitmap= BitmapFactory.decodeResource(getResources(), R.drawable.ask);
  out=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Bitmap.Config.ARGB_8888);
  Canvas canvas=new Canvas(out);
  paint=new Paint();
  paint.setAntiAlias(true);
  canvas.drawRoundRect(0,0,bitmap.getWidth(),bitmap.getHeight(),80,80,paint);
  paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
  canvas.drawBitmap(bitmap,0,0,paint);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  canvas.drawBitmap(out,0,0,null);

 }
}

Shader

  • BitmapShader:位图Shader
  • LinearGradient:线性Shader
  • RadialGradient:光束Shader
  • SweepGradient:梯度Shader
  • ComposeShader:混合Shader
private void useBitmapShader(Canvas canvas){
  @SuppressLint("DrawAllocation")
  Bitmap bitmap= BitmapFactory.decodeResource(getResources(), R.drawable.default_head);
  @SuppressLint("DrawAllocation")
  BitmapShader shader=new BitmapShader(bitmap, Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);
  @SuppressLint("DrawAllocation")
  Paint paint=new Paint();
  paint.setShader(shader);
  canvas.drawCircle(500,200,200,paint);
}
  • Shader.TileMode.REPEAT:重复——横向、纵向不断重复
  • Shader.TileMode.CLAMP:拉伸——拉伸的图片最后的那个像素,不断重复
  • Shader.TileMode.MIRROR:镜像——横向不断翻转重复,横向不断翻转重复

PathEffect(各种笔触绘制一个路径)

  • CornerPathEffect:拐角处变得圆滑
  • DiscretePathEffect:线段上会产生许多杂点
  • DashPathEffect:绘制虚线
  • PathDashPathEffect:比DashPathEffect的功能更加强大,可以设置如方形点的虚线,圆形点的虚线。
  • ComposePathEffect:组合任意两种PathEffect路径组合形成新的效果
public class PathEffectView extends View {
 private Paint paint;
 private Path mainPath;
 private PathEffect[] effects;
 public PathEffectView(Context context, @Nullable AttributeSet attrs) {
  super(context, attrs);
  inView();
 }
 private void inView(){
  paint=new Paint();
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth(5);
  paint.setColor(Color.DKGRAY);
  mainPath=new Path();
  mainPath.moveTo(0,0);
  for (int i = 0; i <= 30; i++) {
   mainPath.lineTo(i*35, (float) (Math.random()*100));
  }
  effects=new PathEffect[6];
 }

 @SuppressLint("DrawAllocation")
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  effects[0]=null;
  effects[1]=new CornerPathEffect(30);
  effects[2]=new DiscretePathEffect(3,5);
  effects[3]=new DashPathEffect(new float[]{20,10,5,10},0);
  Path path=new Path();
  path.addRect(0,0,8,8,Path.Direction.CCW);
  effects[4]=new PathDashPathEffect(path,12,0,PathDashPathEffect.Style.ROTATE);
  effects[5]=new ComposePathEffect(effects[3],effects[1]);
  for (PathEffect effect : effects) {
   paint.setPathEffect(effect);
   canvas.drawPath(mainPath, paint);
   canvas.translate(0, 200);
  }
 }
}

SurfaceView

SurfaceView与View的区别:

1、View主要适用于主动更新的情况下,而SurfaceView主要适用于被动更新,例如频繁的更新
2、View在主线程中对画面进行更新,而SurfaceView通常会通过一个子线程来进行页面的刷新
3、View在绘图时没有使用双缓冲机制,而SurfaceView在底层机制中就已经实现了双缓冲机制

总结:SurfaceView适合需要频繁刷新,或者刷新时数据处理量比较大

public class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback ,Runnable{
 //SurfaceHolder
 private SurfaceHolder holder;
 //用于绘画的Canvas
 private Canvas canvas;
 //子线程标志位
 private boolean isDrawing;
 private Paint paint;
 private Path path;
 private int x,y;
 public SurfaceViewTemplate(Context context) {
  super(context);
  inView();
 }

 public SurfaceViewTemplate(Context context, AttributeSet attrs) {
  super(context, attrs);
  inView();
 }

 public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  inView();
 }
 private void inView(){
  holder=getHolder();
  holder.addCallback(this);
  setFocusable(false);//焦点
  setFocusableInTouchMode(true);
  this.setKeepScreenOn(true);
  path=new Path();
  paint=new Paint(Paint.ANTI_ALIAS_FLAG);
  paint.setColor(Color.RED);
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth(10);
  paint.setStrokeCap(Paint.Cap.ROUND);
  paint.setStrokeJoin(Paint.Join.ROUND);
 }
 @Override
 public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
  isDrawing=true;
  path.moveTo(0,400);
  new Thread(this).start();
 }

 @Override
 public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {

 }

 @Override
 public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
  isDrawing=false;
 }

 @Override
 public void run() {
  while (isDrawing){
   drawSome();
   x+=1;
   y= (int) (100*Math.sin(x*2*Math.PI/180)+400);
   path.lineTo(x,y);
  }
 }
 private void drawSome(){
  try {
   canvas=holder.lockCanvas();
   //draw something...
   canvas.drawColor(Color.WHITE);
   canvas.drawPath(path,paint);
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (canvas!=null){
    holder.unlockCanvasAndPost(canvas);
   }
  }

 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android绘图之Paint的使用方法详解

    前言 大家都知道在Android中,自定义控件是一个非常重要的知识点,而自定义控件对Android开发者是一个难点,考验开发人员对View原理的理解,对于继承View的自定义控件,一般都需要重写onDraw方法,而且往往需要开发人员能够掌握Paint这个类. 简介 The Paint class holds the style and color information about how to draw geometries, text and bitmaps. Paint:该类保存了绘制几何

  • Android绘图常用方法汇总

    Android绘图常用方法有哪些,下面一一为大家列举: 1.有关画笔(Paint)的方法 Paint mPaint= new Paint(); mPaint.setAntiAlias(true); // 消除锯齿 mPaint.setStrokeWidth(mCircleWidth); // 设置圆环的宽度 mPaint.setStrokeCap(Paint.Cap.ROUND); // 定义线段断点形状为圆头 mPaint.setAntiAlias(true); // 消除锯齿 mPaint.

  • Android编程绘图操作之弧形绘制方法示例

    本文实例讲述了Android编程绘图操作之弧形绘制方法.分享给大家供大家参考,具体如下: /** * 绘制弧形图案 * @description: * @author ldm * @date 2016-4-25 下午4:37:01 */ public class ArcsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedIns

  • 简单实现Android绘图板

    下面这个实例通过前面学过的Paint.Canvas等2D绘画技术来实现一个简单的Android的绘图板. 具体实现代码: 创建一个名为DrawView的类,该类继承自android.view.View类.在该类中,首先定义程序中所需的属性,然后添加构造方法,并重写onDraw(Canvas canvas)方法: DrawView.java: package com.example.test; import android.content.Context; import android.graph

  • Android 通过onDraw实现在View中绘图操作的示例

    Android绘图操作,通过继承View实现,在onDraw函数中实现绘图.下面是一个简单的例子: 复制代码 代码如下: public class AndroidTest extends Activity {    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(save

  • android图像绘制(七)ClipRect局部绘图/切割原图绘制总结

    杂语:看了很多程序猿都有写博客的习惯,看来我也得练练,不管写的好不好了,学到点什么体会就写写吧. 内容解说:这几天开始学游戏地图制作,今天小小的总结一下Canvas的clipRect()接口的使用. 1)选取要在画布上绘制(刷新)的区域,如图以(x, y)为起点坐标.宽w.高h的区域 2)选择要绘制的图片,不一定是刚好宽高为(w,h),大图就需要切割了(本例子绘制绿色区域) 3)将图片绘制到画布上,使得绿色区域与白色方块重合 4)最后效果图 代码解说: 复制代码 代码如下: canvas.sav

  • Android UI效果之绘图篇(一)

    最近准备整理一套关于UI效果的文章,算是对这段时间的一个总结,主要讲Android开发中的UI效果设计模块.初步分为一下几个篇幅: Android XML绘图(Shape.Layer.Selector) Android Canvas绘图(canvas.point.porterDuffXfermode.shader) Android 动画详解 Android 自定义控件 今天就当开胃菜,先讲讲最简单的xml绘图,相信这个大家都用的比较熟,这里就当给大家做一个小文档,当那个参数配置忘了,便于查阅 一

  • Android自定义View绘图实现渐隐动画

    实现了一个有趣的小东西:使用自定义View绘图,一边画线,画出的线条渐渐变淡,直到消失.效果如下图所示: 用属性动画或者渐变填充(Shader)可以做到一笔一笔的变化,但要想一笔渐变(手指不抬起边画边渐隐),没在Android中找到现成的API可用.所以,自己做了一个. 基本的想法是这样的: •在View的onTouchEvent中记录触摸点,生成一条一条的线LineElement,放在一个List中.给每个LineElement配置一个Paint实例. •在onDraw中绘制线段. •变换Li

  • Android编程之OpenGL绘图技巧总结

    本文实例讲述了Android编程之OpenGL绘图技巧.分享给大家供大家参考,具体如下: 很久不用OpenGL ES绘图,怕自己忘记了,于是重新复习一遍,顺便原理性的东西总结如下: 1. Android 3D坐标系统 如图: Android的三维坐标系统中: 坐标原点位于中央, X轴从左向右延伸,原点左边的值为负数,右边为正数: Y轴从下向上延伸,原点下边的值为负数,上边为正数: Z轴屏幕里面向外面延伸,屏幕里面为负数,外面为正数. 2. 开发工具(OpenGL和OpenGL ES)介绍 Ope

  • Android编程之绘图canvas基本用法示例

    本文实例讲述了Android编程之绘图canvas基本用法.分享给大家供大家参考,具体如下: MainActivity的代码如下: package example.com.myapplication; import android.os.Bundle; import android.app.Activity; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedIns

随机推荐