Android的创建复合控件

新建工程,在values新建resour flie,取名为attrs(attr是attribute 属性的简写,因为有多个属性,所以就取名为attrs )。
先举个栗子

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="myTop">
        <attr name="mTitleText" format="string"/>
        <attr name="mTitleTextColor" format="color"/>
        <attr name="mTitleTextSize" format="dimension"/>
        <attr name="leftBackground" format="color|reference"/>
        <attr name="leftText" format="string"/>
        <attr name="leftTextColor" format="color"/>
        <attr name="rightBackground" format="color|reference"/>
        <attr name="rightText" format="string"/>
        <attr name="rightTextColor" format="color"/>
    </declare-styleable>
</resources>

解释一下代码,resources是根节点,不用管,创建就会自动生成。declare-styleable 标签声明了使用自定义属性,并通过name属性来确定引用的名称.

然后declare下面有多个attr,即为定义的多个属性,每个自定义属性都有name和format,name不用说,format即为属性的类型。

属性定义好了,就要自定义一个View了

创建一个Class,取名为MyView,继承自ViewGroup(或者RelativeLayout或者LinearLayout),然后重写带两个参数的方法

public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
}

然后在方法里写
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.myTop);
通过TypeArray这样的数据结构来获取自定义属性集

再通过get×××获得属性值(这里属性太多,我就只写了一条获取属性值的例子)

        String rightText = typedArray.getString(R.styleable.myTop_rightText);

全部属性都获取完成之后,那么TypeArray就已经没用了,所以最后执行

typedArray.recycle();//来完成资源的回收,避免重新创建的时候发生错误

然后再将属性值赋给控件的实例(这里的context即为上面两个参数的构造函数里面的一个参数)

Button rightBtn = new Button(context);
rightBtn.setText(rightText);

OK!到现在我们已经自定义了多个属性,并把属性赋给了新建的控件,然后该为组件设置布局了吧

private LayoutParams titleParam;

titleParam= new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

addView(title,titleParam);

到此为止,自定义View就差不多结束了。该去layout里面使用了吧
进入activity_main.xml 可以看到这样一行代码

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns即xml namespace。这里指定了名字控件为”android”,所以在下面的代码里才可以使用android:layout_width、android:layout_height等等以android开头的。所以,我们在下面加上一行

xmlns:myview="http://schemas.android.com/apk/res-auto"

这样我们就可以使用我们的自定义属性了,myview是名字,可以随便起。最后的res-auto是Android Studio里面使用的,而在eclipse里面需要加完整的包名。

下面我们就可以定义属性的值了

<com.example.antact.myview.MyView
        android:id="@+id/my_view"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        myview:mTitleText="自定义标题"
        myview:mTitleTextColor="#123456"
        myview:mTitleTextSize="8sp"
        myview:leftBackground="#678905"
        myview:leftText="左按钮"
        myview:leftTextColor="#456789"
        myview:rightBackground="#678905"
        myview:rightText="右按钮"
        myview:rightTextColor="#456789">

    </com.example.antact.myview.MyView>

到这里就自定义View就结束了。最后展示一下效果图
这里写图片描述

如果我们想为左右Button添加点击事件,你肯定想直接在MyView里面

leftBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                 //Toast
            }
        });

但是这样写就把代码写死了,不一定每个调用这个View的leftButton的功能都是一样的。所以这里需要定义一个接口,并把接口暴露给调用者

private OnMyViewClickListener listener;

public interface OnMyViewClickListener{
        void leftClick();
        void rightClick();
}

public void setOnMyViewClickListener(OnMyViewClickListener mListener){
        listener = mListener;
}

所以下面的Button只用写

leftBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                 listener.leftClick();
            }
        });

具体的方法在MainActivity里面实现

MyView myView = (MyView)findViewById(R.id.my_view);
myView.setOnMyViewClickListener(new MyView.OnMyViewClickListener() {
            @Override
            public void leftClick() {
                Toast.makeText(MainActivity.this,"leftButton",Toast.LENGTH_LONG).show();
            }

            @Override
            public void rightClick() {
                Toast.makeText(MainActivity.this,"rightButton",Toast.LENGTH_LONG).show();
            }
        });

通过如上所示的代码,我们可以在其他布局文件中,直接通过include使用模板。

到这里,所有的总结完成了。

最后,贴一下源码
attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="myTop">
    <attr name="mTitleText" format="string"/>
    <attr name="mTitleTextColor" format="color"/>
    <attr name="mTitleTextSize" format="dimension"/>
    <attr name="leftBackground" format="color|reference"/>
    <attr name="leftText" format="string"/>
    <attr name="leftTextColor" format="color"/>
    <attr name="rightBackground" format="color|reference"/>
    <attr name="rightText" format="string"/>
    <attr name="rightTextColor" format="color"/>
</declare-styleable>
</resources>

MyView.java

package com.example.antact.myview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * Created by Antact on 2017/5/13.
 */


public class MyView extends RelativeLayout{

    private TextView title;
    private Button leftBtn;
    private Button rightBtn;
    private RelativeLayout.LayoutParams titleParam,leftParam,rightParam;

    private OnMyViewClickListener listener;

    public interface OnMyViewClickListener{
        void leftClick();
        void rightClick();
    }

    public void setOnMyViewClickListener(OnMyViewClickListener mListener){
        listener = mListener;
    }



    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.myTop);
        int titleTextColor = typedArray.getColor(R.styleable.myTop_mTitleTextColor, 0);
        String titleText = typedArray.getString(R.styleable.myTop_mTitleText);
        float titleTextSize = typedArray.getDimension(R.styleable.myTop_mTitleTextSize, 0);
        Drawable leftBackground = typedArray.getDrawable(R.styleable.myTop_leftBackground);
        String leftText = typedArray.getString(R.styleable.myTop_leftText);
        int leftColor = typedArray.getColor(R.styleable.myTop_leftTextColor, 0);
        Drawable rightBackground = typedArray.getDrawable(R.styleable.myTop_rightBackground);
        String rightText = typedArray.getString(R.styleable.myTop_rightText);
        int rightColor = typedArray.getColor(R.styleable.myTop_rightTextColor, 0);
        typedArray.recycle();

        title = new TextView(context);
        leftBtn = new Button(context);
        rightBtn = new Button(context);

        title.setTextColor(titleTextColor);
        title.setText(titleText);
        title.setTextSize(titleTextSize);

        leftBtn.setBackground(leftBackground);
        leftBtn.setText(leftText);
        leftBtn.setTextColor(leftColor);

        rightBtn.setBackground(rightBackground);
        rightBtn.setText(rightText);
        rightBtn.setTextColor(rightColor);

        titleParam = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        titleParam.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);
        addView(title,titleParam);

        leftParam = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
        leftParam.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);
        addView(leftBtn,leftParam);

        rightParam = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
        rightParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);
        addView(rightBtn,rightParam);


        leftBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                listener.leftClick();
            }
        });

        rightBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                listener.rightClick();
            }
        });




    }



}

activity_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:myview="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.antact.myview.MyView
        android:id="@+id/my_view"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        myview:mTitleText="自定义标题"
        myview:mTitleTextColor="#123456"
        myview:mTitleTextSize="8sp"
        myview:leftBackground="#678905"
        myview:leftText="左按钮"
        myview:leftTextColor="#456789"
        myview:rightBackground="#678905"
        myview:rightText="右按钮"
        myview:rightTextColor="#456789">

    </com.example.antact.myview.MyView>


</RelativeLayout>

MainActivity.java

package com.example.antact.myview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyView myView = (MyView)findViewById(R.id.my_view);
        myView.setOnMyViewClickListener(new MyView.OnMyViewClickListener() {
            @Override
            public void leftClick() {
                Toast.makeText(MainActivity.this,"leftButton",Toast.LENGTH_LONG).show();
            }

            @Override
            public void rightClick() {
                Toast.makeText(MainActivity.this,"rightButton",Toast.LENGTH_LONG).show();
            }
        });
    }
}

/参考自Android群英传

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值