前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android自定义View【实战教程】2⃣️----自定义view那些事

Android自定义View【实战教程】2⃣️----自定义view那些事

作者头像
先知先觉
发布2019-01-21 15:26:18
4200
发布2019-01-21 15:26:18
举报

很多人对自定义view都很胆怯,其实自己去玩一玩会发现很简单。

知识点

个人把自定义View分为以下四个步骤

1、自定义View的属性
2、在View的构造方法中获得我们自定义的属性
3、重写onMesure
4、重写onDraw

简单的自定义View Demo

1、自定义View的属性

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<resources>
    //??????,??????
    <attr name="titleText" format="string"/>
    <attr name="titleTextSize" format="dimension"/>
    <attr name="titleTextColor" format="color"/>
    <attr name="image" format="reference"/>
    <attr name="imageScaleType" >
        <enum name="fillXY" value="0"/>
        <enum name="center" value="1"/>
    </attr>

    //??????????
    <declare-styleable name="CustomImageView">
        <attr name="titleText" />
        <attr name="titleTextSize" />
        <attr name="titleTextColor" />
        <attr name="image" />
        <attr name="imageScaleType" />
    </declare-styleable>
</resources>

2、在View的构造方法中获得我们自定义的属性

代码语言:javascript
复制
public class CustomImageView extends View {
private static final String TAG = CustomImageView.class.getSimpleName();
    /**
     * ????
     */
    private int mWidth;
    /**
     * ????
     */
    private int mHeight;
    /**
     * ??????
     */
    private Bitmap mImage;
    /**
     * ???????
     */
    private int mImageScale;
    private static final int IMAGE_SCALE_FITXY = 0;
    private static final int IMAGE_SCALE_CENTER = 1;
    /**
     * ?????
     */
    private String mTitle;
    /**
     * ?????
     */
    private int mTextColor;
    /**
     * ?????
     */
    private int mTextSize;

    private Paint mPaint;
    /**
     * ??????
     */
    private Rect mTextBound;
    /**
     * ??????
     */
    private Rect rect;

    public CustomImageView(Context context) {
        super(context);
    }

    public CustomImageView(Context context, @Nullable AttributeSet attrs) {
        this(context,attrs,0);
    }

    public CustomImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyleAttr, 0);

        int indexCount = typedArray.getIndexCount();

        for (int i = 0; i < indexCount; i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
                case R.styleable.CustomImageView_image:
                    mImage = BitmapFactory.decodeResource(getResources(), typedArray.getResourceId(attr, 0));
                    break;
                case R.styleable.CustomImageView_imageScaleType:
                    mImageScale = typedArray.getInt(attr, 0);
                    break;
                case R.styleable.CustomImageView_titleText:
                    mTitle = typedArray.getString(attr);
                    break;
                case R.styleable.CustomImageView_titleTextColor:
                    mTextColor = typedArray.getColor(attr, Color.BLACK);
                    break;
                case R.styleable.CustomImageView_titleTextSize:
                    mTextSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,16,getResources().getDisplayMetrics()));
                    break;
            }

        }

        typedArray.recycle();
        rect = new Rect();
        mPaint = new Paint();
        mTextBound = new Rect();
        mPaint.setTextSize(mTextSize);
        //???????????
        mPaint.getTextBounds(mTitle,0,mTitle.length(),mTextBound);
    }
}

3、重写onMesure

代码语言:javascript
复制
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // TODO: 2017/3/22
        /**
         * UNSPECIFIED ????????????,????????
         * EXACTLY ?????????,???????????,??????????
         * AT_MOST ????????????
         */
        //????
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);

        if(specMode == MeasureSpec.EXACTLY){ //match_parent
            Logger.i("EXACTLY");

            mWidth = specSize;
        }else {
            //??????
            int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth();
            //??????
            int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width();

            if(specMode == MeasureSpec.AT_MOST){ //wrap_content
                int desire = Math.max(desireByImg,desireByTitle);
                mWidth = Math.min(desire,specSize);
                Logger.i("AT_MOST");
            }

            Logger.i("getPaddingLeft "+getPaddingLeft() + "    getPaddingRight()"+ getPaddingRight());
        }

        //????
        specMode = MeasureSpec.getMode(heightMeasureSpec);
        specSize = MeasureSpec.getSize(heightMeasureSpec);

        if(specMode == MeasureSpec.EXACTLY){  //macth_parent
            mHeight = specSize;
        }else{
            int desire = getPaddingTop()+getPaddingBottom()+mImage.getHeight()+mTextBound.height();

            if(specMode == MeasureSpec.AT_MOST){ //wrap_content
                mHeight = Math.min(desire,specSize);
            }
        }

        setMeasuredDimension(mWidth,mHeight);
    }

4、重写onDraw

代码语言:javascript
复制
@Override
    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);

        /**
         * ??
         */
        mPaint.setStrokeWidth(4);
        mPaint.setStyle(STROKE);  // STROKE ?? FILL??
        mPaint.setColor(Color.CYAN);
        canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint);

        // TODO: 2017/3/22
        rect.left = getPaddingLeft();
        rect.right = mWidth - getPaddingRight();
        rect.top = getPaddingTop();
        rect.bottom = mHeight - getPaddingBottom();

        mPaint.setColor(mTextColor);
        mPaint.setStyle(Paint.Style.FILL);

        /**
         * ????????????????,?????xxx...
         */
        if(mTextBound.width() > mWidth){
            TextPaint textpaint = new TextPaint(mPaint);
            String msg = TextUtils.ellipsize(mTitle,textpaint,(float)mWidth-getPaddingLeft()-getPaddingRight(),TextUtils.TruncateAt.END).toString();
            canvas.drawText(msg,getPaddingLeft(),mHeight-getPaddingBottom(),mPaint);
        }else{
            //???? ?????
            canvas.drawText(mTitle,mWidth/2 - mTextBound.width()*1.0f/2,mHeight-getPaddingBottom(),mPaint);
        }

        // TODO: 2017/3/22
        //???????
        rect.bottom -= mTextBound.height();

        //?????
        if (mImageScale == IMAGE_SCALE_FITXY)
        {
            canvas.drawBitmap(mImage, null, rect, mPaint);
        } else
        {
            //?????????
            rect.left = mWidth / 2 - mImage.getWidth() / 2;
            rect.right = mWidth / 2 + mImage.getWidth() / 2;
            rect.top = (mHeight - mTextBound.height()) / 2 - mImage.getHeight() / 2;
            rect.bottom = (mHeight - mTextBound.height()) / 2 + mImage.getHeight() / 2;

            Logger.e("mWidth : " +mWidth + "    mImage.getWidth() : " +mImage.getWidth());

            canvas.drawBitmap(mImage, null, rect, mPaint);
        }

    }

就是这么简单 完成了自定义View 接下来让我们看看如何使用

应用

在布局使用的时候先要定义一下如下信息

代码语言:javascript
复制
xmlns:app="http://schemas.android.com/apk/res-auto"

然后才能使用

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.libin.factory.widget.CustomImageView
        android:id="@+id/civ_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:padding="10dp"
        app:image="@drawable/bg_test"
        app:imageScaleType="center"
        app:titleText="hello andorid ! "
        app:titleTextColor="#ff0000"
        app:titleTextSize="30sp" />
</LinearLayout>

???

???????
???????

工程地址: https://github.com/libin7278/Factory java –》widget

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年03月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 知识点
    • 简单的自定义View Demo
      • 1、自定义View的属性
      • 2、在View的构造方法中获得我们自定义的属性
      • 3、重写onMesure
      • 4、重写onDraw
    • 应用
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档