1.自定义view入门
2024-09-05 02:29:23
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>
最新文章
- 使用DB4o做一个.Net版的website(一)环境
- DWZ (JUI) 教程 tree 控件的选中事件
- C#源码大汇总
- MVC小系列(十四)【MVC+ZTree大数据异步树加载】
- win32程序中简单应用mfc
- 设置outlook自动回复
- Fortran与C混合编程(转自Ubuntu)
- 数据结构学习:KMP模式匹配算法
- VS2013 添加控制台程序
- 【ML入门系列】(二)分类与回归
- Android Jetpack 概述
- Shell高级编程学习笔记(基础篇)
- JS获取系统时间--JavaScript基础
- php 有意思的小题
- hdu 5064 满足b2−b1≤b3−b2... 的最长子序列
- ArcGIS放射状流向地图
- Android利用广播监听设备网络连接(断网)的变化情况
- LNMP环境下独立安装Mysql5.7.18 并对数据库文件进行本地物理迁移 (需暂停数据库服务方式)
- 679. 24 Game
- HDU4280:Island Transport(最大流)
热门文章
- Verilog之阻塞赋值非阻塞赋值
- DataTable 将一列转为List
- 痞子衡嵌入式:深入i.MXRT1050系列ROM中串行NOR Flash启动初始化流程
- PyQt(Python+Qt)学习随笔:QListWidget对项进行排序的sortItems方法
- 第11.14节 正则表达式转义符和Python转义符相同引发问题的解决办法
- PyQt(Python+Qt)学习随笔:Qt Designer中部件mimimumSize和maximumSize的含义
- PyQt(Python+Qt)学习随笔:Designer中ItemViews类部件的frameShadow属性
- Hello TLM
- PHP代码审计分段讲解(6)
- python-列表list和元组tuple