一、效果图
1. settings_item.xml
2. 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