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

#知识点
个人把自定义View分为以下四个步骤

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


##简单的自定义View Demo
###1、自定义View的属性

<?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的构造方法中获得我们自定义的属性

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

@Overrideprotected 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_parentLogger.i("EXACTLY");mWidth = specSize;}else {//??????int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth();//??????int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width();if(specMode == MeasureSpec.AT_MOST){ //wrap_contentint 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_parentmHeight = specSize;}else{int desire = getPaddingTop()+getPaddingBottom()+mImage.getHeight()+mTextBound.height();if(specMode == MeasureSpec.AT_MOST){ //wrap_contentmHeight = Math.min(desire,specSize);}}setMeasuredDimension(mWidth,mHeight);}

###4、重写onDraw

@Overrideprotected 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/22rect.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 接下来让我们看看如何使用

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

xmlns:app="http://schemas.android.com/apk/res-auto"

然后才能使用

<?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.CustomImageViewandroid: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

扫码关注公众号“伟大程序猿的诞生“,更多干货新鲜文章等着你~

公众号回复“资料获取”,获取更多干货哦~

有问题添加本人微信号“fenghuokeji996” 或扫描博客导航栏本人二维码

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

  1. 【Android自定义View实战】之自定义评价打分控件RatingBar,可以自定义星星大小和间距...

    [Android自定义View实战]之自定义评价打分控件RatingBar,可以自定义星星大小和间距

  2. HQChart实战教程24 - 自定义K线画图工具设置框(线段类)

    HQChart实战教程24 - 自定义K线画图工具设置框 画图工具 步骤 监听画图工具选中事件 点击事件回调 1. 回调参数说明 2. 图形实例类说明 Symbol Period Vaule Line ...

  3. 我的世界服务器怎么修改合成表,《我的世界》1.8原版自定义合成表教程 怎么自定义合成表...

    <我的世界>1.8原版自定义合成方法,很多玩家还不了解,今天给大家带来玩家"真名"分享的<我的世界>1.8原版自定义合成表教程,一起来看看吧. 版本要求1. ...

  4. Android移动开发之【Android企业级项目实战教程】DAY1-图表库HelloCharts

    使用HelloCharts开源框架搭建一系列炫酷图表,柱形图,折线图,饼状图和动画特效,抽丝剥茧带你认识图表之美 实际开发中经常会使用第三方的图标库显示数据,其中HelloCharts就是一款非常优秀 ...

  5. Android属性动画实战教程开篇

    本系列博客会分俩篇 本篇博客主要是会介绍属性动画代码使用和xml中使用 关于View动画和属性动画的区别不做过多的介绍,当然涉及到的地方会简单的提一下. 好了废话不多说,直接上内容 首先介绍代码中使用 ...

  6. 自定义html标签教程,HTML自定义标签

    背景 HTML的标签大家不陌生,都是标准定义好的,我们只管用.但是有没有想过,我们可以定义自己的标签,封装成自己的组件. DEMO 下面的demo,用于展示浏览器版本的支持情况.查看其DOM,发现标签 ...

  7. Android 黑马Topline《企业级项目实战教程》2022

    本项目是源于黑马程序员的<Android企业级项目实战教程>TopLine源码的调试方法. 1.导入安卓项目,项目中所需的所有包已经导入成功,项目结构如图所示: 2.打开cmd,使用ipc ...

  8. 可转债交易薅羊毛策略 — Python 量化投资实战教程(10)

    往期推荐 量化投资原来这么简单(1) 量化投资原来这么简单(2)-MACD策略(+26.9%) 量化投资原来这么简单(3) -A股回测MACD策略 Python 量化投资原来这么简单(4) -KDJ ...

  9. 新书推荐:《Android Studio开发实战:从零基础到App上线》终章

    <Android Studio开发实战:从零基础到App上线>是一部Android开发的实战教程,由浅入深.由基础到高级,带领读者一步一步走进App开发的神奇世界. 全书共分为16章.其中 ...

  10. android 行布局选择器,『自定义View实战』—— 银行种类选择器

    在工作中难免遇到自定义 View 的相关需求,本身这方面比较薄弱,因此做个记录,也是自己学习和成长的积累.自定义View实战 前言 年前的最后一个开发需求,将之前H5开卡界面转变成native.意思就 ...

最新文章

  1. 快收藏!整理了 100 个 Python 小技巧
  2. DeepID3:Face Recognition with Very Deep Neural Networks
  3. 使用pt-slave-delay实现mysql的延迟备份
  4. 《程序员面试金典》合法括号判断
  5. 海云健康:上云为10万家药店带去了什么价值?
  6. 测试如何学python_学习Python:如何测试函数和类,快学,与
  7. java weblogic admin,weblogic admin 不能重起服务(Server may already be running)
  8. [leetcode]209. 长度最小的子数组
  9. 初步认识lodash.js
  10. 友情链接php源代码_2017最新ThinkPHP开发的友情链接交易系统平台源码
  11. R语言介绍(R包与帮助文档)
  12. 使用samba软件实现局域网共享文件
  13. 百度问答怎么引流,百度知道引流技巧
  14. MS2561低功耗RS-485接口芯片,可替换MAX487兼容MAX348
  15. 微信公众号 菜单 { “errcode“: 47001, “errmsg“: “data format error rid: 61b36b ...“}
  16. 【机器学习】网络表征学习、网络嵌入必读论文
  17. 虚拟机下 centos7 网络间歇性断网
  18. Ucenter的UClinet和UC_Server编码不一致无法登陆解决方法
  19. iOS身份证的正则验证
  20. android ios版本 市场占有率,最新的智能移动终端ios,android等市场占有率情况

热门文章

  1. Python:字符串、列表、元组、字典之间的相互转换
  2. alert确认后执行_微任务、宏任务、DOM渲染的执行顺序
  3. 局域网Maven Java包批量上传的方法
  4. jquery 事件冒泡的介绍
  5. pcl_viewer 常用实用指令
  6. cartographer代码流程分析
  7. [论文评析] ICLR,2021,An image is worth 16x16 words-transformers for image recognition at scale
  8. CVPR 2021奖项出炉:最佳论文花落马普所,何恺明获提名,首届黄煦涛纪念奖颁布
  9. 一文详解深度相机之TOF成像
  10. 树莓派 4B 配置 Ubuntu20.04 和 ROS2