(一)概述
虽然,已经学过了Android绘图的内容,但是总是觉得很模糊,今天就好好梳理下思路吧!纯粹就是一个读书笔记,整理下自己以前不知道的内容,好了开始:(本节主要介绍一些Drawable的常用方法及其xml定义,如果你已经很熟悉了,就跳过吧)
(二)Android屏幕适配问题
Android屏幕适配和兼容,一直都是非常头疼的问题,如何才能在不同的屏幕尺寸的手机上图片效果显示不失真!现在看看屏幕这个渣渣的相关参数吧:
NO.1———-屏幕相关的参数
1)屏幕大小
指的是屏幕对角线的长度,通常使用“寸”来计量,参见的有4.7寸手机,5.5寸手机;
2)分辨率
指的是手机屏幕的像数点个数,比如:720X1280就是指屏幕的分辨率,指的是宽720个像数点,而高有1280个像数点。
3)PPI
每英寸像数又被称为DPI ,它就是由对角线的像数点除以屏幕的大小得到的;
NO.2———-系统屏幕密度
由于国内厂商很多,要适配每一款手机的屏幕大小,那几乎是不可能的,所以系统定义了几个标准的DPI值,作为手机的固定DPI值,so 你需要适配这几个标准的DPI差不多就可以了!瞬间开心了许多,标准屏幕密度如下:
No.2 独立像数密度dp
正是由于各种屏幕密度的不同,导致同样像数大小的长度,在不同密度的屏幕上显示长度不同,这很容易理解长度完全相同,密度大的在单位面积上的像数点要多,相反,则会少;
Android系统使用mdpi即密度为160的屏幕作为标准,在这个屏幕上 1px = 1 dp ,其他屏幕则可以通过比例进行换算;那么如何进行换算呢?就像下面这样,各个分辨率直接的换算比例:
No.3 单位转换
各种类型转换全在这里了,你可以把它保存在项目中进行使用;
import android.content.Context;
import android.util.TypedValue;
/**
* Created by Eillot on 2016/7/18.
*
* dp , sp 转化为px的工具类
*/
public class DisplayUtil {
/**
* 将px值转换为dip或dp值 ,保证尺寸大小不变
* <p/>
* (DisplayMetrics类中属性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 值 ,保证尺寸大小不变
* <p/>
* (DisplayMetrics类中属性density)
*
* @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);
}
/**
* 将 ps 值转换为 sp 值 ,保证尺寸大小不变
* <p/>
* ( DisplayMetrics 类中属性 scaledDensity )
*
* @param context
* @param pxValue
* @return
*/
public static int px2sp(Context context, float pxValue) {
final float fontscale = context.getResources().getDisplayMetrics()
.scaledDensity;
return (int) (pxValue / fontscale + 0.5f);
}
/**
* 将 sp 值转换为 px 值 ,保证尺寸大小不变
* <p/>
* ( DisplayMetrics 类中属性 scaledDensity )
*
* @param context
* @param spValue
* @return
*/
public static int sp2px(Context context, float spValue) {
final float fontscale = context.getResources().getDisplayMetrics()
.scaledDensity;
return (int) (spValue / fontscale + 0.5f);
}
/**
* 其中density就是前面所说的换算比例。
* 这里使用的是使用公式换算方法进行转换,
* 同时系统也提供了TypeValue类帮助我们转换,
* 代码如下
*/
/**
*
* dp2px
* @param dp
* @return
*/
protected int dp2px( int dp ){
return (int)TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp ,
getResources().getDisplayMetrics());
}
/**
*
* sp2px
*/
protected int sp2px( int sp ){
return (int)(TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
sp ,
getResources().getDisplayMetrics());
}
}
(三)2D绘图基础
其实Canvas跟Paint非常好理解,相信大家对下面这个东东很熟悉吧!
对照起来,非常好理解,各种属性妥妥的懂了!
先看下Paint(画笔)的属性:
就这么多了,我挑几个常用的说下,其他自己用的时候谷歌~
下面演示各种效果:
代码模板:
/**
* Created by Eillot on 2016/7/18.
*/
public class DrawShape extends View {
/**
*
* 颜色
*/
private int mClor = Color.RED;
/**
*
* 画笔
*/
private Paint mpaint;
public DrawShape(Context context) {
super(context);
initView();
}
public DrawShape(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public DrawShape(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
mpaint = new Paint();
mpaint.setColor(mClor);
mpaint.setStrokeWidth(36f); //边框粗细程度
mpaint.setStyle(Paint.Style.FILL);//实心
// mpaint.setStyle(Paint.Style.STROKE);//空心
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//在这里添加代码
canvas.drawRect(0 , 0 , 100 , 100 , mpaint);
}
}
下面改变OnDraw()中canvas.drawXXX()即可;
1) mpaint.setStyle(Paint.Style.FILL);//实心
2) mpaint.setStyle(Paint.Style.STROKE);//空心
未设置变宽的粗细程度,使用的是默认值
另外,请你思考下:
为什么我把 canvas.drawRect(0 , 0 , 100 , 100 , mpaint);改为 canvas.drawRect(100, 100 , 100 , 100 , mpaint);绘制的图形是长方形,而不是正方形,照理说,边长相等应该为正方形?
我的xml文件:
<com.mydraw2.DrawShape
android:id="@+id/my_views"
android:layout_width="match_parent"
android:layout_height="100dp" />
下面咱们继续:
用于画点:
canvas.drawPoint( 400 , 400 , mpaint);
绘制直线:
canvas.drawLine(0,0,300 , 300 ,mpaint);
绘制多条线:
float[] pts={50,50,400,50,
400,50,400,600,
400,600,50,600,
60,600,50,50};
canvas.drawLines(pts ,mpaint);
最终将绘制成一个竖直的长方形;
绘制圆角矩形:
canvas.drawRoundRect( new RectF( 10 , 10 , 210 , 210 ) , 15 , 15 ,mpaint);
绘制圆形:
canvas.drawCircle(100,100,50,mpaint);
绘制弧形:
canvas.drawArc( new RectF( 0,0,100,100) , 0 , 270 , true ,mpaint);
Paint.Style.STROKE + userCenter(true); -----的情况就像下面
Paint.Style.STROKE + userCenter(flase);-----的情况就像下面
Paint.Style.FILL + userCenter(flase);-----的情况就像下面
Paint.Style.FILL + userCenter(true);-----的情况就像下面
绘制椭圆:
canvas.drawOval( new RectF( 20 ,20,200,300 ) , mpaint);
绘制文字:
canvas.drawText("H e l l o" ,50,50,mpaint);
沿着路径进行绘制文本:
Path path = new Path();
path.moveTo( 50 , 50 );
path.lineTo( 100 , 100 );
path.lineTo( 200 , 200 );
path.lineTo( 300 , 300 );
path.close();
canvas.drawTextOnPath("H e l l o" ,path,50,50,mpaint);
(四)Android XMl绘图
No.1 ——Bitmap
在XML中使用Bitmap非常简单,标签更改为<bitmap />
再在里面添加src元素引用图片即可;就像这样
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android">
android:src="@drawable/ic_launcher"
</bitmap>
No.2 ——–Shape
使用Shape可以在xml中绘制就像这样:(不需要死记住,用的时候查下)
No.3 ——–Layer图层
xml定义非常简单,就像这样:(我直接拿上用了)
No.4 ——-Selector(没什么好说的,就是各种属性配置)
好了,Draw各种xml定义就到这里吧,大概有个印象就可以了,用不着死记,用的时候回来查查就ok了,下节说说徐大神带给我们的绘图技巧!