在
Android
开发中有很多业务场景,原生的控件是无法满足应用,并且经常也会遇到一个
UI
在多处
重复使用情况,那么就需要通过自定义
View
的方式来实现这些
UI
效果。
作为一个
Android
开发工程师自定义
View
属于一个必备技能。
自定义
View
的实现方式有以下几种:
组合控件,继承控件,自绘控件
详细可分为:
自定义组合控件,继承系统
View
控件,继承系统
ViewGroup
,自绘
View
控件,自绘
ViewGroup
控件
实现以下效果
分别时自定义标题,带下划线的TextView,蒙上一层蒙版
1. 编写布局文件
标题的布局文件
<?xml version="1.0" encoding="utf-8"?>
<com.hopu.day40tage01.LInerMask 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">
<com.hopu.day40tage01.Handerr
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.hopu.day40tage01.TextNew
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:text="测试"/>
</com.hopu.day40tage01.LInerMask>
2. 实现构造方法
3. 初始化UI
4. 提供对外的方法
因为我们的布局采用RelativeLayout,所以这里继承RelativeLayout。
标题
package com.hopu.day40tage01;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
public class Handerr extends RelativeLayout {
public Handerr(Context context) {
super(context);
}
private void intertle(Context context) {
LayoutInflater.from(context).inflate(R.layout.view_hander,this,true);
}
public Handerr(Context context, AttributeSet attrs) {
super(context, attrs);
intertle(context);
}
public Handerr(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public Handerr(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
}
带下划线的TextView
package com.hopu.day40tage01;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class TextNew extends androidx.appcompat.widget.AppCompatTextView {
public TextNew(@NonNull Context context) {
super(context);
}
public TextNew(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(5);
int whidth = getWidth();
int heith = getBaseline();
canvas.drawLine(0,heith,whidth,heith,paint);
}
public TextNew(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
蒙上一层蒙版
package com.hopu.day40tage01;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
public class LInerMask extends LinearLayout {
public LInerMask(Context context) {
super(context);
}
public LInerMask(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public LInerMask(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public LInerMask(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
canvas.drawColor(Color.parseColor("#50939393"));
}
}
5. 在布局当中引用该控件
<?xml version="1.0" encoding="utf-8"?>
<com.hopu.day40tage01.LInerMask 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">
<com.hopu.day40tage01.Handerr
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<com.hopu.day40tage01.TextNew
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center_vertical"
android:text="测试"/>
</com.hopu.day40tage01.LInerMask>
绘图相关的 一些API,他们分别是Canvas(画布),Paint(画笔),Path(路径)
实现以下效果
1.继承android.view.View
package com.hopu.day40tage02;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
public class View extends android.view.View {
private Paint paint;
public View(Context context) {
super(context);
init();
}
public View(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
paint = new Paint();
paint.setColor(getResources().getColor(R.color.purple_200));
paint.setStrokeWidth(5);
paint.setTextSize(36);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(getResources().getColor(R.color.teal_200));
canvas.drawCircle(getWidth()/2,getHeight()/2,100,paint);
canvas.drawRect(300,300,600,500,paint);
// canvas.drawBitmap((BitmapFactory.decodeResource(getResources(),R.mipmap.a1)),0,0,paint);
Paint textpaint = new Paint();
textpaint.setColor(getResources().getColor(R.color.white));
textpaint.setTextSize(50);
canvas.drawText("15",getWidth()/2,getHeight()/2,textpaint);
canvas.drawRoundRect(new RectF(600,10,810,110),15,15,paint);
Path path = new Path();
path.moveTo(10,10);
path.lineTo(100,50);
path.lineTo(300,150);
path.close();
canvas.drawPath(path,paint);
Path path1 = new Path();
path.moveTo(50,50);
path.lineTo(100, 100);
path.lineTo(200, 200);
path.lineTo(300, 300);
path.close();
canvas.drawTextOnPath("abcdefghijklmnopqrstuvwxyz", path, 25, 25, paint);
}
}
在布局当中引用该控件
<?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"
tools:context=".MainActivity">
<com.hopu.day40tage02.View
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>