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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章