Android自定義View實戰-通知紅點


前言
今天呢想做一個通知紅點。本來想直接用TextView再套個background就好了。可是TextView有很多屬性,能用到的只有一小部分,所以索性想自定義個干干凈凈的View,順便學習一下自定義View的知識。
由於剛剛入自定義View的坑,做的比較簡單...
正文
在values文件夾建立attrs.xml文件,里面寫上你需要的屬性

<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="myText" format="string" /> <attr name="myTextColor" format="color" /> <attr name="myTextSize" format="dimension" /> <attr name="myBackground" format="color" /> <attr name="myShape" format="string" /> <declare-styleable name="NotifyView"> <attr name="myText" /> <attr name="myTextColor" /> <attr name="myTextSize" /> <attr name="myBackground" /> <attr name="myShape" /> </declare-styleable> </resources>

然后新建一個自定義View繼承自View,我這里把它叫做NotifyView
定義NotifyView的成員變量

//view 屬性 private String text; private int textColor; private float textSize; private int backgroud; private String shape; //定義畫筆 private Paint textPaint; private Paint shapePaint; private int height; private int width;

重寫構造方法。由於布局文件默認調用的是兩個參數的構造方法,但是我們需要用到的是三個參數的構造方法,所以我們要讓他調用三個參數的構造方法。構造方法主要用來獲取我們自定義的一些屬性值

public NotifyView(Context context, AttributeSet attrs){ this(context, attrs, 0); } public NotifyView(Context context){ this(context, null); } public NotifyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs); TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.NotifyView, defStyle, 0); int n=attributes.getIndexCount(); for (int i=0;i<n;i++){ int attribute=attributes.getIndex(i); switch (attribute){ case R.styleable.NotifyView_myText: text=attributes.getString(attribute); if(text.length()>2){ text="99+"; } break; case R.styleable.NotifyView_myTextColor: textColor=attributes.getInt(attribute, R.color.white); break; case R.styleable.NotifyView_myBackground: backgroud=attributes.getInt(attribute,R.color.red); break; case R.styleable.NotifyView_myShape: shape=attributes.getString(attribute); break; case R.styleable.NotifyView_myTextSize: textSize=attributes.getDimension(attribute,12); break; } } attributes.recycle(); }

然后繪制形狀和文本

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 初始化畫筆 textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); shapePaint=new Paint(Paint.ANTI_ALIAS_FLAG); height=getHeight(); width=getWidth(); //文本屬性 textPaint.setColor(textColor); textPaint.setTextAlign(Paint.Align.CENTER); textPaint.setTextSize(textSize); textPaint.setTypeface(Typeface.DEFAULT_BOLD); Paint.FontMetrics fontMetrics = textPaint.getFontMetrics(); float top = fontMetrics.top;//為基線到字體上邊框的距離,即上圖中的top float bottom = fontMetrics.bottom;//為基線到字體下邊框的距離,即上圖中的bottom int baseLineY = (int) (height/2 - top/2 - bottom/2);//基線中間點的y軸計算公式 shapePaint.setColor(backgroud); if("rectangle".equals(shape)) { shapePaint.setStyle(Paint.Style.FILL); Rect rect=new Rect(height,width,height,width); canvas.drawRect(rect, shapePaint); canvas.drawText(text,width/2,baseLineY,textPaint); } //畫圓 else { canvas.drawCircle(width / 2, height / 2, Math.min(width, height) / 2, shapePaint); canvas.drawText(text,width / 2,baseLineY,textPaint); } }

這里有一點要說明一下,就是文字居中顯示的問題
這里借用網上的圖來說明一下android canvas drawText()文字居中


安卓繪制文字是相對於基線繪制的,文字的高度即圖中top和bottom之間的距離
要讓文字水平豎直居中,就要找到圖中基線上center那個點的坐標

以矩形為例,矩形中點的坐標為(width/2,height/2);黑點到基線上紅點的距離為(-top+bottom)/2-bottom,即-top/2-bottom/2
所以紅點的坐標為(width/2,height/2-top/2-bottom/2);

最后就是一些setter和getter方法了


public int getBackgroud() { return backgroud; } public void setBackgroud(int backgroud) { this.backgroud = backgroud; } public String getShape() { return shape; } public void setShape(String shape) { this.shape = shape; } public String getText() { return text; } public void setText(String text) { if(text.length()>2){ text="99+"; }else this.text = text; } public int getTextColor() { return textColor; } public void setTextColor(int textColor) { this.textColor = textColor; } public float getTextSize() { return textSize; } public void setTextSize(float textSize) { this.textSize = textSize; }

接下來就可以在布局里引用了(要先在布局根標簽里引入命名空間xmlns:xesygao="http://schemas.android.com/apk/res-auto")

<com.xesygao.xtieba.custom.NotifyView android:layout_width="22dp" android:layout_height="22dp" android:visibility="gone" tools:visibility="visible" xesygao:myText="121" xesygao:myTextSize="10sp" xesygao:myShape="circle" xesygao:myBackground="@color/lightRed" xesygao:myTextColor="@color/white" android:id="@+id/replyme_count"/>

好了,來看看效果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM