1.继承自view

系统提供的view 如 TextView 、ImageView 都是继承自view的;

2.自定义一个TextView

通过自定义一个TextView 来熟悉继承自view 的自定义view的api用法

3.onMeasure

用来处理控件的大小

 	@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
}
//获取宽高的模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec); //mode
//MeasureSpec.AT_MOST 指定了wrap_content
//MeasureSpec.EXACTLY 指定了确切的值 match_parent fill_parent
//MeasureSpec.UNSPECIFIED 尽可能的大

4.onDraw

用于绘制

   @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// canvas.drawText();
}

5.onTouchEvent

用于处理用户触摸事件

    @Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
} return super.onTouchEvent(event);
}

6.自定义属性

用来配置自定义控件的属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 自定义控件的名称 name="TextView"-->
<declare-styleable name="TextView">
<attr name="text" format="string" />
<attr name="textColor" format="color" />
<attr name="textSize" format="dimension" />
<attr name="maxLength" format="integer" />
<attr name="background" format="reference|color" /> <!--枚举-->
<attr name="inputType" format="enum">
<enum name="number" value="1" />
<enum name="text" value="2" />
<enum name="password" value="3" />
</attr>
</declare-styleable>
</resources>

在布局中使用

<com.nb.customview.TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:text="张三"
app:textColor="@color/purple_500"
app:textSize="16" />

在自定义控件中获取

    public TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TextView);
mText = typedArray.getString(R.styleable.TextView_text);
mTextSize = typedArray.getDimensionPixelSize(R.styleable.TextView_textSize, mTextSize);
mTextColor = typedArray.getColor(R.styleable.TextView_textColor, mTextColor);
typedArray.recycle();
}

7.完整的代码

package com.nb.customview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout; import androidx.annotation.Nullable; /**
* Created by DongKing on 2020/11/5
* Version 1.0
* Describe:自定义TextView
*/
class TextView extends View { private static final String TAG = "TextView"; private String mText;
private int mTextSize = 15;
private int mTextColor = Color.BLACK; private Paint mPaint; // 在java 代码中new 的时候使用
public TextView(Context context) {
this(context, null);
} // 在layout 中使用
public TextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
} //有style时使用
public TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取xml中设置的属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TextView);
mText = typedArray.getString(R.styleable.TextView_nbText);
mTextSize = typedArray.getDimensionPixelSize(R.styleable.TextView_nbTextSize, sp2px(mTextSize));
mTextColor = typedArray.getColor(R.styleable.TextView_nbTextColor, mTextColor);
typedArray.recycle(); //初始化画笔
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setTextSize(mTextSize);
mPaint.setColor(mTextColor); } private int sp2px(int sp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
getResources().getDisplayMetrics());
} /**
* 指定宽高
* 针对不同的情况
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec); //1.如果指定大小
int width = MeasureSpec.getSize(widthMeasureSpec);
//2.wrap_content 计算获取值
if (widthMode == MeasureSpec.AT_MOST) {
Rect bounds = new Rect();
mPaint.getTextBounds(mText, 0, mText.length(), bounds);
width = bounds.width() + getPaddingLeft() + getPaddingRight();
} int height = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode == MeasureSpec.AT_MOST) {
Rect bounds = new Rect();
mPaint.getTextBounds(mText, 0, mText.length(), bounds);
height = bounds.height() + getPaddingTop() + getPaddingBottom();
}
//设置控件的宽高
setMeasuredDimension(width, height); } /**
* 用于绘制
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
int dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
int baseLine = getHeight() / 2 + dy; canvas.drawText(mText, getPaddingLeft(), baseLine, mPaint);
} }
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"> <LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <com.nb.customview.TextView
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/purple_200"
app:nbText="张三"
app:nbTextColor="@color/teal_200"
app:nbTextSize="20sp" /> </LinearLayout> </LinearLayout>

1.自定义view入门的更多相关文章

  1. Android简易实战教程--第二十七话《自定义View入门案例之开关按钮详细分析》

    转载此博客请注明出处点击打开链接       http://blog.csdn.net/qq_32059827/article/details/52444145 对于自定义view,可能是一个比较大的 ...

  2. 自定义view入门

    如何自定义控件主要分为以下几个步骤: 1.自定义属性的声明与获取 (1)分析需要的自定义属性 (2)在res/values/attrs.xml定义声明,如 <resources> < ...

  3. Android自定义View入门(一)

    最近在写一个关于音乐播放的应用,写到播放界面UI时,就想自己实现的一个播放界面.那么如何实现自定义View呢?通过查看他人博客和Android官方开发文档,初步了解了一些浅显的内容.在此记录,已供需要 ...

  4. 自定义View入门-绘制基础(1)

    ### 前言 说道自定义View,我们一定会想到,自定义View的绘制流程 - 测量阶段(measure) - 布局阶段(layout) - 绘制阶段(draw) 我们看到的一些炫酷的view效果,都 ...

  5. Android之自定义View的实现

    对于学习Android开发的小童鞋对于自定义View一定不会陌生,相信大家对它是又爱又恨,爱它可以跟随我们的心意设计出漂亮的效果:恨它想要完全流畅掌握,需要一定的功夫.对于初学者来说确实很不容易,网上 ...

  6. Android自定义View

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...

  7. Android 自定义View (一)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...

  8. Android 自定义View(button)

    很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章.先总结下自定义View的步骤 ...

  9. 推翻自己和过往,重学自定义View

    http://blog.csdn.net/lfdfhl/article/details/51671038 深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 A ...

随机推荐

  1. Django之ModelForm实际操作使用

    1.定义model数据库字段如下: class User(models.Model): """ 员工信息表用户.密码.职位.公司名(子.总公司).手机.最后一次登录时间. ...

  2. C++反射机制:可变参数模板实现C++反射(二)

    1. 概要   2018年Bwar发布了<C++反射机制:可变参数模板实现C++反射>,文章非常实用,Bwar也见过好几个看了那篇文章后以同样方法实现反射的项目,也见过不少从我的文章抄过去 ...

  3. Ajax Status(状态码) & readyState()

    Ajax Status & readyState readyState(状态值) 是指运行AJAX所经历过的几种状态,论访问是否成功都将响应的步骤,可以理解成为AJAX运行步骤,使用" ...

  4. Markdown 语法详解

    Markdown 学习 标题 三级标题 四级标题 最多支持六级标题 "#... + 标题名称" 字体 hello, world "** 内容 **" hello ...

  5. HTML-webstorm添加快捷键

    快速输入标签: 先输入标签p,按Tab键变成<p></p>,光标会在标签中间 输入内容后按end键 快速复制粘贴光标所在的一整行内容Ctrl+D 快速删除光标所在的行 Ctrl ...

  6. 06_Intent和IntentFilter

    Intent是同一个或不同的应用中的组件之间的消息传递的媒介,是一个将要执行动作的抽象描述,一般来说是作为参数来使用. Intent描述要启动的基本组件: IntentFilter对组件进行过滤. 下 ...

  7. 【刷题笔记】DP优化-斜率优化

    斜率优化,是一种利用斜率的优化(废话) 关于数论:咕咕咕 部分内容参考自学长 如果有这样的一个状态转移方程: \[f[i]=\min\limits_{j=L_j}^{R_j}\{f[j]+val(j, ...

  8. HPSocket介绍与使用

    一.HPSocket介绍 HP-Socket是一套通用的高性能TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和Agent组件,广泛适用于各种不同应用场景的TCP/UDP/HTTP通信系 ...

  9. Tree--二叉树BinarySearchTree

    BinarySearchTreeMap的实现 1 public interface Map<K extends Comparable<K>, V> { 2 void put(K ...

  10. jupyter notebook 安装记录

    conda install jupyterconda install jupyter_nbextensions_configuratorconda install jupyter_contrib_nb ...