Android 實現帶頭部文字輸入框的自定義控件

前言

在app的輸入框中,需要應用到很多帶有前綴說明的輸入框,運用原有的輸入框和文本控件,一個帶頭部的輸入框就會增加三個控件在layout文件中。當佈局文件輸入框較少的情況下,這樣對後期維護影響不大,但在多個帶頭部的輸入框下,佈局文件代碼量會很大,影響閱讀以及後期維護。而封裝過後的控件,在使用中僅僅需要幾行代碼可實現幾十行的效果。

簡介

  • 帶頭部文字的輸入框
  • 可在xml定義頭部文字樣式
  • 可在xml定義輸入框樣式
  • 可在xml定義提示文字樣式
  • 可在xml定義頭部和輸入框的間距和邊距

效果圖

使用方法

<com.momin.common.widget.EditInputView
    android:layout_width="match_parent"
    android:layout_height="50dp"
    app:inputMarginStart="10dp"
    app:headerText="姓名"
    app:hint="請輸入聯系人姓名"
    app:inputType="text"
    app:maxLength="30"/>

源碼在這

有幫助請點個贊

attrs.xml 屬性文檔

<!--  公共屬性  -->
<!--  前置文字內容  -->
<attr name="headerText" format="string"/>
<!--  前置文字大小  -->
<attr name="headerTextSize" format="dimension"/>
<!--  前置文字大小  -->
<attr name="headerTextStyle">
    <flag name="normal" value="0" />
    <flag name="bold" value="1" />
    <flag name="italic" value="2" />
</attr>
<!--  前置文字顏色  -->
<attr name="headerTextColor" format="reference|color"/>
<!--  前置文字左邊間距  -->
<attr name="headerPaddingStart" format="dimension"/>
<!--  前置文字右邊間距  -->
<attr name="headerPaddingEnd" format="dimension"/>
<!--  前置文字頂部間距  -->
<attr name="headerPaddingTop" format="dimension"/>
<!--  前置文字底部間距  -->
<attr name="headerPaddingBottom" format="dimension"/>
<!--  公共屬性  -->

<!--  帶前置文字的輸入框  -->
<declare-styleable name="EditInputView">
    <!--  文字內容  -->
    <attr name="text" format="string"/>
    <!--  文字大小  -->
    <attr name="textSize" format="dimension"/>
    <!--  文字顏色  -->
    <attr name="textColor" format="reference|color"/>
    <!--  最大輸入字符數  -->
    <attr name="maxLength" format="integer"/>
    <!--  輸入限制  -->
    <attr name="android:enabled"/>
    <!--  輸入類型  -->
    <attr name="android:inputType"/>
    <!--  輸入開始邊距  -->
    <attr name="inputMarginStart" format="dimension"/>
    <!--  輸入結束邊距  -->
    <attr name="inputMarginEnd" format="dimension"/>
    <!--  輸入頂部邊距  -->
    <attr name="inputMarginTop" format="dimension"/>
    <!--  輸入底部邊距  -->
    <attr name="inputMarginBottom" format="dimension"/>
    <!--  輸入開始間距  -->
    <attr name="inputPaddingStart" format="dimension"/>
    <!--  輸入結束間距  -->
    <attr name="inputPaddingEnd" format="dimension"/>
    <!--  輸入頂部間距  -->
    <attr name="inputPaddingTop" format="dimension"/>
    <!--  輸入底部間距  -->
    <attr name="inputPaddingBottom" format="dimension"/>
    <!--  輸入底部間距  -->
    <attr name="android:gravity"/>
    <!--  提示文字  -->
    <attr name="hint" format="string"/>
    <!--  提示文字顏色  -->
    <attr name="hintColor" format="reference|color"/>
    <!--  前置文字內容  -->
    <attr name="headerText"/>
    <!--  前置文字大小  -->
    <attr name="headerTextSize"/>
    <!--  前置文字大小  -->
    <attr name="headerTextStyle"/>
    <!--  前置文字顏色  -->
    <attr name="headerTextColor"/>
    <!--  前置文字左邊間距  -->
    <attr name="headerPaddingStart"/>
    <!--  前置文字右邊間距  -->
    <attr name="headerPaddingEnd"/>
    <!--  前置文字頂部間距  -->
    <attr name="headerPaddingTop"/>
    <!--  前置文字底部間距  -->
    <attr name="headerPaddingBottom"/>
</declare-styleable>

common_edit_input_view.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="match_parent">
    <!--  頭部文字  -->
    <TextView
        android:id="@+id/tv_edit_head"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="start|center_vertical"/>
    <!--  輸入框  -->
    <EditText
        android:id="@+id/et_edit_input"
        android:layout_toEndOf="@id/tv_edit_head"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:singleLine="true"
        android:background="@null"
        android:textColor="@color/c_2B303C"
        android:gravity="end|center_vertical"/>
</RelativeLayout>

EditInputView.java 控件類

package com.momin.common.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.text.InputFilter;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.momin.common.R;

/**
 * <p>Title: EditInputView</p>
 * <p>Description: 帶頭部輸入框 </p>
 * <p>Copyright: </p>
 * <p>Company: </p>
 *
 * @author Momin
 * @version 1.0
 * @date 2021/3/10 18:00
 */

public class EditInputView extends RelativeLayout {

    TextView tvHead;
    EditText etInput;

    public EditInputView(Context context) {
        super(context);
        init(context, null);
    }

    public EditInputView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    /**
     * 初始化
     *
     * @param context   上下文
     * @param attrs     資源
     */
    private void init(Context context, AttributeSet attrs) {
        // 初始化對象
        initView(context);
        // 獲取資源對象
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.EditInputView);
        // 初始化輸入框
        initEdit(context, typedArray);

        // 初始化頭部文字
        CharSequence headText = typedArray.getText(R.styleable.EditInputView_headerText);
        if (TextUtils.isEmpty(headText)) {
            // 頭部為空時
            tvHead.setVisibility(GONE);
        } else {
            // 頭部不為空時
            tvHead.setVisibility(VISIBLE);
            initHeaderText(context, typedArray, headText);
        }

        // 回收資源對象
        typedArray.recycle();
    }

    /**
     * 初始化視圖
     *
     * @param context 上下文
     */
    private void initView(Context context) {
        LayoutInflater.from(context).inflate(R.layout.common_edit_input_view, this);
        tvHead = findViewById(R.id.tv_edit_head);
        etInput = findViewById(R.id.et_edit_input);
    }

    /**
     * 初始化輸入框
     *
     * @param context       上下文
     * @param typedArray    資源對象
     */
    private void initEdit(Context context, TypedArray typedArray) {
        // 初始內容
        CharSequence editText = typedArray.getText(R.styleable.EditInputView_text);
        if (!TextUtils.isEmpty(editText)) {
            etInput.setText(editText);
        }
        // 字體大小
        setViewTextSize(etInput, R.styleable.EditInputView_textSize, typedArray);
        // 字體顏色
        setViewTextColor(context, etInput, R.styleable.EditInputView_textColor, typedArray);
        // 設置間距
        setEditPadding(typedArray);
        // 設置邊距
        setEditMargin(typedArray);
        // 輸入類型限制
        setLimitInputType(typedArray);
        // 輸入長度限制
        setLimitInputLen(typedArray);
        // 輸入限制:可輸入性
        setInputBoolean(typedArray);
        // 輸入字體排列位置
        setInputGravity(typedArray);

        initEditHint(context, typedArray);
    }

    /**
     * 設置字體大小
     *
     * @param view          被設置對象
     * @param attrId        屬性Id
     * @param typedArray    資源對象
     */
    private void setViewTextSize(TextView view, int attrId, TypedArray typedArray) {
        float size = typedArray.getDimension(attrId, 14 * view.getPaint().density);
        view.getPaint().setTextSize(size);
    }

    /**
     * 設置字體風格
     *
     * @param view          被設置對象
     * @param attrId        屬性Id
     * @param typedArray    資源對象
     */
    private void setViewTextStyle(TextView view, int attrId, TypedArray typedArray) {
        int style = typedArray.getInt(attrId, Typeface.NORMAL);
        view.setTypeface(Typeface.defaultFromStyle(style));
    }

    /**
     * 設置字體顏色
     *
     * @param context       上下文
     * @param view          被設置對象
     * @param attrId        屬性Id
     * @param typedArray    資源對象
     */
    private void setViewTextColor(Context context, TextView view, int attrId, TypedArray typedArray) {
        int color = typedArray.getColor(attrId,
                ContextCompat.getColor(context, R.color.c_2B303C));
        view.setTextColor(color);
    }

    /**
     * 設置輸入框間距
     *
     * @param typedArray 資源對象
     */
    private void setEditPadding(TypedArray typedArray) {
        // 開始間距
        int paddingStart = (int)typedArray.getDimension(R.styleable.EditInputView_inputPaddingStart, 0);
        // 結束間距
        int paddingEnd = (int)typedArray.getDimension(R.styleable.EditInputView_inputPaddingEnd, 0);
        // 頂部間距
        int paddingTop = (int)typedArray.getDimension(R.styleable.EditInputView_inputPaddingTop, 0);
        // 底部間距
        int paddingBottom = (int)typedArray.getDimension(R.styleable.EditInputView_inputPaddingBottom, 0);
        etInput.setPadding(paddingStart, paddingTop, paddingEnd, paddingBottom);
    }

    /**
     * 設置輸入框邊距
     *
     * @param typedArray 資源對象
     */
    private void setEditMargin(TypedArray typedArray) {
        // 開始邊距
        int marginStart = (int)typedArray.getDimension(R.styleable.EditInputView_inputMarginStart, 0);
        // 結束邊距
        int marginEnd = (int)typedArray.getDimension(R.styleable.EditInputView_inputMarginEnd, 0);
        // 頂部邊距
        int marginTop = (int)typedArray.getDimension(R.styleable.EditInputView_inputMarginTop, 0);
        // 底部邊距
        int marginBottom = (int)typedArray.getDimension(R.styleable.EditInputView_inputMarginBottom, 0);
        LayoutParams layoutParams = (LayoutParams)etInput.getLayoutParams();
        layoutParams.setMargins(marginStart, marginTop, marginEnd, marginBottom);
        etInput.setLayoutParams(layoutParams);
    }

    /**
     * 設置輸入類型限制
     *
     * @param typedArray    資源對象
     */
    private void setLimitInputType(TypedArray typedArray) {
        etInput.setInputType(typedArray.getInt(R.styleable.EditInputView_android_inputType, EditorInfo.TYPE_NULL));
    }

    /**
     * 設置輸入長度限制
     *
     * @param typedArray    資源對象
     */
    private void setLimitInputLen(TypedArray typedArray) {
        int len = typedArray.getInteger(R.styleable.EditInputView_maxLength, 0);
        if (len > 0) {
            setMaxLength(len);
        }
    }

    /**
     * 輸入限制:可輸入性
     *
     * @param typedArray    資源對象
     */
    private void setInputBoolean(TypedArray typedArray) {
        etInput.setEnabled(typedArray.getBoolean(R.styleable.EditInputView_android_enabled, true));
    }

    /**
     * 輸入字體排列位置
     *
     * @param typedArray    資源對象
     */
    private void setInputGravity(TypedArray typedArray) {
        etInput.setGravity(typedArray.getInt(R.styleable.EditInputView_android_gravity,
                Gravity.END|Gravity.CENTER_VERTICAL));
    }

    /**
     * 初始化輸入框提示文字
     *
     * @param context       上上下文
     * @param typedArray    資源對象
     */
    private void initEditHint(Context context, TypedArray typedArray) {
        CharSequence hintText = typedArray.getText(R.styleable.EditInputView_hint);
        if (!TextUtils.isEmpty(hintText)) {
            // 提示文字不為空
            // 提示內容
            etInput.setHint(hintText);
            // 提示文字顏色
            int color = typedArray.getColor(R.styleable.EditInputView_hintColor,
                    ContextCompat.getColor(context, R.color.c_D2D0DC));
            etInput.setHintTextColor(color);
        }
    }

    /**
     * 初始化頭部文字
     *
     * @param context       上下文
     * @param typedArray    資源對象
     * @param text          頭部文字
     */
    private void initHeaderText(Context context, TypedArray typedArray, CharSequence text) {
        // 頭部字體風格
        setViewTextStyle(tvHead, R.styleable.EditInputView_headerTextStyle, typedArray);
        // 頭部字體顏色
        setViewTextColor(context, tvHead, R.styleable.EditInputView_headerTextColor, typedArray);
        // 頭部字體大小
        setViewTextSize(tvHead, R.styleable.EditInputView_headerTextSize, typedArray);
        // 頭部開始間距
        int paddingStart = (int)typedArray.getDimension(R.styleable.EditInputView_headerPaddingStart, 0);
        // 頭部結束間距
        int paddingEnd = (int)typedArray.getDimension(R.styleable.EditInputView_headerPaddingEnd, 0);
        // 頭部頂部間距
        int paddingTop = (int)typedArray.getDimension(R.styleable.EditInputView_headerPaddingTop, 0);
        // 頭部底部間距
        int paddingBottom = (int)typedArray.getDimension(R.styleable.EditInputView_headerPaddingBottom, 0);

        tvHead.setText(text);
        tvHead.setPadding(paddingStart, paddingTop, paddingEnd, paddingBottom);
    }

    /**
     * 設置頭部內容
     *
     * @param text 被設置內容
     */
    public void setHeadText(CharSequence text) {
        if (tvHead != null) {
            tvHead.setText(text);
        }
    }

    /**
     * 獲取內容
     *
     * @return 內容
     */
    public CharSequence getText() {
        if (etInput == null) {
            return null;
        } else {
            return etInput.getText();
        }
    }

    /**
     * 設置內容
     *
     * @param text 被設置內容
     */
    public void setText(CharSequence text) {
        if (etInput != null) {
            etInput.setText(text);
        }
    }

    /**
     * 設置內容顏色
     *
     * @param colorId 顏色資源Id
     */
    public void setTextColor(@ColorRes int colorId) {
        if (etInput != null) {
            etInput.setTextColor(ContextCompat.getColor(getContext(), colorId));
        }
    }

    /**
     * 設置最大輸入限制
     *
     * @param len   限制值
     */
    public void setMaxLength(int len) {
        etInput.setFilters(new InputFilter[]{new InputFilter.LengthFilter(len)});
    }

    public TextView getHeadTextView() {
        return tvHead;
    }

    public EditText getInputEditView() {
        return etInput;
    }
}

以上就是Android 實現帶頭部文字輸入框的自定義控件的詳細內容,更多關於Android 文字輸入框的自定義控件的資料請關註WalkonNet其它相關文章!

推薦閱讀:

    None Found