天天看點

自定義View之繼承ViewGroup

一個自定義View繼承ViewGroup的執行個體。先看效果圖,如下:

自定義View之繼承ViewGroup

該自定義View中有三個子控件組成,分别是TextView、EditText和ImageView。當EditText為空時不顯示ImageView,當EditText不為空時顯示ImageView,此時點選ImageView則清空EditText。

由于該自定義View中有三個子控件,是以我們可以選擇讓其繼承LinearLayout。

自定義View的屬性,首先在res/values/ 下建立一個attrs.xml , 在裡面定義我們的屬性和聲明我們的整個樣式。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyEdtiText">
        <attr name="left_text" format="string" />
        <attr name="textSize" format="dimension"/>
    </declare-styleable>
</resources>
           

以上代碼定義了左邊TextView的字型和字型大小。

接下來建立一個類MyEditText繼承自LinearLayout,在View的構造方法中,獲得我們的自定義的樣式。

package com.example.smily.customview02;

import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;


public class MyEdtiText extends LinearLayout {
    private View mInflate;
    private TextView mTextView;
    private EditText mEditText;
    private ImageView mImageView;
    private String mString;
    private int textSize;

    public MyEdtiText(Context context) {
        super(context);
        mInflate = View.inflate(context, R.layout.layout_edit, this);
    }

    public MyEdtiText(Context context, AttributeSet attrs) {
        this(context, attrs, );

    }

    public MyEdtiText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mInflate = View.inflate(context, R.layout.layout_edit, this);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyEdtiText, defStyleAttr, );
        int indexCount = typedArray.getIndexCount();
       // mString = typedArray.getString(R.styleable.MyEdtiText_left_text);
       for (int i = ; i < indexCount; i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
                case R.styleable.MyEdtiText_left_text:
                    mString = typedArray.getString(R.styleable.MyEdtiText_left_text);
                    break;
                case R.styleable.MyEdtiText_textSize:
                    // 預設設定為16sp,TypeValue也可以把sp轉化為px
                    textSize = typedArray.getDimensionPixelOffset(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, , getResources().getDisplayMetrics()));
                    break;
            }

        }


        typedArray.recycle();
    }

    //  通過java代碼設定左邊文字内容
    public void setLeftText(String string) {
        mTextView.setText(string);
    }

    //  通過java代碼設定字型大小
    public void setTextSize(int size) {
        mTextView.setTextSize(size);
        mEditText.setTextSize(size);
    }

    /**
     * 當View中所有的子控件均被映射成xml後觸發該方法
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mTextView = (TextView) mInflate.findViewById(R.id.tv_edit);
        mEditText = (EditText) mInflate.findViewById(R.id.et_edit);
        mImageView = (ImageView) mInflate.findViewById(R.id.iv_edit);

        mTextView.setText(mString);
        mTextView.setTextSize(textSize);
        mEditText.setTextSize(textSize);
        mImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                mEditText.setText("");
            }
        });
        //  監聽EditText的變化
        mEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                String s = editable.toString();
                if (s.length() > ) {
                    mImageView.setVisibility(VISIBLE);
                } else {
                    mImageView.setVisibility(INVISIBLE);
                }
            }
        });

    }
}
           

在布局檔案中聲明自定義View

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:orientation="vertical">

    <com.example.smily.customview02.MyEdtiText
        android:id="@+id/met_username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="10dp"
        android:background="#EFEFEF"
        app:textSize="16sp"
        app:left_text="使用者名:" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#fff" />

    <com.example.smily.customview02.MyEdtiText
        android:id="@+id/met_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        app:left_text="密 碼:"
        app:textSize="16sp"
        android:background="#EFEFEF"/>
</LinearLayout>
           

xmlns:custom=”http://schemas.android.com/apk/res/com.example.customview01”是我們的命名空間,後面的包路徑指的是項目的package 。

可以通過java代碼設定屬性

package com.example.smily.customview02;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {
    MyEdtiText mMyEditText;
    EditText mEdittext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMyEditText= (MyEdtiText) findViewById(R.id.met_password);
        mMyEditText.setLeftText("密 碼:");
        mMyEditText.setTextSize();
    }
}