在开发中,遇到了由几个组件和布局一块儿组成的控件,如实现密码的输入框,如下图所示:
为了实现这个效果,在页面布局中,就需要在一个布局中添加一个EditText和一个ImageView两个基本组件。这个密码输入框实现的基本功能是密码的输入,当点击后面的图片时,如果密码不可见,则密码将显示出来,如果已经显示出来,则在点击后将密码隐藏。
然而,在一个app中,可能有多个这样的输入框,这样在布局文件中的布局代码就会有较多的代码(用词欠考虑),而且为了实现图片的点击变化等功能在java代码中也会有太多的重复代码。所以,如果可以将这些组件组合成一个控件,并且将重复的功能操作等添加到控件的基本功能中,则可以很简洁的在多个地方实现该控件的布局和功能。复合自定义组件的实现(密码输入框)
1、将密码输入框的布局写好
本人将要实现的密码输入框按照上图的布局写到了一个布局文件中,代码如下:
文件名为:layout_password_edittext.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="match_parent"
android:background="#ececec"
android:gravity="center_vertical">
<EditText
android:id="@+id/editText_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:gravity="center"
android:singleLine="true"
android:inputType="textPassword"/>
<RelativeLayout
android:id="@+id/layout_eye"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center"
>
<ImageView
android:id="@+id/image_eye"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/btn_eye"
/>
</RelativeLayout>
</LinearLayout>
2、为了将EditText和ImageView等的布局可在控件的布局中添加设置,在这里都设置成了warp_content,而EditText和ImageView的布局参数则在Attr中设置,代码如下
文件名为:values/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PasswordEditText">
<attr name="image_width" format="dimension"/>
<attr name="image_height" format="dimension"/>
<attr name="layout_width" format="dimension"/>
<attr name="layout_height" format="dimension"/>
<attr name="hint" format="string"/>
</declare-styleable>
</resources>
其中,如EditText字体的设置等等许多可以在布局文件中添加的属性都可以在这里添加,从而在布局文件中可以设置这些属性。(之所以在自定义属性中添加 layout_width 和 layout_height 是因为本人在代码中没有找到获得 android:layout_width 和 android:layout_height 的方法,所有使用了自定义属性的方法。可以根据自己的情况决定如何使用)
3、自定义控件的实现
代码如下:
package com.example.mydemo.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.uidea.app.heb_aspark.R;
/**
* Created by Administrator on 2015/10/17.
*/
public class PasswordEditText extends LinearLayout implements View.OnTouchListener{
private EditText editText;
private RelativeLayout eyeLayout;
private ImageView imageView;
private boolean showPwd = false;
private String hint = null;
public PasswordEditText(Context context, AttributeSet attrs) {
super(context, attrs);
View.inflate(context, R.layout.layout_password_edittext, this);
editText = (EditText)findViewById(R.id.editText_password);
eyeLayout = (RelativeLayout)findViewById(R.id.layout_eye);
imageView = (ImageView)findViewById(R.id.image_eye);
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.PasswordEditText);
int width = typedArray.getDimensionPixelSize(R.styleable.PasswordEditText_layout_width, 0);
int height = typedArray.getDimensionPixelSize(R.styleable.PasswordEditText_layout_height,0);
editText.setLayoutParams(new LinearLayout.LayoutParams(width-height,height));
eyeLayout.setLayoutParams(new LinearLayout.LayoutParams(height, height));
imageView.setLayoutParams(
new RelativeLayout.LayoutParams(
typedArray.getDimensionPixelSize(R.styleable.PasswordEditText_image_width, 0),
typedArray.getDimensionPixelSize(R.styleable.PasswordEditText_image_height, 0)));
hint = typedArray.getString(R.styleable.PasswordEditText_hint);
editText.setHint(hint);
imageView.setOnTouchListener(this);
}
/**
* 触摸事件等功能没有写,自己添加,如图片的按下的切换和密码显示的功能等
*/
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
}
//...
//许多功能如返回EditText的字符串等功能可根据需求添加自己的功能,此处就不再赘述
4、 使用
如普通的控件使用差不多,在布局文件中的使用如下:
<com.example.mydemo.views.PasswordEditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_width="293.33dp"
app:layout_height="40dp"
app:image_width="25.33dp"
app:image_height="13.63dp"
app:hint="请输入密码!"/>
在代码中如何使用我想应该都会使用,就不在赘述了。
以上纯属个人见解,如有错误,望指出。