Android绘图(一)

来源:互联网 发布:程序员面试技巧 编辑:程序博客网 时间:2024/05/08 18:45

(《群英传》)整理笔记:

基本知识点:

分辨率:手机屏幕的像素点个数。
PPI(DPI):对角线的像素点除以屏幕的大小。

系统屏幕密度:
Ldpi:240×320;
Mdpi:320×480;
Hdpi:480×800;
Xhdpi:720×1280;
Xxhdpi:1080×1920。

单位转换:

package com.android.utils;import android.content.Context;/** * 单位转换工具类(公式换算方法) *  * @author Administrator * */public class UnitConversion {    /**     * 将px值转换为dip或dp值,保证尺寸不变。 density为换算比例     *      * @param context     * @param pxValue     * @return     */    public static int px2dip(Context context, float pxValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (pxValue / scale + 0.5f);    }    /**     * 将dip或dp转换为px值,保证尺寸大小不变     *      * @param context     * @param dipValue     * @return     */    public static int dip2px(Context context, float dipValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dipValue * scale + 0.5f);    }    /**     * 将px值转换为sp值,保证尺寸大小不变     *      * @param context     * @param pxValue     * @return     */    public static int px2sp(Context context, float pxValue) {        final float fontScale = context.getResources().getDisplayMetrics().density;        return (int) (pxValue / fontScale + 0.5f);    }    /**     * 将sp值转换为px值,保证尺寸大小不变     *      * @param context     * @param spValue     * @return     */    public static int sp2px(Context context, float spValue) {        final float fontScale = context.getResources().getDisplayMetrics().density;        return (int) (spValue * fontScale + 0.5f);    }}

2D绘图基础:

Paint的基本属性:
setAntiAlias(true); // 设置画笔的锯齿效果
setColor(); // 设置画笔的颜色
SetARGB(); // 设置画笔的A、R、G、B值
setAlpha(); // 设置画笔的Alpha(透明度)值
setTextSize() ; //设置字体的尺寸
setStyle(); // 设置画笔的风格(空心或实心)
setStrokeWidth(); // 设置空心边框的宽度

Canvas的常用方法:
DrawPoint:绘制点;
DrawLine:绘制直线;
DrawLines:绘制多条直线;

float[] pts = {                startX1, startY1, endX1, endY1,                …… ……                startXn, startYn, endXn, endYn        };        canvas.drawLines(pts, paint);

DrawRect:绘制矩形;
DrawRoundRect:绘制圆角矩形;
DrawCircle:绘制圆;
DrawArc:绘制弧形、扇形。useCenter(true)为扇形;
DrawOval:绘制椭圆(外接矩形);
DrawText():绘制文本;
DrawPosText:在指定位置绘制文本;
DrawPath:绘制路径–>

Path patn = new Path();path.moveTo(50, 50);path.lineTo(100, 100);path.lineTo(100, 300);path.lineTo(300, 50);canvas.drawPath(path,paint);

Android XML绘图:
1、Bitmap:可以将图片转换成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:可以在XML中绘制各种形状
(为了说明用法,格式并不准确)

<shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle" >    <!-- 绘制各种形状 -->    <!-- 指定大小,一般用在imageview配合scaleType属性使用 -->    <size         android:width="integer"        android:height="integer"/>    <!-- 渐变 -->    <gradient        android:angle="45"        android:endColor="color"        android:startColor="color"        android:centerX="integer"        android:centerY="integer"        android:centerColor="color"        android:gradientRadius="integer"        android:type="linear"        android:useLevel="true" />    <padding         android:left="integer"        android:top="integer"        android:right="integer"        android:bottom="integer"/>    <!-- 填充颜色 -->    <solid android:color="color"/>    <!-- 指定边框 -->    <stroke android:width="integer"        android:color="color"        // 虚线宽度        android:dashWidth="integer"        // 虚线间隔宽度        android:dashGap="integer"/>    <corners android:radius="integer"/></shape>

通过渐变实现的阴影效果

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

3、Layer图层:
图片会依次叠加

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

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

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

5、上面方法的共同作用:

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

绘图技巧:
1、Canvas:
Canvas.save():将之前的所有已绘制图像保存起来;
Canvas.restore():合并图层;
Canvas.translate():坐标系的平移;
Canvas.rotate():坐标系的反转。

示例:时钟

import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.View;import android.view.WindowManager;public class MyClock extends View {    private int mWidth;    private int mHeight;    public MyClock(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView(context);    }    public MyClock(Context context, AttributeSet attrs) {        super(context, attrs);        initView(context);    }    public MyClock(Context context) {        super(context);        initView(context);    }    // 获取屏幕的宽和高    private void initView(Context context) {        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);        DisplayMetrics dm = new DisplayMetrics();        wm.getDefaultDisplay().getMetrics(dm);        mWidth = dm.widthPixels;        mHeight = dm.heightPixels;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        Paint panintCicle = new Paint();        panintCicle.setStyle(Paint.Style.STROKE);        panintCicle.setAntiAlias(true);        panintCicle.setStrokeWidth(5);        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, panintCicle);        Paint paintDegree = new Paint();        panintCicle.setStrokeWidth(3);        for (int i = 0; i < 12; i++) {            // 区分整点与非整点            if (i == 0 || i == 3 || i == 6 || i == 9) {                paintDegree.setStrokeWidth(5);                paintDegree.setTextSize(100);                canvas.drawLine(                        mWidth / 2,                        mHeight / 2 - mWidth / 2 + 100,                        mWidth / 2, mHeight / 2 - mWidth,                        paintDegree);                String degree = String.valueOf(i);                canvas.drawText(                        degree,                        mWidth / 2 - paintDegree.measureText(degree) / 2,                        mHeight / 2 - mWidth / 2 + 170,                        paintDegree);            } else {                paintDegree.setStrokeWidth(3);                paintDegree.setTextSize(50);                canvas.drawLine(                        mWidth / 2,                        mHeight / 2 - mWidth / 2 + 60,                        mWidth / 2,                        mHeight / 2 - mWidth,                        paintDegree);                String degree = String.valueOf(i);                canvas.drawText(                        degree,                        mWidth / 2 - paintDegree.measureText(degree) / 2,                        mHeight / 2 - mWidth / 2 + 100,                        paintDegree);            }            // 通过旋转画布简化坐标运算            canvas.rotate(30, mWidth / 2, mHeight / 2);        }        // 画指针        Paint paintHour = new Paint();        paintHour.setStrokeWidth(20);        Paint paintMinute = new Paint();        paintMinute.setStrokeWidth(10);        canvas.save();        canvas.translate(mWidth / 2, mHeight / 2);        canvas.drawLine(0, 0, 100, 100, paintHour);        canvas.drawLine(0, 0, 100, 200, paintMinute);        canvas.restore();    }}

2、Layer图层
使用saveLayer()方法来创建一个图层,图层是基于栈的结构进行管理。调用saveLayer()、saveLayerAlpha(),使用restore()、restoreToCount()将一个图层出栈。

@Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawColor(Color.WHITE);        Paint mPaint = new Paint();        mPaint.setColor(Color.BLUE);        canvas.drawCircle(150, 150, 100, mPaint);        // 入栈        canvas.saveLayerAlpha(0, 0, 400, 400, 127, LAYER_FLAGS);        mPaint.setColor(Color.RED);        canvas.drawCircle(200, 200, 100, mPaint);        // 出栈        canvas.restore();    }

透明度为127时,即半透明;
透明度为255时,即完全不透明;
透明度为0时,即完全透明。

0 0
原创粉丝点击