1. 程式人生 > >001-自定義檢視-圓角TextView、ImageView、Button

001-自定義檢視-圓角TextView、ImageView、Button

今天總結了一下如何自定義圓角檢視的方法,使用了一種比較簡單的方式,直接在控制元件屬性裡面新增.9格式圓角的png圖片背景,然後即可達到預期的效果,同時還挺方便,在專案中使用到這裡方式來設定效果,還是很常見的。那我就不見解了,現在講如何自定義ImageViewLinearLayout,實現在ImageView中可以顯示文字,同時在LinearLayout中顯示圖文並茂的效果,如下圖:

 

一、前面二個直接新增.9格式圖片作為TextViewButton控制元件的背景,展示出圓角效果

二、後面三個自定義ImageViewLinearLayout,即繼承ImageViewLinearLayout

,然後重寫構造方法和其中的onDraw方法。

三、自定義檢視三部曲:第一宣告屬性、第二繼承需要的自定義檢視的父類,例如ImageViewLinearLayout或者View、第三在佈局檔案中引用

      第一步:建立attrs.xml,並定義需要使用到的屬性,我習慣的自定義方式,如下圖:

 

<resources>

<declare-styleable name="MyImageView">

<attr name="android:text" />

<attr name="android:textColor" />

<attr name

="android:textSize" />

<attr name="android:background"/>

</declare-styleable>

</resources>

   說明:這裡,我直接定義屬性名字系統的一樣,在佈局檔案中引用的時候,比較方便,你也可以定義成<attrs name=myText format=string/>表示屬性名為:myText,格式是字串型別,或者定義成顏色型別:<attrs name=myColor format=color/>,其中format的取值主要有:

1. reference:參考某一資源

ID

2. color:顏色值。

3. boolean:布林值。

4. dimension:尺寸值。

5. float:浮點值。

6. integer:整型值。

7. string:字串。

8. fraction:百分數。

9. enum:列舉值。

10. flag:位或運算。

這裡我只列出取值的型別,具體怎麼使用請前往飛騰空間檢視我另一篇帖子。

     第二步:繼承ImageView,重寫onDraw方法

package cn.teachcourse.utils.view;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.Paint.FontMetricsInt;

import android.util.AttributeSet;

import android.widget.ImageView;

import cn.teachcourse.round.R;

/**

 * 重寫onDraw方法,繪製獨特的ImageView

 * 

 * @author 飛騰:http://teachcourse.cn

 * @version 建立:2015-9-30上午9:35:05

 */

public class MyRoundImageView extends ImageView {

private int textColor;

private float textSize;

private String textContent;

private Paint mPaint;

private FontMetricsInt mFontMetricsInt;

private int mWidth;

private int mHeight;

private float mStringWidth;

public MyRoundImageView(Context context) {

super(context);

// TODO Auto-generated constructor stub

}

public MyRoundImageView(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

TypedArray ta = context.obtainStyledAttributes(attrs,

R.styleable.MyImageView);

textColor = ta.getColor(R.styleable.MyImageView_android_textColor, 0);

textSize = ta.getDimension(R.styleable.MyImageView_android_textSize,

12f);

textContent = ta.getString(R.styleable.MyImageView_android_text);

initPaint();

ta.recycle();

}

public MyRoundImageView(Context context, AttributeSet attrs,

int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

// TODO Auto-generated method stub

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

@Override

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

super.onDraw(canvas);

int x, y;

if (mPaint.getTextAlign() == Paint.Align.LEFT) { // 

x = mWidth / 2 - (int) (mStringWidth / 2);

} else if (mPaint.getTextAlign() == Paint.Align.CENTER) { // 

x = mWidth / 2;

} else { // 

x = mWidth / 2 + (int) (mStringWidth / 2);

}

y = (mHeight - mFontMetricsInt.ascent - mFontMetricsInt.descent) / 2;

canvas.drawText(textContent, x, y, mPaint);

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mWidth = w;

mHeight = h;

}

private float measureText() {

mStringWidth = mPaint.measureText(textContent);

return mStringWidth;

}

private void initPaint() {

mPaint = new Paint();

mPaint.setStrokeWidth(1);

mPaint.setTextSize(textSize);

mPaint.setTextAlign(Paint.Align.CENTER);

mPaint.setStyle(Paint.Style.FILL);

mPaint.setColor(textColor);

mFontMetricsInt = mPaint.getFontMetricsInt();

measureText();

}

}

第三步:佈局檔案中引用

檢視效果:

 

現在算是完成了自定義ImageView顯示文字、圓角效果,關鍵是重寫onDraw方法,在裡面繪製顯示的文字,因為ImageView本身沒提供顯示文字的屬性,如果對PaintCanvas熟悉的,自然很容易理解,不是問題。接下來我們看看,這種重寫的LinearLayout如何實現:

第一步:宣告需要使用到的屬性

<declare-styleable name="MyImageButtton">

<attr name="android:src" />

<attr name="android:background" />

<attr name="android:text" />

<attr name="android:textColor"/>

</declare-styleable>

第二步:繼承LinearLayout父類

package cn.teachcourse.utils.view;

import cn.teachcourse.round.R;

import android.annotation.SuppressLint;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.drawable.Drawable;

import android.util.AttributeSet;

import android.view.LayoutInflater;

import android.view.View;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.RelativeLayout;

import android.widget.TextView;

/**

 * 

 * @author 飛騰:http://teachcourse.cn

 * @version 建立:2015-9-29下午2:50:25

 */

@SuppressLint("NewApi")

public class MyRoundButtonView extends LinearLayout {

private RelativeLayout round_bg_ll;

private ImageView round_iv;

private TextView round_tv;

public MyRoundButtonView(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

View view = LayoutInflater.from(context).inflate(

R.layout.my_round_btn_view, this, true);

round_bg_ll = (RelativeLayout) view.findViewById(R.id.my_round_rl);

round_iv = (ImageView) view.findViewById(R.id.my_icon_iv);

round_tv = (TextView) view.findViewById(R.id.my_info_tv);

TypedArray ta = context.obtainStyledAttributes(attrs,

R.styleable.MyImageButtton);

CharSequence text = ta.getText(R.styleable.MyImageButtton_android_text);

Drawable background = ta

.getDrawable(R.styleable.MyImageButtton_android_background);

Drawable src = ta.getDrawable(R.styleable.MyImageButtton_android_src);

int color=ta.getColor(R.styleable.MyImageButtton_android_textColor, 0);

if (text != null)

round_tv.setText(text);

if (background != null)

// round_bg_ll.setBackground(background);

round_bg_ll.setBackgroundResource(ta.getResourceId(

R.styleable.MyImageButtton_android_background, 0));

if (src != null)

round_iv.setImageDrawable(src);

        if(color!=0)

round_tv.setTextColor(color);

}

public MyRoundButtonView(Context context, AttributeSet attrs,

int defStyleAttr, int defStyleRes) {

super(context, attrs, defStyleAttr, defStyleRes);

// TODO Auto-generated constructor stub

}

public MyRoundButtonView(Context context) {

super(context);

// TODO Auto-generated constructor stub

}

}

第三步:佈局檔案中引用

<cn.teachcourse.utils.view.MyRoundButtonView

        android:id="@+id/round_btn_view_001"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_alignParentLeft="true"

        android:layout_below="@+id/round_view_iv"

        android:layout_marginTop="30dp"

        android:background="@drawable/green_bg"

        android:src="@drawable/ic_launcher"

        android:text="自定義屬性"

        android:textColor="#FFFFFF" />

效果顯示:

 

說明:這裡解釋一下這裡,直接載入一個自定義的my_round_btn_view.xml檔案,然後取得其View物件對應的控制元件

LayoutInflater.from(context).inflate(

R.layout.my_round_btn_view, this, true);

my_round_btn_view.xml檔案內容

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:id="@+id/my_round_rl"

    android:layout_gravity="center_vertical" >

    <ImageView

        android:id="@+id/my_icon_iv"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:src="@drawable/ic_launcher" 

        android:layout_toLeftOf="@+id/my_info_tv"

        android:layout_centerInParent="true"/>

    <TextView

        android:id="@+id/my_info_tv"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="顯示文字"

        android:layout_centerInParent="true"/>

</RelativeLayout>