Android学习之自定义布局与属性的创建与使用

一、效果图

1. settings_item.xml

settings_item.xml

2. activity_main.xml

activity_main.xml

二、实现步骤

1. 自定义布局文件,绘制想要重复使用的自定义布局。(settings_item.xml)
<?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:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="8dp"
    android:paddingBottom="8dp">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_alignParentLeft="true"
        android:layout_centerInParent="true"
        android:layout_margin="5dp"
        android:src="@drawable/personaldata" />

    <TextView
        android:id="@+id/title_text"
        android:layout_width="wrap_content"
        android:layout_height="25dp"
        android:gravity="center_vertical"
        android:layout_marginRight="5dp"
        android:layout_marginLeft="16dp"
        android:layout_toRightOf="@id/icon"
        android:layout_centerInParent="true"
        android:text="@string/s_settings_item_personal_data"
        android:textColor="#292929"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="25dp"
        android:gravity="center_vertical"
        android:layout_marginRight="8dp"
        android:layout_marginLeft="5dp"
        android:layout_toLeftOf="@id/forward"
        android:layout_centerInParent="true"
        android:text="@string/s_settings_item_real_name_check"
        android:textSize="16sp"/>

    <ImageView
        android:id="@+id/forward"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_margin="5dp"
        android:layout_alignParentRight="true"
        android:layout_centerInParent="true"
        android:src="@drawable/forward" />
    
</RelativeLayout>
2. 自定义属性,编写自定义的属性。(values/attrs.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--
        一个属性集合,外层的name是属性集合名称,
        内层的name则是属性的名称,format则是属性的值的类型
    -->
    <declare-styleable name="SettingsItemLayout">
        <attr name="title_text" format="string" />
        <attr name="complement_text" format="string" />
        <attr name="icon_iv" format="reference" />
        <attr name="forward_iv" format="reference" />
    </declare-styleable>
</resources>
3. 编写控制自定义布局的java类实现对其控制。(SettingsItemLayout.java)
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class SettingsItemLayout extends RelativeLayout {

    private ImageView mIconIV;//最左侧图标
    private int icon;//图标对应资源id
    private String titleText;//标题文字
    private TextView mTitleTextTV;//标题文字对应的TextView
    private String complementText;//标题文字
    private TextView mComplementTextTV;//标题文字对应的TextView
    private ImageView mForwardIV;//最左侧图标
    private int forward;//最左侧图标对应资源id

    /*
    构造函数,参数一:上下文;参数二:属性集
     */
    public SettingsItemLayout(Context context, AttributeSet attrs){
        super(context,attrs);
        //加载自定义布局
        LayoutInflater.from(context).inflate(R.layout.settings_item,this);
        //实例化组件
        mIconIV = (ImageView) findViewById(R.id.icon);
        mForwardIV = (ImageView) findViewById(R.id.forward);
        mTitleTextTV = (TextView)findViewById(R.id.title_text);
        mComplementTextTV = (TextView)findViewById(R.id.complement_text);

        /*
            每一个属性集合编译之后都会对应一个styleable对象,
            通过styleable对象获取TypedArray typedArray,然后通过键值对获取属性值。
            R.styleable.SettingsItemLayout,SettingsItemLayout对应attrs里面属性集的名称而不是本类的类名
         */
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SettingsItemLayout);
        if (typedArray != null) {
            titleText = typedArray.getString(R.styleable.SettingsItemLayout_title_text);
            complementText = typedArray.getString(R.styleable.SettingsItemLayout_complement_text);
            icon = typedArray.getResourceId(R.styleable.SettingsItemLayout_icon_iv,R.drawable.personaldata);
            forward = typedArray.getResourceId(R.styleable.SettingsItemLayout_forward_iv,R.drawable.forward);
            typedArray.recycle();
        }
        //将自定义的属性值设置到组件上
        mTitleTextTV.setText(titleText);
        mComplementTextTV.setText(complementText);
        //Drawable drawableIcon = context.getDrawable(icon);
        mIconIV.setImageResource(icon);
        mForwardIV.setImageResource(forward);
        /* 可对组件设置点击事件
        mTitleTextTV.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                ((Activity) getContext()).finish();
            }
        });*/
    }

    /*
        设置组件内容,不同参数,字符串或者资源id
     */
    public void setTitleText(String titleText){
        mTitleTextTV.setText(titleText);
    }

    public void setTitleText(int titleText){
        mTitleTextTV.setText(titleText);
    }

    public void setComplementText(String complementText){
        mComplementTextTV.setText(complementText);
    }

    public void setComplementText(int complementText){
        mComplementTextTV.setText(complementText);
    }

    public void setIconIV(int id){
        mIconIV.setImageResource(id);
    }

    public void setForwardIV(int id){
        mForwardIV.setImageResource(id);
    }

    //设置组件的可见性 0 GONE 1 INVISIBLE 2 VISIBLE
    public void setIconIVVisibility(int flag){
        switch (flag){
            case 0:
                mIconIV.setVisibility(GONE);
                break;
            case 1:
                mIconIV.setVisibility(INVISIBLE);
                break;
            case 2:
                mIconIV.setVisibility(VISIBLE);
                break;
            default:break;
        }
    }

    public void setForwardIVVisibility(int flag){
        switch (flag){
            case 0:
                mForwardIV.setVisibility(GONE);
                break;
            case 1:
                mForwardIV.setVisibility(INVISIBLE);
                break;
            case 2:
                mForwardIV.setVisibility(VISIBLE);
                break;
            default:break;
        }
    }

    public void setTitleTextTVVisibility(int flag){
        switch (flag){
            case 0:
                mTitleTextTV.setVisibility(GONE);
                break;
            case 1:
                mTitleTextTV.setVisibility(INVISIBLE);
                break;
            case 2:
                mTitleTextTV.setVisibility(VISIBLE);
                break;
            default:break;
        }
    }

    public void setComplementTextTVVisibility(int flag){
        switch (flag){
            case 0:
                mComplementTextTV.setVisibility(GONE);
                break;
            case 1:
                mComplementTextTV.setVisibility(INVISIBLE);
                break;
            case 2:
                mComplementTextTV.setVisibility(VISIBLE);
                break;
            default:break;
        }
    }
}

4. 在布局文件中使用。(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hzf="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <!--为属性集设置一个属性集名称,这里使用hzf。-->

    <com.hzf.nicholas.customlayouttest.SettingsItemLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        hzf:title_text="@string/s_settings_item_personal_data"
        hzf:complement_text="@string/s_settings_item_personal_data_cp">

    </com.hzf.nicholas.customlayouttest.SettingsItemLayout>

    <com.hzf.nicholas.customlayouttest.SettingsItemLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        hzf:title_text="@string/s_settings_item_real_name_check"
        hzf:complement_text="@string/s_settings_item_real_name_check_cp"
        hzf:forward_iv="@drawable/forward"
        hzf:icon_iv="@drawable/realname">

    </com.hzf.nicholas.customlayouttest.SettingsItemLayout>

    <com.hzf.nicholas.customlayouttest.SettingsItemLayout
        android:id="@+id/test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    </com.hzf.nicholas.customlayouttest.SettingsItemLayout>

</LinearLayout>
5. 在活动中使用java类控制。(MainActivity.java)
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    private SettingsItemLayout mSettingsItemLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mSettingsItemLayout = (SettingsItemLayout)findViewById(R.id.test);
        //通过java类控制
        mSettingsItemLayout.setIconIV(R.drawable.changepwd);
        mSettingsItemLayout.setTitleText("修改密码");
        mSettingsItemLayout.setComplementTextTVVisibility(0);
    }
}

三、参考博客

liu_xi_xin Android中自定义属性的使用
https://blog.csdn.net/liu_xi_xin/article/details/54934545
鸿洋_ Android 深入理解Android中的自定义属性
https://blog.csdn.net/lmj623565791/article/details/45022631
总李写代码 Android自定义控件之自定义属性
http://www.cnblogs.com/whoislcj/p/5711001.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值