android自定義view控制元件之一圓角背景TextView
阿新 • • 發佈:2018-12-31
繼昨天寫了一個TextView可以包括兩種不同的風格字型,而保證可以換行的情況下的自定義View。今天的正文還是寫一個自定義的TextView。
一慣風格首先亮出實現效果,這最是直接不過的了。看下圖:
其實不通過寫一個自定義view的方式也可以實現這個效果,但是就需你在你class檔案中堆更多的程式碼了,這從軟體工程的思想是不可取的。所以還是為了不省事,去寫一個自定義的TextView控制元件吧。相信大家都會寫這種比較簡單的自定義view了。
首先給出這個自定義view的類RadioTextView,程式碼如下:
下面再給出在attrs.xml檔案中定義的styleable:package com.example.yuzhuo.view; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import com.example.yuzhuo.R; /** * Created by yuzhuo on 16/9/4. */ public class RadioTextView extends View{ /** * title文字 */ private String mTitleText; /** * title文字的顏色 */ private int mTitleTextColor; /** * titel文字的大小 */ private int mTitleTextSize; /** * background * @param context * @param attrs */ private int background; /** * 圓角大小 */ private int mCornerSize; /** * 繪製時控制文字繪製的範圍 */ private Rect mtitleBound; private Paint mtitlePaint; public RadioTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RadioTextView(Context context) { this(context, null); } /** * 獲得我自定義的樣式屬性 * * @param context * @param attrs * @param defStyle */ public RadioTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); /** * 獲得我們所定義的自定義樣式屬性 */ TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RaidoTextView, defStyle, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.RaidoTextView_titleText: mTitleText = a.getString(attr); break; case R.styleable.RaidoTextView_titleTextColor: // 預設顏色設定為黑色 mTitleTextColor = a.getColor(attr, Color.BLACK); break; case R.styleable.RaidoTextView_titleTextSize: // 預設設定為16sp,TypeValue也可以把sp轉化為px mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics())); break; case R.styleable.RaidoTextView_background: //預設為白色 background = a.getColor(attr, Color.WHITE); break; case R.styleable.RaidoTextView_mCornerSize: //預設圓角為0 mCornerSize = a.getInteger(attr,0); break; } } a.recycle(); /** * 獲得繪製文字的寬和高 */ mtitlePaint = new Paint(); mtitlePaint.setTextSize(mTitleTextSize); mtitleBound = new Rect(); mtitlePaint.getTextBounds(mTitleText, 0, mTitleText.length(), mtitleBound); } @Override protected void onMeasure(int widthMeasureSpec, int 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 { mtitlePaint.setTextSize(mTitleTextSize); mtitlePaint.getTextBounds(mTitleText, 0, mTitleText.length(), mtitleBound); int desired = getPaddingLeft() + mtitleBound.width() + getPaddingRight(); width = desired<=widthSize?desired:widthSize; } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { mtitlePaint.setTextSize(mTitleTextSize); mtitlePaint.getTextBounds(mTitleText, 0, mTitleText.length(), mtitleBound); int desired = getPaddingTop() + mtitleBound.height() + getPaddingBottom(); height = desired<=heightSize?desired:heightSize; } setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG); paint.setAntiAlias(true); paint.setColor(background); RectF rec = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()); canvas.drawRoundRect(rec, mCornerSize, mCornerSize, paint); mtitlePaint.setColor(mTitleTextColor); Paint.FontMetricsInt fontMetrics = mtitlePaint.getFontMetricsInt(); int baseline = (getMeasuredHeight() - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top; canvas.drawText(mTitleText,getPaddingLeft(), baseline, mtitlePaint); } }
最後給出layout.xml中如何寫義的佈局檔案程式碼:<declare-styleable name="RaidoTextView"> <attr name="titleText" format="string" /> <attr name="background" format="color"/> <attr name="titleTextSize" format="dimension"/> <attr name="titleTextColor" format="color"/> <attr name="mCornerSize" format="integer"/> </declare-styleable>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" <span style="color:#ff6666;">xmlns:radiostyle="http://schemas.android.com/apk/res-auto"</span> android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.yuzhuo.MainActivity" > <com.example.yuzhuo.view.RadioTextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" <span style="color:#ff0000;">radiostyle:titleText = "我是中國人" radiostyle:titleTextColor = "#ffffff" radiostyle:titleTextSize = "18sp" radiostyle:background ="#00ffff" radiostyle:mCornerSize = "18"/</span>> <com.example.yuzhuo.view.RadioTextView android:id="@+id/textView2" android:layout_marginTop="30dp" android:layout_below="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" radiostyle:titleText = "我是中國人" radiostyle:titleTextColor = "#ffffff" radiostyle:titleTextSize = "18sp" radiostyle:background ="#ff00ff" radiostyle:mCornerSize = "12"/> <com.example.yuzhuo.view.RadioTextView android:id="@+id/textView3" android:layout_marginTop="30dp" android:layout_below="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" radiostyle:titleText = "我是中國人" radiostyle:titleTextColor = "#ffffff" radiostyle:titleTextSize = "18sp" radiostyle:background ="#ffff00" radiostyle:mCornerSize = "6"/> </RelativeLayout>
<span style="color:#ff6666;">xmlns:radiostyle="http://schemas.android.com/apk/res-auto"</span>
上面程式碼紅色標註出來的是,為你自定義的styleabe這義的標籤模式,這個名字可以隨意,只是需要與下面使用的時候保持一致,否則layout佈局載入的時候會造成識別不出來,而導致出錯。
這是一個特別簡單的自定義view控制元件,實現了個圓角背景的textview,但是通過最簡單的自定義view的編寫,可以很輕鬆的去了解和掌握自定義view控制元件的原理。
還是那句話,歡迎大家批評指正。手下點贊。需要專案工程的可以在github上面下載到,這個是連結點選開啟連結