具有自定义属性的自定义控件

本文介绍了如何在Android中创建一个自定义输入视图InputView,包括在values文件夹下定义自定义属性,如input_icon、input_hint和is_password,创建布局文件,设置输入框样式,以及在类中解析并应用这些属性。同时展示了如何在其他布局文件中使用该自定义组件,提供了完整代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义的属性

在values文件夹下新建一个attrs.xml文件,在其中定义一个新的样式,在样式下的子标签中放入一些自己所需的属性。
format表示能接受哪些内容, reference是指资源文件

<?xml version="1.0" encoding="utf-8"?>
<!--自定义的属性-->
<resources>
<!--    声明一个需要的样式-->
<!--    一个样式对应着一个控件-->
    <!--一个叫InputView的样式,该样式还具备一些属性    -->
    <declare-styleable name="InputView">
        <!--   输入框前面的小图标     -->
        <attr name="input_icon" format="reference"/>
        <!--输入框的提示内容        -->
        <attr name="input_hint" format="string"></attr>
<!--        输入框的内容是否以密文进行展示-->
        <attr name="is_password" format="boolean"></attr>
    </declare-styleable>
</resources>

新建一个布局文件

写入自己所需要的一些布局。
在这里插入图片描述
一些数据都存放在dimen的xml文件中,方便统一更改。

<?xml version="1.0" encoding="utf-8"?>
<!--用来存储各种尺寸数据-->
<!--一个dimen标签对应于一个数据,如果标签中还有子标签,子标签是表明性质之类的东西-->
<resources>
    <dimen name="marginSize">16dp</dimen>
    <dimen name="navBarHeight">56dp</dimen>
    <dimen name="navBarTitleSize">22sp</dimen>
    <dimen name="titleSize">18sp</dimen>
    <dimen name="inputViewHeight">44dp</dimen>
</resources>
<?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="@dimen/inputViewHeight"
    android:orientation="horizontal"
    android:layout_gravity="center_vertical"
    android:paddingRight="@dimen/marginSize"
    android:paddingLeft="@dimen/marginSize">

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/phone"/>
   <EditText
       android:id="@+id/et_input"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:background="@null"
       android:paddingLeft="@dimen/marginSize"
       android:paddingRight="@dimen/marginSize"
       android:hint="用户名"
       android:textSize="@dimen/titleSize"/>


</LinearLayout>

新建一个类

1.该类必须继承自某一基础布局,并且重写构造器。
在这里插入图片描述

2.在每个构造器中都要执行init()。
3.initi()函数有三个功能:1.获取自定义属性,2.加载之前布局 3.给布局中的控件绑定属性4.将加载的布局加入到该类的子View中

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

private View mView;
private EditText mEtInput;
private ImageView mIvIcon;
//   使用inputView布局时,可以通过 AttributeSet 来获取我们所传入的属性。
    private void init(Context context, AttributeSet attrs){
        if (attrs == null) return;
        //获取自定义属性 R.styleable.InputView表明属性来源
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.InputView);
//        getxxxxx是由format决定的。
        inputIcon = typedArray.getResourceId(R.styleable.InputView_input_icon,R.mipmap.logo);
        inputHint = typedArray.getString(R.styleable.InputView_input_hint);
        isPassword = typedArray.getBoolean(R.styleable.InputView_is_password,false);
        //        使用完后,要记得回收
        typedArray.recycle();

//        绑定布局
       mView = LayoutInflater.from(context).inflate(R.layout.input_view,this, false);
       mEtInput = mView.findViewById(R.id.et_input);
       mIvIcon = mView.findViewById(R.id.iv_icon);

//       布局关联属性
        mIvIcon.setImageResource(inputIcon);
        mEtInput.setHint(inputHint);
        //设置是否密文展示  是 InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD 来表示密文
//        否 接收手机号的输入 InputType.TYPE_CLASS_PHONE
        mEtInput.setInputType(isPassword ? InputType.TYPE_CLASS_TEXT | InputType.TYPE_NUMBER_VARIATION_PASSWORD
                : InputType.TYPE_CLASS_PHONE);
//       将mView添加到InPutView--将inputView 的布局 与mView绑定在一起了
        addView(mView);
    }

4.其他一些需求的功能方法。

/**
 * 返回输入内容
 * @return
 */
public String getInputStr(){
    return mEtInput.getText().toString().trim();
}

在其他布局文件中使用该控件

自己定义的属性前缀是app.

<com.example.musicclouddemo.views.InputView
    android:layout_width="match_parent"
    android:layout_height="@dimen/inputViewHeight"
    android:layout_marginTop="@dimen/marginSize"
    app:input_icon="@mipmap/phone"
    app:input_hint="手机号"
    app:is_password="false"/>

完整的inputView代码

package com.example.musicclouddemo.views;

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.musicclouddemo.R;

/**需要3个可配置的属性
 * 1.input_icon:输入框前面的图标
 * 2.input_hint : 输入框的提示内容
 * 3. is_passWord :输入框的内容是否以密文进行展示。
 * Ctreate by barry on 2020/10/7.
 */
public class InputView extends FrameLayout {
    private int inputIcon;//null
    private String inputHint;
    private boolean isPassword;

    private View mView;
    private EditText mEtInput;
    private ImageView mIvIcon;
    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);
    }
//   使用inputView布局时,可以通过 AttributeSet 来获取我们所传入的属性。
    private void init(Context context, AttributeSet attrs){
        if (attrs == null) return;
        //获取自定义属性 R.styleable.InputView表明属性来源
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.InputView);
//        getxxxxx是由format决定的。
        inputIcon = typedArray.getResourceId(R.styleable.InputView_input_icon,R.mipmap.logo);
        inputHint = typedArray.getString(R.styleable.InputView_input_hint);
        isPassword = typedArray.getBoolean(R.styleable.InputView_is_password,false);
        //        使用完后,要记得回收
        typedArray.recycle();

//        绑定布局
       mView = LayoutInflater.from(context).inflate(R.layout.input_view,this, false);
       mEtInput = mView.findViewById(R.id.et_input);
       mIvIcon = mView.findViewById(R.id.iv_icon);

//       布局关联属性
        mIvIcon.setImageResource(inputIcon);
        mEtInput.setHint(inputHint);
        //设置是否密文展示  是 InputType.TYPE_CLASS_TEXT | InputType.TYPE_NUMBER_VARIATION_PASSWORD 来表示密文
//        否 接收手机号的输入 InputType.TYPE_CLASS_PHONE
        mEtInput.setInputType(isPassword ? InputType.TYPE_CLASS_TEXT | InputType.TYPE_NUMBER_VARIATION_PASSWORD
                : InputType.TYPE_CLASS_PHONE);
//       将mView添加到InPutView--将inputView 的布局 与mView绑定在一起了
        addView(mView);
    }

    /**
     * 返回输入内容
     * @return
     */
    public String getInputStr(){
        return mEtInput.getText().toString().trim();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值