Android绘图(一)

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

基本知识点:

分辨率:手机屏幕的像素点个数。
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时,即完全透明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值