码迷,mamicode.com
首页 > 其他好文 > 详细

自定义组合控件和在自定义控件中使用自定义属性

时间:2016-07-17 17:19:45      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:

今天,整理了一下我平时的笔记,写一个比较简单的自定义组合控件,仅供小白参考,大神请绕道,希望能够对大家有一些帮助
首先,得明白为什么我们需要自定义组合控件,它是因为原有控件并不能满足开发的需求,或者说并不能达到我们想要的一种效果,这个时候,就需要我们自己定义一些控件,以达到目的
![先来看一下效果](http://img.blog.csdn.net/20160716224219109)

个人总结自定义控件的步骤:
1、先写一个布局,这里我用的是一个相对布局,我这里的相对布局就是根布局了

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:paddingBottom="10dp"
    android:paddingLeft="15dp"
    android:paddingRight="15dp"
    android:paddingTop="10dp" >

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:text="设置自动更新"
        android:textColor="#000000"
        android:textSize="16sp" />

    <ImageView
        android:id="@+id/iv_toggle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerHorizontal="true"
        android:src="@drawable/off" />

</RelativeLayout>
2、用一个类去继承这个布局(相对布局),注意一下,这里最好继承这个布局的根布局,因为有可能会用到根布局里的一些属性
public class SettingItemView extends RelativeLayout{}
3、继承布局的这个类会实现三个构造方法,一般情况下,用到那个就从写那个,但是,如果你不知道要用到那个,那么,你可以三个都实现,通过有一个参数和两个参数的构造方法去调用第三个构造方法,因为第三个构造方法系统并不会自动帮我们调用
    //这个构造方法系统不会帮我们调用,需要通过另外两个方法来调用这个方法,那么,这时候,初始化的一些数据就可一个在这个方法中实现
    public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
}
    //通过下面这两个构造方法,去调用上面的那个构造方法
public SettingItemView(Context context, AttributeSet attrs) {
        this(context, attrs,0);

    }

    public SettingItemView(Context context) {
        this(context,null);

    }

下面是自定义组合控件的完整代码`,在这里我给它起名为SettingItemView.java

public class SettingItemView extends RelativeLayout{

    public static final String NAMESPACE ="http://schemas.android.com/apk/res/com.xxx.myphonesafe";
    private View view;
    private TextView tv_title;
    private ImageView iv_toggle;
    boolean isToggle = false;  //记录当前开关的状态

    public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        //读取布局文件中给自定义控件使用的属性
        //参数1:布局的命名空间
        //参数2:布局中控件的属性
        //参数3:默认值,如果在读取控件的属性没有读取到时,就返回默认的值
        /**
         * backaground、title、isShowToggle为控件的自定义属性
         * 自定义属性步骤:
         * 1、在res/values下新建一个attrs.xml
         * 2、在自定义类中通过attrs去获取这些属性,如attrs.getAttributeIntValue(NAMESPACE, "backgroundres", 0);
         * 3、在布局文件中使用这些属性时,需要声明命名空间
         * 4、  xmlns:abc="http://schemas.android.com/apk/res/com.xxx.myphonesafe"
         *  注意以下三点:
         * abc:可以随便更换为其他字符,但是在下面使用属性时必须保证和你更换后的字符串相同
         * com.xxx.myphonesafe:对应的是你在清单文件中的包名,必须和清单文件一致,不能随意更改
         * NAMESPACE:命名空间必须和在布局中使用的命名空间一致
         */
        //获取布局中的属性值
        int backaground = attrs.getAttributeIntValue(NAMESPACE, "backgroundres", 0);
        String title = attrs.getAttributeValue(NAMESPACE, "title");
        boolean isShowToggle = attrs.getAttributeBooleanValue(NAMESPACE, "isshowtoggle", true);


        //加载布局文件
        initView();
        //设置标题
        tv_title.setText(title);
        //根据属性值设置条目
        if(isShowToggle){
            iv_toggle.setVisibility(View.VISIBLE);
        }else {
            iv_toggle.setVisibility(View.INVISIBLE);
        }

        //设置背景颜色
        setBackGround(backaground);

    }



    private void setBackGround(int backaground) {
        switch (backaground) {
        case 0:  //first
            setBackgroundResource(R.drawable.first_normal);
            break;

        case 1:  //middle
            setBackgroundResource(R.drawable.middle_normal);
            break;
        case 2:  //last
            setBackgroundResource(R.drawable.last_normal);
            break;
        }
    }


    public SettingItemView(Context context, AttributeSet attrs) {
        this(context, attrs,0);

    }

    public SettingItemView(Context context) {
        this(context,null);

    }

    /**
     * 初始化布局文件
     */
    private void initView() {
        view = View.inflate(getContext(), R.layout.setting_item_view, null);
        tv_title = (TextView) view.findViewById(R.id.tv_title);    //获取自动更新的id
        iv_toggle = (ImageView) view.findViewById(R.id.iv_toggle); //获取开关的id
        addView(view);
    }

    /**
     * 判断开关 是否打开
     * @param isToggle
     * @return
     */
    public boolean isToggle(){

        return isToggle;
    }

    public void  setToggle(boolean toggle){
        //记录当前的开关状态
        isToggle = toggle;
        if(toggle){ 
            //根据toggle的值切换图片
            iv_toggle.setImageResource(R.drawable.on);
        }else {
            iv_toggle.setImageResource(R.drawable.off);
        }
    }

}

自定义属性如下:
在res/values下新建一个attrs.xml(attrs.xml这个文件的命名最好为attrs),代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
             <!-- 注意 -->
    <!-- value:不要写成 values-->
    <!-- string:不要写成 String-->
     <declare-styleable name="SettingItemView">
       <!-- 用来控制显示的背景图 -->
        <attr name="backgroundres">
            <enum name="first" value="0" />
            <enum name="middle" value="1" />
            <enum name="last" value="2" />
        </attr>

        <!-- 用来控制显示的文字 -->
        <attr name="title" format="string" />
        <!-- 用来控制是否显示开关 -->
        <attr name="isshowtoggle" format="boolean" />


        </declare-styleable>
</resources>

4、新建一个布局(暂且命名为a.xml),在布局中使用这个自定义的组合控件
注意,要在这里引用命名空间,因为你用到了自定义属性,而且要和自定义组合控件中的命名空间一致

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:abc="http://schemas.android.com/apk/res/com.xxx.myphonesafe"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        style="@style/TitleStyle"
        android:text="设置中心" />
    <!-- 怎么在自定义组合控件的布局中获取自定义控件中的自定义属性  注意这种方法 -->
    <!-- 注意需要声明命名空间 -->


    <!-- 要记得声明命名空间 -->
    <!-- com.abc.myphonesafe:对应的是清单文件中的包名 -->
    <!--
         * 自定义属性步骤:
         * 1、在res/values下新建一个attrs.xml
         * 2、在自定义类中通过attrs去获取这些属性,如attrs.getAttributeIntValue(NAMESPACE, "backgroundres", 0);
         * 3、在布局文件中使用这些属性时,需要声明命名空间
         * 4、  xmlns:abc="http://schemas.android.com/apk/res/com.abc.myphonesafe"
         *  注意以下两点:
         * abc:可以随便更换为其他字符,但是在下面使用属性时必须保证和你更换后的字符串相同
         * com.abc.myphonesafe:对应的是你在清单文件中的包名,必须和清单文件一致,不能随意更改
    -->

    <com.xxx.myphonesafe.ui.SettingItemView
        android:id="@+id/siv_auto_update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:background="@drawable/color_selector"
        abc:backgroundres="first"
        abc:isshowtoggle="true"
        abc:title="设置是否自动更新" />

    <com.xxx.myphonesafe.ui.SettingItemView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        abc:backgroundres="last"
        abc:isshowtoggle="true"
          android:background="@drawable/color_selector"
       abc:title="设置拦截骚扰" />

</LinearLayout>

最后,新建一个Activity,在Activity使用这个a.xml
希望能对看到此文的小伙伴有所帮助

自定义组合控件和在自定义控件中使用自定义属性

标签:

原文地址:http://blog.csdn.net/teashui/article/details/51927072

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!