使用 Android Studio自定义View02——图文混排的View

来源:互联网 发布:淘宝第三方运营商 编辑:程序博客网 时间:2024/06/16 10:08

整理总结自鸿洋的博客:http://blog.csdn.net/lmj623565791/article/details/24300125

com.cctvjiatao.customview02.act.MainActivity.java

/** * 自定义的View结构为:上部是图片,下部是文字。注意图文混排的宽度的取值、图片显示的方式。 */public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}


res/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?><resources>    <attr name="title" format="string" />    <attr name="titleColor" format="color" />    <attr name="titleSize" format="dimension" />    <attr name="image" format="reference" />    <attr name="imageScaleType">        <enum name="fillXY" value="0" />        <enum name="center" value="1" />    </attr>    <declare-styleable name="ImgAndText">        <attr name="title" />        <attr name="titleColor" />        <attr name="titleSize" />        <attr name="image" />        <attr name="imageScaleType" />    </declare-styleable></resources>

res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:custom="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".act.MainActivity">    <!--字体的宽度大于图片,且View宽度设置为wrap_content-->    <com.cctvjiatao.customview02.view.ImgAndText        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="5dp"        android:padding="5dp"        custom:image="@mipmap/ic_launcher"        custom:imageScaleType="center"        custom:title="Hello World!Hello World!Hello World!"        custom:titleColor="#ff0000"        custom:titleSize="16sp" />    <!--View宽度设置为精确值,字体的长度大于此宽度-->    <com.cctvjiatao.customview02.view.ImgAndText        android:layout_width="100dp"        android:layout_height="wrap_content"        android:layout_margin="5dp"        android:padding="5dp"        custom:image="@mipmap/ic_launcher"        custom:imageScaleType="center"        custom:title="Hello World!Hello World!Hello World!"        custom:titleColor="#ff0000"        custom:titleSize="16sp" />    <!--图片的宽度大于字体,且View宽度设置为wrap_content-->    <com.cctvjiatao.customview02.view.ImgAndText        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="5dp"        android:padding="5dp"        custom:image="@mipmap/girl"        custom:imageScaleType="center"        custom:title="Hello World!"        custom:titleColor="#ff0000"        custom:titleSize="16sp" /></LinearLayout>

com.cctvjiatao.customview02.view.ImgAndText.java

public class ImgAndText extends View {    //自定义属性    private String mTitle;    private int mTitleColor;    private int mTitleSize;    private Bitmap mImage;    private int mImageScaleType;    //常规属性    private static final int IMAGE_SCALE_FITXY = 0;    private static final int IMAGE_SCALE_CENTER = 1;    private int width;//view的宽    private int height;//view的高    private Rect mRect;//view的整体区域    private Rect mTitleBound;//title的区域    private Paint mPaint;    public ImgAndText(Context context) {        this(context, null);    }    public ImgAndText(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public ImgAndText(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ImgAndText, defStyleAttr, 0);        int n = typedArray.getIndexCount();        for (int i = 0; i < n; i++) {            int attr = typedArray.getIndex(i);            switch (attr) {                case R.styleable.ImgAndText_title:                    mTitle = typedArray.getString(attr);                    break;                case R.styleable.ImgAndText_titleColor:                    mTitleColor = typedArray.getColor(attr, Color.BLACK);                    break;                case R.styleable.ImgAndText_titleSize:                    mTitleSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,                            16, getResources().getDisplayMetrics()));                    break;                case R.styleable.ImgAndText_image:                    mImage = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(attr, 0));                    break;                case R.styleable.ImgAndText_imageScaleType:                    mImageScaleType = typedArray.getInt(attr, 0);                    break;            }        }        typedArray.recycle();        mRect = new Rect();        mPaint = new Paint();        mTitleBound = new Rect();        mPaint.setTextSize(mTitleSize);        mPaint.getTextBounds(mTitle, 0, mTitle.length(), mTitleBound);//title的绘制区域    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int specMode, specSize;        //设置宽度        specMode = MeasureSpec.getMode(widthMeasureSpec);        specSize = MeasureSpec.getSize(widthMeasureSpec);        if (specMode == MeasureSpec.EXACTLY) {            width = specSize;        } else {            int widthImg = getPaddingLeft() + mImage.getWidth() + getPaddingRight();//图片的宽度            int widthTitle = getPaddingLeft() + mTitleBound.width() + getPaddingRight();//title的宽度            if (specMode == MeasureSpec.AT_MOST) {                width = Math.min(Math.max(widthImg, widthTitle), specSize);            }        }        //设置高度        specMode = MeasureSpec.getMode(heightMeasureSpec);        specSize = MeasureSpec.getSize(heightMeasureSpec);        if (specMode == MeasureSpec.EXACTLY) {            height = specSize;        } else {            int heightImgAndTitle = getPaddingTop() + mImage.getWidth() + mTitleBound.height() + getPaddingBottom();//图片+Title的高度            if (specMode == MeasureSpec.AT_MOST) {                height = Math.min(heightImgAndTitle, specSize);            }        }        setMeasuredDimension(width, height);    }    @Override    protected void onDraw(Canvas canvas) {        //绘制边框        mPaint.setStrokeWidth(4);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setColor(Color.CYAN);        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);        //图片和文字        mRect.left = getPaddingLeft();        mRect.right = width - getPaddingRight();        mRect.top = getPaddingTop();        mRect.bottom = height - getPaddingBottom();        mPaint.setColor(mTitleColor);        mPaint.setStyle(Paint.Style.FILL);        //文字        if (width > mTitleBound.width()) {//如果 view宽度大于title的宽度,则tltle居中显示            canvas.drawText(mTitle, width / 2 - mTitleBound.width() * 1.0f / 2, height - getPaddingBottom(), mPaint);        } else {//如果 view宽度小于title的宽度,则tltle缩略形式显示            TextPaint textPaint = new TextPaint(mPaint);            String msg = TextUtils.ellipsize(mTitle, textPaint, width - getPaddingLeft() - getPaddingRight(), TextUtils.TruncateAt.END).toString();            canvas.drawText(msg, getPaddingLeft(), height - getPaddingBottom(), mPaint);        }        //图片        mRect.bottom -= mTitleBound.height();//减掉被title用掉的高度        if (mImageScaleType == IMAGE_SCALE_FITXY) {            canvas.drawBitmap(mImage, null, mRect, mPaint);        } else {            mRect.left = width / 2 - mImage.getWidth() / 2;            mRect.right = width / 2 + mImage.getWidth() / 2;            mRect.top = height / 2 - mTitleBound.height() / 2 - mImage.getHeight() / 2;            mRect.bottom = height / 2 - mTitleBound.height() / 2 + mImage.getWidth() / 2;            canvas.drawBitmap(mImage, null, mRect, mPaint);        }    }}

程序运行结果如图:


0 0