美文网首页
Android 自定义View

Android 自定义View

作者: 愈强 | 来源:发表于2020-07-04 14:14 被阅读0次

本文包含以下内容

  • 定义一个自己的View
  • 添加自己的绘制内容
  • 处理View的手势
  • 在xml中使用自定义的类
  • 自定义View属性,以及其使用方法
  1. 创建MyView类,并继承系统的View类
package com.mypackage.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

    public MyView(Context context) {
        this(context, null);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}
  1. 此时,就可以在xml文件中添加自定义的View了
    <com.mypackage.view.MyView
        android:id="@+id/my_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
  1. 在代码中访问自定义View的方式与访问其他View是一致的
MyView myView = findViewById(R.id.my_view);
  1. 覆盖View父类的onDraw方法,并进行绘制
    // 新建一个Paint用于Canvas上的绘制。
    private Paint paint = new Paint();

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

        paint.setColor(Color.RED);
        int width = getWidth();
        int height = getHeight();
        int r = Math.min(width, height) / 2;
        // 这里在View的中间绘制了一个最大的正圆。
        canvas.drawCircle(width / 2, height / 2, r, paint);
    }

onDraw方法会被频繁调用,所以禁止在该方法内部创建对象。

可以使用invalidate或postInvalidate主动触发页面重绘,View接收到消息时会调用onDraw方法。

Canvas中声明了多种绘图方法,这里不过多介绍。

  1. 在View中接收处理手势事件,覆盖View中的onTouchEvent方法即可
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 获取事件类型
        int action = event.getAction();
        // 获取当前触摸位置
        float x = event.getX();
        float y = event.getY();

        if (action == MotionEvent.ACTION_DOWN) {
            // 处理按下事件
        } else if(action == MotionEvent.ACTION_MOVE) {
            // 处理移动事件
        } else {
            // 此时事件可能是抬起MotionEvent.ACTION_UP事件;
            // 也可能是取消MotionEvent.ACTION_CANCEL事件;
            // 如果支持多指触摸,还可能是其他的事件。
        }

        // 这里一定要返回true,如果返回false,则只会接收到onDown消息。
        // 父类方法默认返回false。
        return true;
    }
  1. 下面来添加一个自定义的属性,该属性允许使用者在xml中添加MyView的同时指定绘图的颜色。

首先,我们在res/values/attr.xml文件中添加如下代码。

<resources>
    <declare-styleable name="MyView">
        <attr name="circle_color" format="color"></attr>
    </declare-styleable>
</resources>

其中declare-styleable的name参数要与自定义View的名称一致,这是Android推荐做法,主要是为了避免命名冲突。
attr段定义了一个属性,名称为circle_color,值类型为color。可以定义多种类型的属性,包括int、boolean、string、reference等。

然后,在xml中就可以使用该属性了

<RelativeLayout 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">

    <com.yuqiang.tools.view.MyView
        android:id="@+id/select_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:circle_color="#00FF00" />
</RelativeLayout>

这里添加了两行代码,代码第二行声明了xmlns:app命名空间,表示可以使用自定义属性了。代码倒数第二行添加了app:circle_color属性并设置颜色值为绿色。

最后,需要在MyView内对属性进行解析:

public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);

    // 获取TypedArray对象
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyView);
    // 获取属性值并使用
    int color = typedArray.getColor(R.styleable.MyView_circle_color, Color.RED);
    // 。。。 使用属性值
    // 回收TypedArray对象
    typedArray.recycle();
}

注意一定要将TypedArray对象进行回收。

相关文章

网友评论

      本文标题:Android 自定义View

      本文链接:https://www.haomeiwen.com/subject/bmhuqktx.html