Android自定义控件-完全自定义(继承View ,ViewGroup)

完全自定义控件步骤:

一.自定义view并绘制

1. 写个类继承View
首先写一个类继承View或ViewGroup,并实现其构造方法,View类的构造方法有三种并且有不同的作用,作用分别为:

 /**
     * 用于代码创建控件
     * @param context
     */
    public ToggleView(Context context) {
        super(context);
    }

    /**
     * 用于在xml里使用, 可指定自定义属性
     * @param context
     * @param attrs
     */
    public ToggleView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 用于在xml里使用, 可指定自定义属性, 如果指定了样式, 则走此构造函数
     * @param context
     * @param attrs
     * @param defStyle
     */
    public ToggleView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

2. 拷贝包含包名的全路径到xml中
在布局文件中使用该自定义控件,空间名字为“包含包名的全路径”,如:

 <com.app.demo.ToggleView
        android:id="@+id/toggleView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"/>

3. 界面中找到该控件, 设置初始信息
在未声明自定义属性之前,可在主界面类中找到该控件并设置一些基本信息,在声明了自定义属性后可将其注释直接在xml布局中设置信息:

public class MainActivity extends Activity {

    private ToggleView toggleView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toggleView = (ToggleView) findViewById(R.id.toggleView); 
                                        toggleView.setSwitchBackgroundResource(R.drawable.switch_background); //设置开关背景 
                             toggleView.setSlideButtonResource(R.drawable.slide_button);//设置滑块背景
       toggleView.setSwitchState(true);//设置开关状态 
        });
    }  
}

上述三个方法在定义控件的类中编写:

/**
     * 设置背景图
     * @param switchBackground
     */
    public void setSwitchBackgroundResource(int switchBackground) {
        switchBackgroupBitmap = BitmapFactory.decodeResource(getResources(), switchBackground);
    }

    /**
     * 设置滑块图片资源
     * @param slideButton
     */
    public void setSlideButtonResource(int slideButton) {
        slideButtonBitmap = BitmapFactory.decodeResource(getResources(), slideButton);
    }

    /**
     * 设置开关状态
     * @param mSwitchState
     */
    public void setSwitchState(boolean mSwitchState) {
        this.mSwitchState = mSwitchState;
    }

4. 根据需求绘制界面内容

  • Android 的界面绘制流程
    基本操作由三个函数完成:measure()、layout()、draw(),其内部又分别包含了onMeasure()、onLayout()、onDraw()三个子方法。
  测量             摆放     绘制
  measure   ->  layout  ->  draw
      |           |          |
  onMeasure -> onLayout -> onDraw 重写这些方法, 实现自定义控件

  都在onResume()之后执行

  View流程
  onMeasure() (在这个方法里指定自己的宽高) -> onDraw() (绘制自己的内容)

  ViewGroup流程
  onMeasure() (指定自己的宽高, 所有子View的宽高)-> onLayout() (摆放所有子View) -> onDraw() (绘制内容)

5. 响应用户的触摸事件
重写触摸事件, 响应用户的触摸.

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_MOVE:
            break;
        case MotionEvent.ACTION_UP:
            break;
        default:
            break;
        }
        // 重绘界面
        invalidate(); // 会引发onDraw()被调用, 里边的变量会重新生效.界面会更新
        return true; // 消费了用户的触摸事件, 才可以收到其他的事件.
    }

6. 创建一个状态更新监听
定义接口,在主界面监听

二.自定义View属性

  1. 在attrs.xml声明节点declare-styleable

    
        
        
        
    
    
  2. 在xml配置声明的属性/ 注意添加命名空间
    命名方式:xmlns: 自定义名字=”http://schemas.android.com/apk/res/包名”

 <com.app.demo.ToggleView   xmlns:uview="http://schemas.android.com/apk/res/com.app.demo"
        android:id="@+id/toggleView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        uview:switch_background="@drawable/switch_background"
        uview:slide_button="@drawable/slide_button"
        uview:switch_state="true"
        android:layout_centerInParent="true"/>
4. 在构造函数中获取并使用
    // 获取配置的自定义属性
        String namespace = "http://schemas.android.com/apk/res/com.app.demo";
        int switchBackgroundResource = attrs.getAttributeResourceValue(namespace , "switch_background", -1);
        int slideButtonResource = attrs.getAttributeResourceValue(namespace , "slide_button", -1);

        mSwitchstate = attrs.getAttributeBooleanValue(namespace, "switch_state", false);
        setSwitchBackgroundResource(switchBackgroundResource);
        setSlideButtonResource(slideButtonResource);

你可能感兴趣的:(Android)