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

    科技2025-07-08  7

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

    自定义的属性新建一个布局文件新建一个类在其他布局文件中使用该控件完整的inputView代码

    自定义的属性

    在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(); } }
    Processed: 0.012, SQL: 8