记一次Android完整项目(3) 自定义属性

177 阅读3分钟

基本输入框的封装

我们知道,系统默认提供的输入框不仅简单还不是很美观,而且,我们可能会在一个应用中不同的Activity中使用,为了不增加代码的复杂性,我们将其进行封装,使用时只需要在对应的xml文件里调用即可!

步骤
1.在 app-java-项目文件夹 下创建一个Views文件夹,并在里面创建所需要的类文件

如下:创建一个输入框文件

/**
 * @author iwenLjr
 * Create to 2020/2/20 2:25
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.example.musicdemo.R;

/**
 * 1.input_icon:输入框前面的图标
 * 2.input_hint:输入框文字
 */
public class InputView extends FrameLayout {

    private int inputIcon;
    private String inputHint;
    private boolean isPassword;

    private View mView;
    private ImageView mIvIcon;
    private EditText mEtInput;

    public InputView(@NonNull Context context) {
        super(context);
        init(context,null);
    }

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

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

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public InputView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    private void init(Context context, AttributeSet attrs){
        if (attrs == null) return;
        // 获取自定义属性
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.inputView);
        inputIcon = typedArray.getResourceId(R.styleable.inputView_input_icon, R.mipmap.phone);
        inputHint = typedArray.getString(R.styleable.inputView_input_hint);
        isPassword = typedArray.getBoolean(R.styleable.inputView_is_password,false);
        typedArray.recycle();

        // 绑定Layout布局
        mView = LayoutInflater.from(context).inflate(R.layout.input_view,this,false);
        mIvIcon = mView.findViewById(R.id.iv_icon);
        mEtInput = mView.findViewById(R.id.ed_input);
        // 将布局和属性绑定
        mIvIcon.setImageResource(inputIcon);
        mEtInput.setHint(inputHint);
        mEtInput.setInputType(isPassword ? InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD : InputType.TYPE_CLASS_PHONE);


        addView(mView);
    }

    /**
     * 获取输入内容
     * @return 返回输入内容
     */
    public String getInputStr(){
        return mEtInput.getText().toString().trim();
    }
}
2.在 res-layout 下创建一个对应的xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="@dimen/inputViewHeight"
    android:paddingLeft="@dimen/marginSize"
    android:paddingRight="@dimen/marginSize"
    android:gravity="center_vertical">

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/phone"/>

    <EditText
        android:id="@+id/ed_input"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@null"
        android:hint="用户名"
        android:paddingRight="@dimen/marginSize"
        android:paddingLeft="@dimen/marginSize"
        android:textSize="@dimen/titleSize"/>

</LinearLayout>
3.在 values 下创建 attrs.xml 用来保存我们自定义的属性
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!--声明样式-->
    <declare-styleable name="inputView">
        <!--输入框前面的图标-->
        <attr name="input_icon" format="reference"></attr>
        <!--输入框的提示-->
        <attr name="input_hint" format="string"></attr>
        <!--输入框是否以密文展示-->
        <attr name="is_password" format="boolean"></attr>

    </declare-styleable>
</resources>
4.初始化封装自定义属性
private void init(Context context, AttributeSet attrs){
        if (attrs == null) return;
        // 获取自定义属性
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.inputView);
        inputIcon = typedArray.getResourceId(R.styleable.inputView_input_icon, R.mipmap.phone);
        inputHint = typedArray.getString(R.styleable.inputView_input_hint);
        isPassword = typedArray.getBoolean(R.styleable.inputView_is_password,false);
        typedArray.recycle();

        // 绑定Layout布局
        mView = LayoutInflater.from(context).inflate(R.layout.input_view,this,false);
        mIvIcon = mView.findViewById(R.id.iv_icon);
        mEtInput = mView.findViewById(R.id.ed_input);
        // 将布局和属性绑定
        mIvIcon.setImageResource(inputIcon);
        mEtInput.setHint(inputHint);
        mEtInput.setInputType(isPassword ? InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD : InputType.TYPE_CLASS_PHONE);
        addView(mView);
    }
5.使用:在需要使用的xml文件中直接使用第一步创建的类名即可,使用自定义属性时,需要以 app:xxxx的形式
<com.example.musicdemo.views.InputView
        android:id="@+id/input_phone"
        android:layout_width="match_parent"
        android:layout_height="@dimen/inputViewHeight"
        android:layout_marginTop="@dimen/marginSize"
        app:input_hint="手机号"
        app:input_icon="@mipmap/phone"
        app:is_password="false">
</com.example.musicdemo.views.InputView>

基本按钮的封装

步骤
1.直接在 values-styles里面添加
    <!--按钮-->
    <style name="commitBtn">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">@dimen/btnHeight</item>
        <item name="android:textColor">@android:color/white</item>
        <item name="android:textSize">@dimen/titleSize</item>
        <item name="android:layout_marginLeft">@dimen/marginSize</item>
        <item name="android:layout_marginRight">@dimen/marginSize</item>
        <item name="android:gravity">center</item>
        <item name="android:background">@drawable/btn_commit_selector</item>
    </style>
2.使用:在需要使用的xml文件中直接使用第一步创建的style=""即可
<Button
        style="@style/commitBtn"
        android:layout_marginTop="@dimen/marginSize"
        android:onClick="onCommitClick"
        android:text="登   录" />