Android绘图机制和处理技巧

2016-08-02  本文已影响301人  14cat

前言

目录

Android绘图机制与处理技巧.png

Android屏幕相关知识

屏幕尺寸信息

屏幕参数

系统屏幕密度

密度 密度值 分辨率
ldpi 120 240×320
mdpi 160 320×480
hdpi 240 480×800
xhdpi 320 720×1280
xxhdpi 480 1080×1920

独立像素密度dp

Android系统使用mdpi即密度值为160的屏幕作为标准,在这个屏幕上1px = 1dp,其他屏幕可以进行比例换算,例如同样是100dp的长度,在mdpi中为100px,而hdpi中为150px。也就是说在mdpi中1dp = 1px,而hdpi中1dp = 1.5px,在xdpi中1dp = 2px,在xxhpi中1dp = 3px

各分辨率换算比率
ldpi :mdpi :hdpi :xhdpi :xxhdpi = 3:4:6:8:12

单位换算

public class DisplayUtils {

    /**
     * 获得屏幕宽度(像素)
     *
     * @param activity
     * @return
     */
    public static int getDisplayWidth(Activity activity) {
        DisplayMetrics metric = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(metric);
        int width = metric.widthPixels;     // 屏幕宽度(像素)
        return width;
    }

    /**
     * 获得屏幕高度(像素)
     *
     * @param activity
     * @return
     */
    public static int getDisplayHeight(Activity activity) {
        DisplayMetrics metric = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(metric);
        int height = metric.heightPixels;     // 屏幕高度(像素)
        return height;
    }


    /**
     * 将px值转换为dip或dp值,保证尺寸大小不变
     *
     * @param context 通过上下文获得显示参数中的屏幕密度
     * @param pxValue 需要转换的px值
     * @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 需要转换的dp值
     * @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 需要转换的px值
     * @return
     */
    public static int px2sp(Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }


    /**
     * 将sp值转换为px值,保证文字大小不变
     *
     * @param context 通过上下文获得显示参数中的屏幕密度
     * @param spValue 需要转换的sp值
     * @return
     */
    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }
}

Android绘图技巧

2D绘图技巧

API 绘制(6)
drawPoint()
drawLine() 线
drawsLine() 多条线
drawRect() 矩形
drawRoundRect() 圆角矩形
drawVertices() 多边形
drawArc() 弧、扇
drawCircle()
drawOval() 椭圆
drawText() 绘制文本
drawPosText() 在指定位置绘制文本
drawPath() 绘制路径
drawBitmap() 绘制Bitmap(加载)
API 设置属性
setAntiAlias() 设置画笔锯齿效果
setColor() 设置画笔颜色
setARGB() 设置画笔A,R,G,B值
setAlpha() 设置画笔Alpha值
setTextSize() 设置字体尺寸
setStyle() 设置画笔风格(空心或实心)
setStrokeWidth() 设置空心边框的宽度
reset() 重置

绘制的实例
http://blog.csdn.net/rhljiayou/article/details/7212620

Android XML绘图

Bitmap

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

Shape

<?xml version="1.0" encoding="utf-8"?>
<shape    
    xmlns:android="http://schemas.android.com/apk/res/android"    
    android:shape=["rectangle" | "oval" | "line" | "ring"] >    
    <corners        //当shape为rectangle时使用
        android:radius="integer"        //半径值会被后面的单个半径属性覆盖,默认为1dp
        android:topLeftRadius="integer"        
        android:topRightRadius="integer"        
        android:bottomLeftRadius="integer"        
        android:bottomRightRadius="integer" />    
    <gradient       //渐变
        android:angle="integer"        
        android:centerX="integer"        
        android:centerY="integer"        
        android:centerColor="integer"        
        android:endColor="color"        
        android:gradientRadius="integer"        
        android:startColor="color"        
        android:type=["linear" | "radial" | "sweep"]        
        android:useLevel=["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>

Layer 层


<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="10.0dp"
               android:top="10.0dp"
               android:right="10.0dp"
               android:bottom="10.0dp"/>
    ......
</layer-list>

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:drawable="@drawable/X2" android:state_window_focused="false"/>
    <!-- 非触摸模式下获得焦点并单击时的背景图片 -->
    <item android:drawable="@drawable/X3" android:state_focused="true" android:state_pressed="true"/>
    <!-- 触摸模式下单击时的背景图片-->
    <item android:drawable="@drawable/X4" android:state_focused="false" android:state_pressed="true"/>
    <!--选中时的图片背景-->
    <item android:drawable="@drawable/X5" android:state_selected="true"/>
    <!--获得焦点时的图片背景-->
    <item android:drawable="@drawable/X6" android:state_focused="true"/>
</selector>

Android绘图技巧

Canvas

API 作用
Canvas.save() 保存画布(类似PS中的图层保存)
Canvas.restore() 合并画布(类似PS中的合并图层)
Canvas.translate() 画布所在坐标系平移
Canvas.rotate() 画布所在坐标系旋转

Layer 层

API 作用
saveLayer() 将图层入栈
saveLayerAlpha() 将图层入栈
restore() 将图层出栈
restoreCount() 将图层出栈
@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawColor(Color.WHITE);
        p.setColor(Color.BLUE);
        canvas.drawCircle(150, 150, 100, p);

        // 图一
        canvas.saveLayerAlpha(0, 0, 400, 400, 127, LAYER_TYPE_NONE);
        // 图二
//        canvas.saveLayerAlpha(0, 0, 400, 400, 255, LAYER_TYPE_NONE);
        p.setColor(Color.RED);
        canvas.drawCircle(200, 200, 100, p);
        canvas.restore();
    }

图一,透明度为127时,为半透明状态 图二,透明度设置为255时,完全不透明

Android图像处理技巧

色彩矩阵分析

// ---- 施工中(8月2日--6日) ----


SurfaceView的使用

SurfaceView和View的区别

SurfaceView的使用

 @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {

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

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

    }

    @Override
    public void run() {

    }
private SurfaceHolder mHolder;
private Canvas mCanvas;
private boolean mIsDrawing;

private void init() {    
     mHolder = getHolder(); 
     mHolder.addCallback(this);
}
API 作用
lockCanvas() 获得当前Canvas对象
drawColor() 清屏
public class SurfaceViewDemo extends SurfaceView implements Runnable, SurfaceHolder.Callback {

    private SurfaceHolder mHolder;
    private Canvas mCanvas;
    private boolean mIsDrawing;         // 子线程标志位

    public SurfaceViewDemo(Context context) {
        super(context);
        initView();
    }

    private void initView() {
        mHolder = getHolder();
        mHolder.addCallback(this);

        setFocusable(true);
        setFocusableInTouchMode(true);
        this.setKeepScreenOn(true);
        // mHolder.setFormat(PixelFormat.OPAQUE);
    }


    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        mIsDrawing = true;
        new Thread(this).start();
    }

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

    }

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

    @Override
    public void run() {
        while (mIsDrawing) {
            draws();
        }
    }

    public void draws() {
        try {
            mCanvas = mHolder.lockCanvas();
        } catch (Exception e) {
            
        } finally {
            if (mCanvas != null) {
                mHolder.unlockCanvasAndPost(mCanvas);
            }
        }
    }
}

SurfaceView实例

1. 正选曲线

@Override
    public void run() {
        while (mIsDrawing) {
            draws();
            x += 1;
            y = (int) (100 * Math.sin(x * 2 * Math.PI/180) + 400);
            mPath.lineTo(x, y);
        }
    }

    private void draws() {
        try {
            mCanvas = mHolder.lockCanvas();
            // Surface背景
            mCanvas.drawColor(Color.WHITE);
            mCanvas.drawPath(mPath, mPaint);
        } catch (Exception e) {

        } finally {
            if (mCanvas != null) {
                mHolder.unlockCanvasAndPost(mCanvas);
            }
        }
    }
绘制正弦曲线

2. 绘图板

private void draws() {
        try {
            mCanvas = mHolder.lockCanvas();
            // Surface背景
            mCanvas.drawColor(Color.WHITE);
            mCanvas.drawPath(mPath, mPaint);
        } catch (Exception e) {

        } finally {
            if (mCanvas != null) {
                mHolder.unlockCanvasAndPost(mCanvas);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mPath.moveTo(x,y);
                break;
            case MotionEvent.ACTION_MOVE:
                mPath.lineTo(x, y);
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }

画笔粗细没调。。
上一篇 下一篇

猜你喜欢

热点阅读