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. Java基础教程——异常处理详解

    异常处理 好程序的特性 可重用性 可维护性 可扩展性 鲁棒性 |--|--Robust的音译 |--|--健壮.强壮之意 |--|--指在异常和危险情况下系统依然能运行,不崩溃 Java中,写下如下代 ...

  2. java多态2

    1 package pet_2; 2 3 public class Pet { 4 private String name; 5 6 public String getName() { 7 retur ...

  3. django(django学习) 两张表创建 插入数据

      pycharm中直接创建django项目 输入创建项目名(如first_django) 在此输入应用名(如g_tu) 此为项目总目录 将first_django中settings.py中第58行修 ...

  4. 速刷git<一> 常用命令记录

    git config  --list 列出配置  --local 对某个仓库有效  --global 对当前用户的所有仓库有效  --system 对系统所有登录用户有效git reset  --ha ...

  5. 区块链学习5:智能合约Smart contract原理及发展历程科普知识

    ☞ ░ 前往老猿Python博文目录 ░ 一.智能合约的定义 通俗来说,智能合约就是一种在计算机系统上,当一定条件满足的情况下可被自动执行的合约,智能合约体现为一段代码及其运行环境.例如银行信用卡的自 ...

  6. XFF SSTI 模板注入 [BJDCTF2020]The mystery of ip

    转自https://www.cnblogs.com/wangtanzhi/p/12328083.html SSTI模板注入:之前也写过:https://www.cnblogs.com/wangtanz ...

  7. 从零开始的pickle反序列化学习

    前言 在XCTF高校战疫之中,我看到了一道pickle反序列化的题目,但因为太菜了花了好久才做出来,最近正好在学flask,直接配合pickle学一下. 找了半天终于找到一个大佬,这里就结合大佬的文章 ...

  8. Python Flask后端异步处理(三)

    前一篇博文我们已经将基础知识和环境配置进行了介绍:https://www.cnblogs.com/Cl0ud/p/13192925.html,本篇博文在实际应用场景中使用Celery,对Flask后端 ...

  9. [BJDCTF 2nd]Schrödinger && [BJDCTF2020]ZJCTF,不过如此

    [BJDCTF 2nd]Schrödinger 点进题目之后是一堆英文,英语不好就不配打CTF了吗(流泪) 复制这一堆英文去谷歌翻译的时候发现隐藏文字 移除test.php文件,访问test.php ...

  10. 跨国合作:Serverless Components 在腾讯云的落地和实践

    导语 | Serverless Components 是 Serverless Framework 推出的最新解决⽅案,具有基础设施编排能⼒,开发者通过使⽤ Serverless Components ...