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

首頁 > 系統 > Android > 正文

Android重寫View實現全新的控件

2019-12-12 06:26:36
字體:
來源:轉載
供稿:網友

通常情況下,Android實現自定義控件無非三種方式。

  Ⅰ、繼承現有控件,對其控件的功能進行拓展。

  Ⅱ、將現有控件進行組合,實現功能更加強大控件。

  Ⅲ、重寫View實現全新的控件

  本文來討論最難的一種自定義控件形式,重寫View來實現全新的控件。

  首先,我們要明白在什么樣的情況下,需要重寫View來實現一種全新的控件,一般當我們遇到了原生控件無法滿足我們現有的需求的時候,我們此時就可以考慮創建一個全新的View來實現我們所需要的功能。創建一個全新View實現自定義控件,無非分成這么幾步:

  Ⅰ、在OnMeasure()方法中,測量自定義控件的大小,使自定義控件能夠自適應布局各種各樣的需求。

  Ⅱ、在OnDraw()方法中,利用哼哈二將(Canvas與Paint)來繪制要顯示的內容。

  Ⅲ、在OnLayout()方法中來確定控件顯示位置。

  Ⅳ、在OnTouchEvent()方法處理控件的觸摸事件。

  相應的思維導圖如下:

  多說無益,我們通過幾個小案例,來講解到底如何實現自定義控件。

一、一個帶有比例進度的環形控件

   首先看一下這個控件的示意圖: 

  通過這個簡單的示意圖,我們對于項目所完成的比例,就一目了然了。通過這個簡單的示意圖,我們可以很快速的把這個圖形分成三個部分。Ⅰ、外層的環,Ⅱ、里面的園,三、相應文字。有了這個思路以后,我們只需要在onDraw()方法中一個個進行繪制罷了。我這里為了簡單起見,把這個控件的寬度設置為屏幕的寬度。

  首先,還是老樣子,為自定義控件設置一些自定義屬性,便于調用者對其進行擴展,自定義屬性的設置代碼為:

 <declare-styleable name="circleView">  <attr name="textSize" format="dimension" />  <attr name="text" format="string" />  <attr name="circleColor" format="color" />  <attr name="arcColor" format="color" />  <attr name="textColor" format="color" />  <attr name="startAngle" format="integer" />  <attr name="sweepAngle" format="integer" /> </declare-styleable>

  Ⅰ、textSize――對應中間文本文字的大小

  Ⅱ、text――對應中間文本

  Ⅲ、circleColor――對應內圓的顏色

  Ⅳ、arcColor――對應外環的顏色

  Ⅴ、textColor――對應文本的顏色

  Ⅵ、startAngle――對應外環的起始角度

  Ⅶ、sweepAngle――對應外環掃描角度

  緊接著,就是在自定義控件的初始化方法中來獲取這些自定義屬性:

TypedArray ta = context.obtainStyledAttributes(attrs,    R.styleable.circleView);  if (ta != null) {   circleColor = ta.getColor(R.styleable.circleView_circleColor, 0);   arcColor = ta.getColor(R.styleable.circleView_arcColor, 0);   textColor = ta.getColor(R.styleable.circleView_textColor, 0);   textSize = ta.getDimension(R.styleable.circleView_textSize, 50);   text = ta.getString(R.styleable.circleView_text);   startAngle = ta.getInt(R.styleable.circleView_startAngle, 0);   sweepAngle = ta.getInt(R.styleable.circleView_sweepAngle, 90);   ta.recycle();  }

  這里在多說一嘴子,為了釋放更多的資源,一定要將TypedArray這個對象進行資源的釋放。

  接下來,在OnMeasure()方法中,初始化要繪制畫筆樣式,獲取屏幕的寬度,計算中間位置的坐標,以及指定外接矩形的寬高代碼如下:

 private void init() {  int length = Math.min(width, height);  mCircleXY = length / 2;  mRadius = length * 0.5f / 2;  mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);  mCirclePaint.setColor(circleColor);  mRectF = new RectF(length * 0.1f, length * 0.1f, length * 0.9f,    length * 0.9f);  mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  mArcPaint.setColor(arcColor);  mArcPaint.setStyle(Paint.Style.STROKE);  mArcPaint.setStrokeWidth((width * 0.1f));  mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  mTextPaint.setTextSize(textSize);  mTextPaint.setColor(textColor);  mTextPaint.setTextAlign(Align.CENTER); }

  將我們設置的自定義屬性,設置給不同筆刷。

  做了這么多準備以后,我們所需的就是在OnDraw方法中繪制內圓、外環與文字。代碼如下:

@Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  drawSth(canvas); } private void drawSth(Canvas canvas) {  canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);  canvas.drawArc(mRectF, startAngle, sweepAngle, false, mArcPaint);  canvas.drawText(text, 0, text.length(), mCircleXY, mCircleXY + textSize    / 4, mTextPaint); }

  需要指出的是,畫環形需要在一個指定矩形區域畫取,并且要指定起始角度,掃描角度,這些變量都是自定義屬性。 

  這個自定義控件的最終的運行效果為:

二、動態條形圖

  條形圖,應該在圖表展示系統中再普通不過的一種圖標了。靜態示意圖就像這樣:

  通過這個簡單的示意圖,我們所需要做的是,繪制一個個的矩形,然后將每一個矩形x坐標平移一定的單位,我們還看到這么一個現象:每個條形圖的起始點不一致,而終止點是一樣的。起始坐標用個Random(隨機函數)剛剛好,實現靜態條形圖就是這樣的思路:

   首先,在OnMeasure()方法中計算出每個矩形寬與高,這里為了方便起見,每個矩形默認的高為屏幕的高,每個矩形的寬這里定義為屏幕的寬度乘以80%除以矩形的個數。然后根據寬與高來初始化筆刷(Paint)。為什么要根據寬與高來初始化筆刷了,這里我為了使自定義View更加的逼真,我這里使用LinearGradient(線性渲染器)進行了渲染,這個對象需要使用矩形寬與高。需要指出來的是這個自定義控件是動態的,我只需要onDraw方法不斷發生重繪,這里為了防止控件刷新太快,我這里每隔300毫秒刷新視圖。這個控件的完整源代碼如下:

public class VolumneView extends View { private Paint mPaint; private int mCount; private int mWidth; private int mRectHeight; private int mRectWidth; private LinearGradient mLinearGradient; private double mRandom; private float mcurrentHeight; public static final int OFFSET = 5; public VolumneView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  initView(context, attrs); } private void initView(Context context, AttributeSet attrs) {  mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  mPaint.setColor(Color.GREEN);  mPaint.setStyle(Paint.Style.FILL);  TypedArray ta = context.obtainStyledAttributes(attrs,    R.styleable.volumneView);  if (ta != null) {   mCount = ta.getInt(R.styleable.volumneView_count, 6);   ta.recycle();  } } public VolumneView(Context context, AttributeSet attrs) {  this(context, attrs, 0); } public VolumneView(Context context) {  this(context, null); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {  super.onSizeChanged(w, h, oldw, oldh);  mWidth = getMeasuredWidth();  mRectHeight = getMeasuredHeight();  mRectWidth = (int) (mWidth * 0.8 / mCount);  mLinearGradient = new LinearGradient(0, 0, mRectWidth, mRectHeight,    Color.GREEN, Color.YELLOW, TileMode.CLAMP);  mPaint.setShader(mLinearGradient); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  for (int i = 0; i < mCount; i++) {   mRandom = Math.random();   mcurrentHeight = (float) (mRectHeight * mRandom);   float width = (float) (mWidth * 0.4 / 2 + OFFSET);   canvas.drawRect(width + i * mRectWidth, mcurrentHeight, width     + (i + 1) * mRectWidth, mRectHeight, mPaint);  }  postInvalidateDelayed(300); }


最終,運行效果如下:

  后記,通過這兩個簡單控件,相信大家對于自定義控件基本步驟有說了解,當然,要真正做好自定義控件的話,我們還需要按這個步驟一步步的來,加油!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 库尔勒市| 武陟县| 茶陵县| 东宁县| 阳原县| 余姚市| 登封市| 泰和县| 北安市| 育儿| 沈丘县| 河曲县| 太保市| 交城县| 图片| 黄龙县| 永和县| 水城县| 梅河口市| 牙克石市| 罗平县| 芜湖市| 台北县| 通城县| 杭锦旗| 柘荣县| 蒲城县| 连南| 六枝特区| 柞水县| 玉树县| 渭南市| 湘潭县| 舟山市| 当涂县| 苍梧县| 东光县| 兴山县| 华蓥市| 宜州市| 兴山县|