自定義View之自定義設(shè)置界面欄位

自定義View之自定義設(shè)置界面欄位

在app的應(yīng)用設(shè)置中經(jīng)常會(huì)有如下所示的設(shè)置樣式,正好學(xué)習(xí)自定義view,下面我們就先實(shí)現(xiàn)一個(gè);

效果
效果

1.開啟新的自定義view

public class ComboBox extends RelativeLayout{

    public ComboBox(Context context) {
        super(context);
    }

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

    public ComboBox(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
  }

2.設(shè)置到xml中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.skkk.ww.costomviewdemo.MainActivity">
        <com.skkk.ww.costomviewdemo.ComboBox
            android:id="@+id/cb_test"
            combo:title="測(cè)試一下吧"
            combo:checkedContent="右側(cè)勾選框被選中"
            combo:unCheckContent="右側(cè)勾選框取消選中"
            combo:ischeck="true"
            android:layout_width="match_parent"
            android:layout_height="100dp" />
</LinearLayout>  

其實(shí)這個(gè)時(shí)候運(yùn)行項(xiàng)目就可以顯示出自定義view了,但是我沒(méi)什么都沒(méi)有設(shè)置,所以只是一片空白;

3.自定義view布局

  • 自定義view布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    
        <LinearLayout
            android:id="@+id/ll_left"
            android:layout_weight="1"
            android:layout_margin="5dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <TextView
                android:id="@+id/tv_title_cb"
                android:text="Title"
                android:textSize="30dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
    
            <TextView
                android:id="@+id/tv_content_cb"
                android:textSize="20dp"
                android:text="Content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    
        <CheckBox
            android:id="@+id/cb_select_cb"
            android:layout_marginRight="10dp"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />
    
    </LinearLayout>
    
  • 引用布局

    private void initUI(Context context) {
        LayoutInflater.from(context).inflate(R.layout.layout_combobox,this,true);
        tvTitle= (TextView) findViewById(R.id.tv_title_cb);
        tvContent= (TextView) findViewById(R.id.tv_content_cb);
        cbCombo= (CheckBox) findViewById(R.id.cb_select_cb);
        llLeft= (LinearLayout) findViewById(R.id.ll_left);
    }
    

    當(dāng)然initUI方法還需要加入到構(gòu)造方法中,不然就沒(méi)效果了。

    效果
    效果

4.自定義屬性

通過(guò)以上的操作我們就可以得到一個(gè)像模像樣的設(shè)置欄位了,當(dāng)然,所有的屬性我們都需要在java文件中修改,這不是我們想要的,我們?nèi)绾尾拍芟蛘5目丶粯釉趚ml中定義各種屬性呢?這就需要用的自定義屬性了。

  • 定義屬性

    1.首先我們需要新建一個(gè)文件attrs.xml,如下圖所示:

    attrs.xml
    attrs.xml

    2.然后具體定義屬性內(nèi)容:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="ComboBox">
            <attr name="title" format="string"/>
            <attr name="checkedContent" format="string"/>
            <attr name="unCheckContent" format="string"/>
            <attr name="ischeck" format="boolean"/>
        </declare-styleable>
    </resources>
    
  • 引用屬性

    private String title,checkContent,unCheckContent;
    private boolean isChecked;
    private TextView tvTitle,tvContent;
    private CheckBox cbCombo;
    
    private void initAttr(Context context, AttributeSet attrs) {
        TypedArray ta=context.obtainStyledAttributes(attrs,
                R.styleable.ComboBox);
    
        title=ta.getString(R.styleable.ComboBox_title);
        checkContent=ta.getString(R.styleable.ComboBox_checkedContent);
        unCheckContent=ta.getString(R.styleable.ComboBox_unCheckContent);
        isChecked=ta.getBoolean(R.styleable.ComboBox_ischeck,false);
    
        //獲取完值之后我們需要調(diào)用recycle()方法來(lái)避免重新創(chuàng)建的時(shí)候的錯(cuò)誤
        ta.recycle();
    }
    

    我們通過(guò)獲取TyoedArray對(duì)象來(lái)獲取到我們自定義的屬性,獲取到屬性之后在賦值到我們定義的內(nèi)部屬性里,這樣就可以調(diào)用了

    tvTitle.setText(title);
    tvContent.setText(isChecked?checkContent:unCheckContent);
    cbCombo.setChecked(isChecked);
    cbCombo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            tvContent.setText(isChecked?checkContent:unCheckContent);
        }
    });
    
  • 使用屬性

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:combo="http://schemas.android.com/apk/res-auto"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.skkk.ww.costomviewdemo.MainActivity">
    
        <com.skkk.ww.costomviewdemo.CostomScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <ImageView
                android:scaleType="fitXY"
                android:layout_width="match_parent"
                android:layout_height="100dp"
                android:src="@mipmap/ic_launcher"
                />
            <com.skkk.ww.costomviewdemo.ComboBox
                android:id="@+id/cb_test"
                combo:title="這里是我們定義的標(biāo)題"
                combo:checkedContent="選中了,wow!"
                combo:unCheckContent="沒(méi)被選中,好煩躁!"
                combo:ischeck="true"
                android:layout_width="match_parent"
                android:layout_height="100dp" />
    </LinearLayout>
    

    這樣我們可以在xml中定義我們的屬性了,效果如下:

    attr2
    attr2
    attr3
    attr3

5.自定義方法

能夠在xml中設(shè)置屬性還不夠,我們還要在java代碼中設(shè)置屬性,接下來(lái)構(gòu)造對(duì)應(yīng)的設(shè)置方法

  • 設(shè)置基本屬性getter&setter方法

    /**
         * 設(shè)置標(biāo)題
         * @param title
         */
        public void setTitle(String title){
            tvTitle.setText(title);
        }
    
        /**
         * 設(shè)置勾選顯示文本
         * @param checkContent
         */
        public void setCheckContent(String checkContent) {
            this.checkContent = checkContent;
        }
    
        /**
         * 設(shè)置未勾選顯示文本
         * @param unCheckContent
         */
        public void setUnCheckContent(String unCheckContent) {
            this.unCheckContent = unCheckContent;
        }
    
        /**
         * 設(shè)置是否勾選
         * @param checked
         */
        public void setChecked(boolean checked){
            cbCombo.setChecked(checked);
        }
    
        /**
         * 返回是否勾選
         * @return boolean
         */
        public boolean isChecked(){
            return cbCombo.isChecked();
        }
    
  • 設(shè)置點(diǎn)擊事件

    當(dāng)然還有自定義view的點(diǎn)擊事件,我得需求是除開CheckBox之外的部分響應(yīng),也就是上面對(duì)上面初始化的左邊的LinearLayout進(jìn)行點(diǎn)擊事件設(shè)置

    /**
     * 設(shè)置點(diǎn)擊事件
     * @param listener 對(duì)左側(cè)文本LinearLayout設(shè)置點(diǎn)擊事件
     */
    public void setLeftContainerClickListener(OnClickListener listener){
        this.setOnClickListener(listener);
    }
    

6.正式使用

public class MainActivity extends AppCompatActivity {
    private ComboBox cbTest;
    private String TAG=this.getClass().getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cbTest = (ComboBox) findViewById(R.id.cb_test);
        cbTest.setLeftContainerClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (cbTest.isChecked()){
                    Logger.t(TAG).i("設(shè)置勾選為TRUE");
                    cbTest.setChecked(false);
                }else {
                    cbTest.setChecked(true);
                }
            }
        });
    }
}

這樣就獲得了一個(gè)簡(jiǎn)單的自定義view!

7.源碼傳送門

我是一只咸魚,不想承認(rèn),也不能否認(rèn),不要同情我笨,又夸我天真,還夢(mèng)想著翻身...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容