zoukankan      html  css  js  c++  java
  • Android 自定义View

      最近在看鸿洋大神的博客,在看到自定义部分View部分时,想到之前案子中经常会要用到"图片 + 文字"这类控件,如下图所示:

        之前的做法是在布局文件中,将一个Image & TextView组件放在LinearLayout/RelativeLayout中。今天就尝试了通过自定义View的方式来实现"图片 + 文字"组件。

      首先在/res/value/目录下新建attrs.xml文件,在该文件中为CustomTextView定义以下几个attr。分别为

      1.文字内容-titleText 2.文字颜色-titleTextColor 3.文字大小-titleTextSize

      4.图像内容-image 5.图像宽度-imageWidth 6.图像高度-imageHeight 7.图像显示模式-imageScaleType

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!--define some attrs for custom view-->
    
        <attr name="titleText" format="string"/>
        <attr name="titleTextColor" format="color"/>
        <attr name="titleTextSize" format="dimension"/>
        <attr name="image" format="reference"/>
        <attr name="imageWidth" format="dimension"/>
        <attr name="imageHeight" format="dimension"/>
        <attr name="imageScaleType">
            <enum name="fillXY" value="0" />
            <enum name="center" value="1" />
        </attr>
    
        <declare-styleable name="CustomTextView">
            <attr name="titleText" />
            <attr name="titleTextColor" />
            <attr name="titleTextSize" />
            <attr name="image" />
            <attr name="imageScaleType" />
            <attr name="imageWidth"/>
            <attr name="imageHeight"/>
        </declare-styleable>
    </resources>

      下面就是CustomTextView.java内容:

    package com.example.steve.customizedview;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.Typeface;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.view.View;
    
    /**
     * Created by steve on 17-6-2.
     */
    
    public class CustomTextView extends View {
        /**
         * 文本
         */
        private String mTitleText;
        /**
         * 文本的颜色
         */
        private int mTitleTextColor;
        /**
         * 文本的大小
         */
        private int mTitleTextSize;
    
        /**
         * 图片
         */
        private Bitmap mImage;
        private int mImageWidth;
        private int mImageHeight;
        /**
         * 图片显示模式
         */
        private int mImageScaleType;
        /**
         * 绘制时控制文本绘制的范围
         */
        private Rect mBound;
        private Paint mPaint;
        /**
         * Canvas大小
         */
        private int mWidth;
        private int mHeight;
    
        public CustomTextView(Context context) {
            this(context, null);
        }
    
        public CustomTextView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView, defStyleAttr, 0);
            int count = a.getIndexCount();
            for (int i = 0; i < count; i++)
            {
                int attr = a.getIndex(i);
                switch (attr)
                {
                    case R.styleable.CustomTextView_titleText:
                        mTitleText = a.getString(attr);
                        break;
                    case R.styleable.CustomTextView_titleTextColor:
                        mTitleTextColor = a.getColor(attr, Color.BLACK);
                        break;
                    case R.styleable.CustomTextView_titleTextSize:
                        mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                                TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
                        break;
                    case R.styleable.CustomTextView_image:
                        mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));
                        break;
                    case R.styleable.CustomTextView_imageScaleType:
                        mImageScaleType = a.getInt(attr, 0);
                        break;
                    case R.styleable.CustomTextView_imageWidth:
                        mImageWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                                TypedValue.COMPLEX_UNIT_SP, 24, getResources().getDisplayMetrics()));
                        break;
                    case R.styleable.CustomTextView_imageHeight:
                        mImageHeight = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                                TypedValue.COMPLEX_UNIT_DIP, 32, getResources().getDisplayMetrics()));
                        break;
                }
    
            }
            a.recycle();

    // 如果设置图片的宽和高的话,需要对原始图片进行缩放处理
    if (mImageWidth > 0 && mImageHeight > 0) { mImage = zoomImg(mImage, mImageWidth, mImageHeight); } mPaint = new Paint(); mPaint.setTextSize(mTitleTextSize); mBound = new Rect(); mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound); } public Bitmap zoomImg(Bitmap bm, int newWidth ,int newHeight){ // 获得图片的宽高 int width = bm.getWidth(); int height = bm.getHeight(); // 计算缩放比例 float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; // 取得想要缩放的matrix参数 Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); // 得到新的图片 Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true); return newbm; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //设置宽度 int specMode = MeasureSpec.getMode(widthMeasureSpec); int specWidth = MeasureSpec.getSize(widthMeasureSpec); if (specMode == MeasureSpec.EXACTLY) { mWidth = specWidth; } else { int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth(); int desireByTitle = getPaddingLeft() + getPaddingRight() + mBound.width(); if (specMode == MeasureSpec.AT_MOST) { int desireWidth = Math.max(desireByImg, desireByTitle);//取两者之间的最大值 mWidth = Math.min(desireWidth, specWidth); } } //设置高度 specMode = MeasureSpec.getMode(heightMeasureSpec); int specHight = MeasureSpec.getSize(heightMeasureSpec); if (specMode == MeasureSpec.EXACTLY) { mHeight = specHight; } else { int desireHight = getPaddingTop() + getPaddingBottom() + mImage.getHeight() + mBound.height(); if (specMode == MeasureSpec.AT_MOST) { mHeight = Math.min(desireHight, specHight); } } setMeasuredDimension(mWidth, mHeight); } @Override protected void onDraw(Canvas canvas) { Rect rect = new Rect(); rect.left = getPaddingLeft(); rect.right = mWidth - getPaddingRight(); rect.top = getPaddingTop(); rect.bottom = mHeight - getPaddingBottom(); mPaint.setColor(mTitleTextColor); mPaint.setStyle(Paint.Style.FILL); mPaint.setTypeface(Typeface.DEFAULT_BOLD);//设置字体样式 canvas.drawText(mTitleText, mWidth / 2 - mBound.width() * 1.0f / 2, mHeight - getPaddingBottom(), mPaint); rect.bottom = - mBound.height();//重新计算rect的高度,即减去字体占用的空间 if (mImageScaleType == 1) { canvas.drawBitmap(mImage, null, rect, mPaint); } else { //计算居中的矩形范围 rect.left = mWidth / 2 - mImage.getWidth() / 2; rect.right = mWidth / 2 + mImage.getWidth() / 2; rect.top = (mHeight - mBound.height()) / 2 - mImage.getHeight() / 2; rect.bottom = (mHeight - mBound.height()) / 2 + mImage.getHeight() / 2; canvas.drawBitmap(mImage, null, rect, mPaint); } } }

      布局文件如下:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:custom="http://schemas.android.com/apk/res-auto"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.steve.customizedview.MainActivity">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/custom_view_height"
            android:background="#F0F0F0">
            <com.example.steve.customizedview.CustomTextView
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:layout_centerInParent="true"
                android:paddingBottom="5dp"
                custom:titleText="@string/delete_text"
                custom:titleTextColor="#5C5C5C"
                custom:titleTextSize="12sp"
                custom:image="@drawable/delete_n"
                custom:imageWidth="28dp"
                custom:imageHeight="28dp"/>
            />
        </RelativeLayout>
    </RelativeLayout>

      该文章内容基本上都是参考http://blog.csdn.net/lmj623565791/article/details/24252901/,有兴趣的可以直接看鸿洋大神的blog。

  • 相关阅读:
    进阶之路 | 奇妙的View之旅
    进阶之路 | 奇妙的Window之旅
    进阶之路 | 奇妙的Activity之旅
    Laravel5.5 邮件发送报错:stream_socket_client()
    ThinkPHP中使用PHPMailer发送邮件
    php 实现密码错误三次锁定账号10分钟
    自定义函数实现字符串数组互转
    自定义函数实现判断一个字符串是否包含另外一个字符串
    PHP一个for循环输出9*9乘法表
    中国地区表SQL语句
  • 原文地址:https://www.cnblogs.com/Peter-Chen/p/6934899.html
Copyright © 2011-2022 走看看