在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"/>