Android繪圖機制與處理技巧

一.屏幕的尺寸信息

1屏幕參數

  • 屏幕大小

    指屏幕對角線的長度,通常使用”寸”來度量,例如4.7寸手機 5.5寸手機等.

  • 分辨率

    分辨率是指手機屏幕的像素點個數,例如720*1280是指屏幕分變率,指寬有720個像素點,高有1280個像素點.

  • PPI

    每英寸像素(Pixels Per Inch)又被稱爲DPI(Dots Per Inch).它有對角線的像素點數除以屏幕的大小得到的.

2系統屏幕密度

系統定義了幾個標準的DPI值,作爲手機的固定DPI
此處輸入圖片的描述

3獨立像素密度dp

相同長度的屏幕,高密度的屏幕包含更多的像素點,Android系統使用mdpi即密度值爲160的屏幕作爲標準,在這個屏幕上1px=1dp.

各個分辨率直接的換算比例:ldpi:mdpi:xhdpi:xxhdpi=3:4:6:8:12

4單位換算

package com.jia.androidfirst;

import android.content.Context;

/**
 * dp sp 轉換爲px的工具類
 * 
 * @author aldrich
 *
 */
public class DisplayUtil {
    /**
     * 將px值轉換爲dip或dp值,保證尺寸大小不變
     * 
     * @param context
     * @param pxValue
     * @param scale
     *            (DisplayMetrics類中屬性density)
     * @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
     * @param scale
     *            (DisplayMetrics類中屬性density)
     * @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
     * @param fontScale
     *            (DisplayMetrics類中屬性scaledDensity)
     * @return
     */
    public static int px2sp(Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValue / fontScale + 0.5);
    }

    /**
     * 將sp值轉換爲px值,保證文字大小不變
     * 
     * @param context
     * @param spValue
     * @param fontScale
     *            (DisplayMetrics類中屬性scaledDensity)
     * @return
     */
    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }
}

其實的density就是前面所說的換算比例,這裏使用的是公式換算方法進行轉換,同時系統也提供了TypedValue幫助我們轉換

 /**
     * dp2px
     * @param dp
     * @return
     */
    protected int dp2px(int dp){
        return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,getResources().getDisplayMetrics());
    }

    /**
     * sp2px
     * @param dp
     * @return
     */
    protected int sp2px(int sp){
        return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,sp,getResources().getDisplayMetrics());
    }

二.2D繪圖基礎

通過Canvas對象提供的各種繪製圖像的API:
drawPoint(點)/drawLine(線)/drawRect(矩形)/drawVertices(多邊形)/drawArc(弧)/drawCircle(圓).

  • setAntiAlias(); //設置畫筆的鋸齒效果
  • setColor(); //設置畫筆的顏色
  • setARGB(); //設置畫筆的A R G B值
  • setAlpha(); //設置畫筆的Alpha值
  • setTextSize(); //設置字體的尺寸
  • setStyle(); //設置畫筆的風格(空心或實心)
  • setStrokeWidth(); //設置空心邊框的寬度

  • DrawPoint,繪製點

    canvas.drawPoint(x,y,paint);

  • DrawLine,繪製直線

    canvas.drawLine(startX,startY,endX,endY,paint);

  • DrawLines,繪製多條直線

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

  • DrawRect,繪製矩形

    canvas.drawRect(left,top,right,bottom,paint);

  • DrawRoundRect,繪製圓角矩形

    canvas.drawRoundRect(left,top,right,bottom,radiusX,radiusY,paint);

  • DrawCircle,繪製圓

    canvas.drawCircle(circleX,circleY,radius,paint);

  • DrawArc,繪製弧形 扇形

    paint.setStyle(Paint.style.STROKE);
    canvas.drawArc(left,top,right,bottom,startAngle,sweepAngle,useCenter,paint);
    繪製弧形與扇形的區分就是倒數第二個參數useCenter的區別

  • DrawOval,繪製橢圓

    //通過橢圓的外接矩形來繪製橢圓
    canvas.drawOval(left,top,right,bottom,paint);

  • DrawText,繪製文本

    canvas.drawText(text,startX,startY,paint);

  • DrawPosText,在指定位置繪製文本

    canvas.drawPosText(text,new float[]{X1,Y1,X2,Y2,……Xn,Yn},paint);

  • DrawPath,繪製路徑

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

三.Android XML 繪圖

XML在安卓系統中可不僅僅是JAVA中的一個佈局文件配置列表,在安卓開發者的手頭上他甚至可以變成一張畫,一幅畫,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="@mipmap/ic_launcher">

</bitmap>

通過這樣引用圖片就可以將圖片直接轉化成Bitmap讓我們在程序中使用

2.Shape

通過Shape可以繪製各種圖形,下面展示一下shape的參數

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"

    android:shape="rectangle">
    <!--默認是rectangle-->

    <!--當shape= rectangle的時候使用-->
    <corners
        android:bottomLeftRadius="1dp"
        android:bottomRightRadius="1dp"
        android:radius="1dp"
        android:topLeftRadius="1dp"
        android:topRightRadius="1dp" />
    <!--半徑,會被後面的單個半徑屬性覆蓋,默認是1dp-->

    <!--漸變-->
    <gradient
        android:angle="1dp"
        android:centerColor="@color/colorAccent"
        android:centerX="1dp"
        android:centerY="1dp"
        android:gradientRadius="1dp"
        android:startColor="@color/colorAccent"
        android:type="linear"
        android:useLevel="true" />

    <!--內間距-->
    <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="1dp" />

    <!--大小,主要用於imageview用於scaletype-->
    <size
        android:width="1dp"
        android:height="1dp" />

    <!--填充顏色-->
    <solid android:color="@color/colorAccent" />

    <!--指定邊框-->
    <stroke
        android:width="1dp"
        android:color="@color/colorAccent" />
    <!--虛線寬度-->
    android:dashWidth= "1dp"

    <!--虛線間隔寬度-->
    android:dashGap= "1dp"

</shape>

shape可以說是xml繪圖的精華所在,而且功能十分的強大,無論是扁平化,擬物化還是漸變,都是十分的OK,我們現在來做一個陰影的效果

<?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

Layer是在PhotoShop中是非常常用的功能,在Android中,我們同樣可以實現圖層的效果

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--圖片1-->
    <item android:drawable="@mipmap/ic_launcher"/>

    <!--圖片2-->
    <item
        android:bottom="10dp"
        android:top="10dp"
        android:right="10dp"
        android:left="10dp"
        android:drawable="@mipmap/ic_launcher"
        />

</layer-list>

4.Selector

Selector的作用是幫助開發者實現靜態View的反饋,通過設置不同的屬性呈現不同的效果

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 默認時候的背景-->
    <item android:drawable="@mipmap/ic_launcher" />

    <!-- 沒有焦點時候的背景-->
    <item android:drawable="@mipmap/ic_launcher" android:state_window_focused="false" />

    <!-- 非觸摸模式下獲得焦點並點擊時的背景圖片-->
    <item android:drawable="@mipmap/ic_launcher" android:state_pressed="true" android:state_window_focused="true" />

    <!-- 觸摸模式下獲得焦點並點擊時的背景圖片-->
    <item android:drawable="@mipmap/ic_launcher" android:state_focused="false" android:state_pressed="true" />

    <!--選中時的圖片背景-->
    <item android:drawable="@mipmap/ic_launcher" android:state_selected="true" />

    <!--獲得焦點時的圖片背景-->
    <item android:drawable="@mipmap/ic_launcher" android:state_focused="true" />

</selector>

這一方法可以幫助開發者迅速製作View的反饋,通過配置不同的觸發事件,selector會自動選中不同的圖片,特別是自定義button的時候,而我們不再使用原生單調的背景,而是使用selector特別製作的背景,就能完美實現觸摸反饋了

通常情況下,上面提到的這些方法都可以共同實現,下面這個例子就展示了在一個selector中使用shape作爲他的item的例子,實現一個具體點擊反饋效果的,圓角矩形的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="#33444444" />
            <!--設置按鈕的四個角爲弧形-->
            <corners android:radius="5dp" />
            <!--間距-->
            <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
        </shape>
    </item>

    <item>
        <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>

我們來看一下效果圖

這裏寫圖片描述

四.繪圖技巧

在Android中,默認的座標零點位於屏幕左上角,向下爲Y軸正方向,向右爲X軸正方向.

1.Canvas

canvas中常用方法:

  • Canvas.save():將之前的所有已繪製圖像保存起來,讓後續的操作就好像在一個新的圖層操作
  • Canvas.restore():合併圖層操作,將我們在save()之後繪製的所有圖像,與sava()之前的圖像進行合併.
  • Canvas.translate():座標平移,調用translate(x,y)方法之後,則將原點(0,0)移動到了(x,y).之後的所有繪圖操作都將以(x,y)爲原點進行.
  • Canvas.rotate():翻轉,將座標系旋轉了一定的角度.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章