《Android群英传》读书笔记(5)第六章:Android绘图机制与处理技巧之一

1.屏幕参数

  1. 屏幕分辨率与DPI的对照表
密度ldpimdpihdpixhdpixxhdpi
密度值120160240320480
分辨率240x320320x480480x800720x12801080x1920

2. 在密度为160的屏幕上,即分辨率为320x480的屏幕上,1dp = 1px;在其他屏幕则可以通过比例进行计算,在mdpi中1dp = 1px,hdpi中1dp = 1.5px,xhdpi中1dp = 2px,在xxhdpi中1dp = 3px。
3. 单位换算
下面代码是px、dp、sp相互转换的工具类,可以集成到工程中来使用。

public class DisplayUtil{
    public static int px2dp(Context context,float pxValue){
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int)(pxValue / scale + 0.5f);
    }

    public static int dp2px(Context context,float dpValue){
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int)(dpValue * scale + 0.5f);
    }

    public static int px2sp(Context context,float pxValue){
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int)(pxValue / fontScale + 0.5f);
    }

    public static int sp2px(Context context,float spValue){
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int)(spValue * fontScale + 0.5f);
    }
}

或者使用Android提供的TypedVaule中的方法来实现:

protected int dp2px(int dp){
    return (int)TypedVaule.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,getResources().getDisplayMetrics());
}

protected int sp2px(int sp){
    return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,sp,getResources().getDisplayMetrics());
}

2.2D绘图基础

Paint类中提供的一些方法:

setAntiAlias();//设置画笔抗锯齿效果
setColor();//设置画笔的颜色
setARGB();//设置画笔的A、R、G、B的值
setAlpha();//设置画笔的Alpha值
setTextSize();//设置字体的大小
setStyle();//设置画笔的风格(空心或者实心Paint.Style.STROKE或Paint.Style.FILL)
setStrokeWidth();//设置画笔空心边框宽度

Canvas类的一些方法

canvas.drawPoint(x,y,paint);//画点
canvas.drawLine(startX,startY,endX,endY,paint);//画线
canvas.drawLines(float[] pts,Paint paint);//画多条线
canvas.drawRect(left,top,right,bottom,paint);//画矩形
canvas.drawRoundRect(left,top,right,bottom,radiusX,radiusY,paint);//画圆角矩形
canvas.drawCircle(circleX,circleY,radius,paint);//画圆
//画弧、扇形
canvas.drawArc(left,top,right,bottom,startAngle,sweepAngle,useCenter,paint);//startAngle:起始角度,sweepAngle:扫过的角度,useCenter:boolean类型,为true时画出来的是扇形,false画出来的是弧线
canvas.drawText(text,startX,startY,paint);//画文本
canvas.drawPosText(text,
        new float[]{X1,Y1,
                    X2,Y2,
                    .....
                    Xn,Yn},
                    paint);//在指定位置绘制文本
canvas.drawOval(left,top,right,bottom,paint);//画椭圆
Path path = new Path();
path.moveTo(50,50);
path.lineTo(100,100);
path.lineTo(100,300);
path.lineTo(300,50);
canvas.drawPath(path,paint);//绘制路径

3.Android中的XML绘图

1.Bitmap

在XML中使用Bitmap非常简单:

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

通过这样引用一张图片,就可以将图片直接转成了Bitmap在程序中使用。

2.shape

通过shape可以在XML中绘制任何形状,下面展示了Shape所支持的参数

<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    //默认为rectangle
    android:shape=["rectangle"|"oval"|"line"|"ring"]>
    <corners //当shape="rectangle"时使用
        //半径,会被后面的单个半径属性覆盖
        android:radius="integer"
        android:topLeftRadius="integer"
        android:topRightRadius="integer"
        android:bottomLegtRadius="integer"
        android:bottomRightRadius="integer"/>
    <gradient   //渐变
        android:angle="integer"
        android:centerX="integer"
        android:centerY="integer"
        android:centerColor="color"
        android:endColor="color"
        android:gradientRadius="integer"
        android:startColor="color"
        android:type=["linear"|"radial"|"sweep"]
        android:useCenter=["true"|"false"]/>
    <padding
        android:left="integer"
        android:top="integer"
        android:right="integer"
        android:bottom="integer"/>
    <size //指定大小,一般用在ImageView配合scaleType属性使用
        android:width="integer"
        android:height="integer"/>
    <solid  //填充颜色
        android:color="color"/>
    <stroke //指定边框
        android:width="integer"
        android:color="color"
        //虚线宽度
        android:dashWidth="integer"
        //虚线间隔宽度
        android:dashGap="integer"/>
</shape>
3.Layer

Layer是在PhotoShop中非常常用的功能,在Android中,同样可以通过Layer来实现类似的概念

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--图片一-->
    <item
        android:drawable="@drawable/ic_launcher"/>
    <!--图片二-->
    <item
        android:drawable="@drawable/ic_launcher"
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp"/>
</layer-list>

layer-list中的图片会依次叠加

4.selector

Selector的作用在于帮助开发者实现静态绘图中的事件反馈,通过给不同的设置不同的图像,从而在程序中根据用户输入,返回不同的效果。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    <!-- 默认时的背景图片 -->
    <item android:drawable="@drawable/X1"/>
    <!-- 没有焦点时的背景图片 -->
    <item android:state_window_focused="false"
        android:drawable="@drawable/X2"/>
    <!-- 非触摸模式下获得焦点并单击时的背景图片 -->
    <item android:state_window_focused="true"
        android:state_pressed="true"
        android:drawable="@drawable/X3"/>
    <!-- 触摸模式下单击时的背景图片 -->
    <item android:state_window_focused="false"
        android:state_pressed="true"
        android:drawable="@drawable/X4"/>
    <!-- 选中时的图片背景 -->
    <item android:state_selected="true"
        android:drawable="@drawable/X5"/>
    <!-- 获得焦点时的图片背景 -->
    <item android:state_focused="true"
        android:drawable="@drawable/X6"/>
</selector>

Selector还可以和shape共同作用

<?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="#33444444"/>
            <corners android:radius="5dp"/>
            <padding android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp"/>
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#FFFFFF"/>
            <corners android:radius="5dp"/>
            <padding android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp"/>
        </shape>
    </item>
</selector>

4.Android绘图技巧

1.Canvas

Canvas中的几个方法:

Canvas.save();//
Canvas.restore();
Canvas.translate();
Canvas.rotate();

Canvas.save()意为保存画布,它的作用就是将之前所有已绘制的图像保存起来,让后续的操作像是在一个新的图层上操作。
Canvas.restore()可以理解为合并图层的操作,是将save()之前绘制的图像和之后绘制的图像进行合并。
Canvas.translate()和Canvas.rotate()分别为平移画布和旋转画布,更像是对坐标系的平移和旋转,例如调用translate(x,y)会将原点(0,0)移动到(x,y),之后的所有操作都将以(x,y)为原点执行。
一般在对Canvas调用translate或者rotate之前需要调用save()方法,然后translate或rotate方法之后的内容绘制完成后再调用restore()方法。
先来看一下Android绘图的坐标系,坐标零点位于屏幕左上角,向下为Y轴正方向,向右为X轴正方向。

2.Layer图层

Android中通过调用saveLayer()saveLayerAlpha()方法将一个图层入栈,使用restore()restoreToCount()方法将一个图层出栈。入栈的时候后面所有的操作都将发生在这个图层上,而出栈的时候,则会把图像绘制到上层Canvas上。下面的代码展示了如何使用Layer:

@Override
protected void onDraw(Canvas canvas){
    canvas.drawColor(Color.WHITE);
    mPaint.setColor(Color.BLUE);
    canvas.drawCircle(150,150100,mPaint);
    canvas.saveLayerAlpha(0,0,400,400,127,LAYER_FLAGS);
    mPaint.setColor(Color.RED);
    canvas.drawCircle(200,200,100,mPaint);
    canvas.restore();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值