国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義View多種效果解析

2019-10-22 18:11:10
字體:
來源:轉載
供稿:網友

最近項目里涉及到自定義View的東西還是挺多的,所以打算在自定義View上多花點時間,也順便分享給大家。

先總結下自定義View的步驟:
1、自定義View的屬性
2、在View的構造方法中獲得我們自定義的屬性
[3、重寫onMeasure]
4、重寫onDraw

1.首先在我們的res/values/目錄下建立一個attrs.xml文件,然后在里面聲明我們我們需要的自定義屬性

Android,View

我們定義了矩形的顏色,矩形的高度,矩形的寬度3個屬性,format是指該屬性的取值類型:
一共有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;
不太明白的可以google一下
然后在布局中聲明我們的自定義View

Android,View

需要引入xmls:app="http://schemas.android.com/apk/res-auto"這樣就會自動查找我們的自定義屬性,也可以采用另外一種引入方式,xmlns:app="http://schemas.android.com/apk/res/com.example.administrator.demoone.customeview.CustomeRectView"
我們的命名空間,后面的包路徑指的是項目的package

2.在View的構造方法里獲取我們的自定義屬性

public class CustomeRectView extends View { private Paint mPiant;//定義畫筆對象 private int rectColor;//矩形的顏色 private int rectHeight;//矩形的高度 private int rectWidth;//矩形的寬度 public CustomeRectView(Context context) {  this(context, null); } public CustomeRectView(Context context, @Nullable AttributeSet attrs) {  this(context, attrs, 0); } public CustomeRectView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  /**   * 獲取我們自定義的屬性   */  TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CustomeRectView, defStyleAttr, 0);  int arrayCount = array.getIndexCount();  for (int i = 0; i < arrayCount; i++) {   int index = array.getIndex(i);   switch (index) {    case R.styleable.CustomeRectView_rectColor:     //getColor(int index,int defaultValue)     rectColor=array.getColor(R.styleable.CustomeRectView_rectColor, Color.BLACK);     break;    case R.styleable.CustomeRectView_rectHeight:     /**      * 獲取dimension值得時候會有3個不同的方法getDimension()、getDimensionPixelSize()和getDimenPixelOffset()      * 結果值都是將資源文件中定義的dip值乘以屏幕密度,即rectHeight*屏幕密度,只是getDimension()返回的是float,      * 其余兩個返回的是int, 其中getDimensionPixelSize()返回的是實際數值的四舍五入,      * 而getDimensionPixelOffset返回的是實際數值去掉后面的小數點;      */     rectHeight=array.getDimensionPixelOffset(R.styleable.CustomeRectView_rectHeight,200);     break;    case R.styleable.CustomeRectView_rectWidth:     rectWidth=array.getDimensionPixelOffset(R.styleable.CustomeRectView_rectWidth,200);     break;   }  }  array.recycle(); }}

我們重寫了3個構造方法,默認的布局文件調用的是兩個參數的構造方法,所以記得讓所有的構造調用我們的三個參數的構造,我們在三個參數的構造中獲得自定義屬性。

3.重寫OnDraw,調用系統的onMeasure

@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); mPiant=new Paint(); mPiant.setColor(rectColor);//設置畫筆的顏色 mPiant.setStyle(Paint.Style.FILL);//設置畫筆的樣式 mPiant.setAntiAlias(true);//去除鋸齒 /**  * Draw the specified Rect using the specified paint. The rectangle will  * be filled or framed based on the Style in the paint.  *  * @param left The left side of the rectangle to be drawn  * @param top The top side of the rectangle to be drawn  * @param right The right side of the rectangle to be drawn  * @param bottom The bottom side of the rectangle to be drawn  * @param paint The paint used to draw the rect  */ canvas.drawRect(0,0,getWidth(),getHeight(),mPiant);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec);}

此時的效果是:

Android,View

但是此時如果我們把布局文件的寬和高寫成wrap_content,去掉我們自定義的寬高屬性

Android,View

運行效果如下

Android,View

系統幫我們測量的高度和寬度都是MATCH_PARNET,當我們設置明確的寬度和高度時,系統幫我們測量的結果就是我們設置的結果,當我們設置為WRAP_CONTENT,或者MATCH_PARENT系統幫我們測量的結果就是MATCH_PARENT的長度。

所以,當設置了WRAP_CONTENT時,我們需要自己進行測量,即重寫onMesure方法”:
重寫之前先了解MeasureSpec的specMode,一共三種類型:
EXACTLY:一般是設置了明確的值或者是MATCH_PARENT
AT_MOST:表示子布局限制在一個最大值內,一般為WARP_CONTENT
UNSPECIFIED:表示子布局想要多大就多大,很少使用

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  int widthMode=MeasureSpec.getMode(widthMeasureSpec);  int widthSize=MeasureSpec.getSize(widthMeasureSpec);  int heightMode=MeasureSpec.getMode(heightMeasureSpec);  int heightSize=MeasureSpec.getSize(heightMeasureSpec);  int width;  int height;  //如果設置了明確的大小  if(widthMode==MeasureSpec.EXACTLY){   width=widthSize;  }else{   //設置寬   width=dpToPx(getContext(),200);  }  if(heightMode==MeasureSpec.EXACTLY){  height=heightSize;  }else{  //設置高   height=dpToPx(getContext(),200);  }  setMeasuredDimension(width,height); }  /** * 根據手機的分辨率從 dp 的單位 轉成為 px(像素) */ public int dpToPx(Context context, float dpValue){  final float scale=context.getResources().getDisplayMetrics().density;  return (int)(dpValue*scale+0.5f); }

此時的效果如下,就和我們在布局文件里設置的一樣了

Android,View

好了,后續還會陸續更新。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永德县| 娄烦县| 县级市| 通榆县| 米脂县| 澳门| 常德市| 涞水县| 泸西县| 横峰县| 瓦房店市| 中卫市| 扶沟县| 黔西| 南昌县| 丹寨县| 霍州市| 宁波市| 犍为县| 赞皇县| 乳山市| 县级市| 衡东县| 伊川县| 玉溪市| 达州市| 沭阳县| 正定县| 泾阳县| 禹城市| 顺义区| 天柱县| 安国市| 邵东县| 湘潭市| 枣强县| 韩城市| 昌邑市| 革吉县| 瓮安县| 嵩明县|