Android自定义View【实战教程】2⃣️----自定义view那些事
很多人对自定义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那些事相关推荐
- 【Android自定义View实战】之自定义评价打分控件RatingBar,可以自定义星星大小和间距...
[Android自定义View实战]之自定义评价打分控件RatingBar,可以自定义星星大小和间距
- HQChart实战教程24 - 自定义K线画图工具设置框(线段类)
HQChart实战教程24 - 自定义K线画图工具设置框 画图工具 步骤 监听画图工具选中事件 点击事件回调 1. 回调参数说明 2. 图形实例类说明 Symbol Period Vaule Line ...
- 我的世界服务器怎么修改合成表,《我的世界》1.8原版自定义合成表教程 怎么自定义合成表...
<我的世界>1.8原版自定义合成方法,很多玩家还不了解,今天给大家带来玩家"真名"分享的<我的世界>1.8原版自定义合成表教程,一起来看看吧. 版本要求1. ...
- Android移动开发之【Android企业级项目实战教程】DAY1-图表库HelloCharts
使用HelloCharts开源框架搭建一系列炫酷图表,柱形图,折线图,饼状图和动画特效,抽丝剥茧带你认识图表之美 实际开发中经常会使用第三方的图标库显示数据,其中HelloCharts就是一款非常优秀 ...
- Android属性动画实战教程开篇
本系列博客会分俩篇 本篇博客主要是会介绍属性动画代码使用和xml中使用 关于View动画和属性动画的区别不做过多的介绍,当然涉及到的地方会简单的提一下. 好了废话不多说,直接上内容 首先介绍代码中使用 ...
- 自定义html标签教程,HTML自定义标签
背景 HTML的标签大家不陌生,都是标准定义好的,我们只管用.但是有没有想过,我们可以定义自己的标签,封装成自己的组件. DEMO 下面的demo,用于展示浏览器版本的支持情况.查看其DOM,发现标签 ...
- Android 黑马Topline《企业级项目实战教程》2022
本项目是源于黑马程序员的<Android企业级项目实战教程>TopLine源码的调试方法. 1.导入安卓项目,项目中所需的所有包已经导入成功,项目结构如图所示: 2.打开cmd,使用ipc ...
- 可转债交易薅羊毛策略 — Python 量化投资实战教程(10)
往期推荐 量化投资原来这么简单(1) 量化投资原来这么简单(2)-MACD策略(+26.9%) 量化投资原来这么简单(3) -A股回测MACD策略 Python 量化投资原来这么简单(4) -KDJ ...
- 新书推荐:《Android Studio开发实战:从零基础到App上线》终章
<Android Studio开发实战:从零基础到App上线>是一部Android开发的实战教程,由浅入深.由基础到高级,带领读者一步一步走进App开发的神奇世界. 全书共分为16章.其中 ...
- android 行布局选择器,『自定义View实战』—— 银行种类选择器
在工作中难免遇到自定义 View 的相关需求,本身这方面比较薄弱,因此做个记录,也是自己学习和成长的积累.自定义View实战 前言 年前的最后一个开发需求,将之前H5开卡界面转变成native.意思就 ...
最新文章
- 快收藏!整理了 100 个 Python 小技巧
- DeepID3:Face Recognition with Very Deep Neural Networks
- 使用pt-slave-delay实现mysql的延迟备份
- 《程序员面试金典》合法括号判断
- 海云健康:上云为10万家药店带去了什么价值?
- 测试如何学python_学习Python:如何测试函数和类,快学,与
- java weblogic admin,weblogic admin 不能重起服务(Server may already be running)
- [leetcode]209. 长度最小的子数组
- 初步认识lodash.js
- 友情链接php源代码_2017最新ThinkPHP开发的友情链接交易系统平台源码
- R语言介绍(R包与帮助文档)
- 使用samba软件实现局域网共享文件
- 百度问答怎么引流,百度知道引流技巧
- MS2561低功耗RS-485接口芯片,可替换MAX487兼容MAX348
- 微信公众号 菜单 { “errcode“: 47001, “errmsg“: “data format error rid: 61b36b ...“}
- 【机器学习】网络表征学习、网络嵌入必读论文
- 虚拟机下 centos7 网络间歇性断网
- Ucenter的UClinet和UC_Server编码不一致无法登陆解决方法
- iOS身份证的正则验证
- android ios版本 市场占有率,最新的智能移动终端ios,android等市场占有率情况
热门文章
- Python:字符串、列表、元组、字典之间的相互转换
- alert确认后执行_微任务、宏任务、DOM渲染的执行顺序
- 局域网Maven Java包批量上传的方法
- jquery 事件冒泡的介绍
- pcl_viewer 常用实用指令
- cartographer代码流程分析
- [论文评析] ICLR,2021,An image is worth 16x16 words-transformers for image recognition at scale
- CVPR 2021奖项出炉:最佳论文花落马普所,何恺明获提名,首届黄煦涛纪念奖颁布
- 一文详解深度相机之TOF成像
- 树莓派 4B 配置 Ubuntu20.04 和 ROS2