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

首頁 > 系統 > Android > 正文

Android自定義控件之自定義屬性(二)

2019-12-12 05:50:30
字體:
來源:轉載
供稿:網友

前言:
上篇介紹了自定義控件的基本要求以及繪制的基本原理,本篇文章主要介紹如何給自定義控件自定義一些屬性。本篇文章將繼續以上篇文章自定義圓形百分比為例進行講解。有關原理知識請參考Android自定義控件基本原理詳解(一)這篇文章。 

需求產生背景:
為何要引入自定義屬性?當Android提供的原生屬性不能滿足實際的需求的時候,比如我們需要自定義圓形百分比半徑大小、圓形背景、圓形顯示的位置、圓形進度的背景等等。這個時候就需要我們自定義屬性了。 

自定義屬性步驟:
1.)在res/values文件下添加一個attrs.xml文件,如果項目比較大的話,會導致attrs.xml代碼相當龐大,這時可以根據相應的功能模塊起名字,方便查找,例如:登錄模塊相關attrs_login.xml 

<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="RoundImageView">  <attr name="borderRadius" />  <attr name="type" /> </declare-styleable></resources>

2.)如何聲明一組屬性 
使用<declare-styleable name="PercentView"></declare-styleable>來定義一個屬性集合,name就是屬性集合的名字,這個名字一定要起的見名知意。 

 <declare-styleable name="PercentView"> <!--添加屬性--> </declare-styleable> 

然后就是定義屬性值了,通過<attr name="textColor" format="color" /> 方式定義屬性值,屬性名字同樣也要起的見名知意,format表示這個屬性的值的類型,類型有以下幾種:
 •reference:引用資源
 •string:字符串
 •Color:顏色
 •boolean:布爾值
 •dimension:尺寸值
 •float:浮點型
 •integer:整型
 •fraction:百分數
 •enum:枚舉類型
 •flag:位或運算 

基于上面的要求,我們可以定義一下百分比控件屬性

 <declare-styleable name="PercentView">  <attr name="percent_circle_gravity"><!--圓形繪制的位置-->   <flag name="left" value="0" />   <flag name="top" value="1" />   <flag name="center" value="2" />   <flag name="right" value="3" />   <flag name="bottom" value="4" />  </attr>  <attr name="percent_circle_radius" format="dimension" /><!--圓形半徑-->  <attr name="percent_circle_progress" format="integer" /><!--當前進度值-->  <attr name="percent_progress_color" format="color" /><!--進度顯示顏色-->  <attr name="percent_background_color" format="color" /><!--圓形背景色--> </declare-styleable>

3.)布局中如何使用 

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:lee="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.whoislcj.views.PercentView  android:layout_width="200dp"  android:layout_height="200dp"  android:layout_margin="10dp"  android:background="@color/red"  android:padding="10dp"  lee:percent_background_color="@color/gray"  lee:percent_circle_gravity="left"  lee:percent_circle_progress="30"  lee:percent_circle_radius="50dp"  lee:percent_progress_color="@color/blue" /></LinearLayout>

為屬性集設置一個屬性集名稱,我這里用的lee,我這是因為實在想不起使用什么屬性集名稱了,建議在真正的項目中使用項目的縮寫,比如微信可能就是使用wx。 

4.)自定義控件中如何獲取自定義屬性 
每一個屬性集合編譯之后都會對應一個styleable對象,通過styleable對象獲取TypedArray typedArray,然后通過鍵值對獲取屬性值,這點有點類似SharedPreference的取法。 

 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PercentView); if (typedArray != null) {  backgroundColor = typedArray.getColor(R.styleable.PercentView_percent_background_color, Color.GRAY);  progressColor = typedArray.getColor(R.styleable.PercentView_percent_progress_color, Color.BLUE);  radius = typedArray.getDimension(R.styleable.PercentView_percent_circle_radius, 0);  progress = typedArray.getInt(R.styleable.PercentView_percent_circle_progress, 0);  gravity = typedArray.getInt(R.styleable.PercentView_percent_circle_gravity, CENTER);  typedArray.recycle();  }

5.)完整示例 

public class PercentView extends View { private final static String TAG = PercentView.class.getSimpleName(); private Paint mPaint; private int backgroundColor = Color.GRAY; private int progressColor = Color.BLUE; private float radius; private int progress; private float centerX = 0; private float centerY = 0; public static final int LEFT = 0; public static final int TOP = 1; public static final int CENTER = 2; public static final int RIGHT = 3; public static final int BOTTOM = 4; private int gravity = CENTER; private RectF rectF; //用于定義的圓弧的形狀和大小的界限 public PercentView(Context context) {  super(context);  init(); } public PercentView(Context context, AttributeSet attrs) {  super(context, attrs);  initParams(context, attrs);  init(); } public PercentView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  initParams(context, attrs);  init(); } private void init() {  mPaint = new Paint();  mPaint.setAntiAlias(true);  rectF = new RectF(); } private void initParams(Context context, AttributeSet attrs) {  mPaint = new Paint();  mPaint.setAntiAlias(true);  rectF = new RectF();  TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PercentView);  if (typedArray != null) {   backgroundColor = typedArray.getColor(R.styleable.PercentView_percent_background_color, Color.GRAY);   progressColor = typedArray.getColor(R.styleable.PercentView_percent_progress_color, Color.BLUE);   radius = typedArray.getDimension(R.styleable.PercentView_percent_circle_radius, 0);   progress = typedArray.getInt(R.styleable.PercentView_percent_circle_progress, 0);   gravity = typedArray.getInt(R.styleable.PercentView_percent_circle_gravity, CENTER);   typedArray.recycle();  } } @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);  Log.e(TAG, "onMeasure--widthMode-->" + widthMode);  switch (widthMode) {   case MeasureSpec.EXACTLY://    break;   case MeasureSpec.AT_MOST:    break;   case MeasureSpec.UNSPECIFIED:    break;  }  Log.e(TAG, "onMeasure--widthSize-->" + widthSize);  Log.e(TAG, "onMeasure--heightMode-->" + heightMode);  Log.e(TAG, "onMeasure--heightSize-->" + heightSize);  int with = getWidth();  int height = getHeight();  Log.e(TAG, "onDraw---->" + with + "*" + height);  centerX = with / 2;  centerY = with / 2;  switch (gravity) {   case LEFT:    centerX = radius + getPaddingLeft();    break;   case TOP:    centerY = radius + getPaddingTop();    break;   case CENTER:    break;   case RIGHT:    centerX = with - radius - getPaddingRight();    break;   case BOTTOM:    centerY = height - radius - getPaddingBottom();    break;  }  float left = centerX - radius;  float top = centerY - radius;  float right = centerX + radius;  float bottom = centerY + radius;  rectF.set(left, top, right, bottom); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) {  super.onLayout(changed, left, top, right, bottom);  Log.e(TAG, "onLayout"); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  mPaint.setColor(backgroundColor);  // FILL填充, STROKE描邊,FILL_AND_STROKE填充和描邊  mPaint.setStyle(Paint.Style.FILL_AND_STROKE);  canvas.drawCircle(centerX, centerY, radius, mPaint);  mPaint.setColor(progressColor);  double percent = progress * 1.0 / 100;  int angle = (int) (percent * 360);  canvas.drawArc(rectF, 270, angle, true, mPaint); //根據進度畫圓弧 }}

運行結果:
 根據不同的配置顯示的兩種效果

 

小結: 
通過自定義屬性可以達到自定義的控件也能像原生的控件一樣實現可配置。但是在實際的項目開發中,像本文介紹的這種自定義控件使用頻率并不是最高的,使用頻率較高的是通過自定義一個組合控件的方式,來達到布局文件的復用,以減少項目維護成本以及開發成本,下篇文章將重點介紹如何自定義控件組合,點擊查看。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武定县| 同江市| 枣阳市| 闻喜县| 津市市| 南木林县| 甘德县| 牙克石市| 小金县| 澄江县| 晋城| 靖江市| 鲁甸县| 大荔县| 嘉义县| 保定市| 卓资县| 大姚县| 驻马店市| 花莲市| 尼木县| 玉树县| 青冈县| 延边| 达孜县| 尖扎县| 洪泽县| 丰都县| 五常市| 深水埗区| 南城县| 清丰县| 冕宁县| 营口市| 临汾市| 新源县| 兴和县| 博爱县| 兴和县| 伊春市| 揭西县|