例如实现上边这种编辑框,左边带标题,右边可以输入。 获取到焦点的线加深。离开焦点的时候,检测输入信息是否合法。不合法给出提示信息。
实现思路:
1)自定义编辑框布局。布局里包含一个完整的这种结构的布局文件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"
android:id="@+id/line_top"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
>
<TextView
android:id="@+id/text"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:textColor="@color/line_color_title"
android:textSize="14sp"
android:singleLine="true"
android:ellipsize="end"
/>
<EditText
android:id="@+id/edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/text"
android:background="@drawable/edit_border_server_n"
android:hint=""
android:textColor="@color/line_color_edit"
android:singleLine="true"
android:textSize="14sp"
/>
<!-- 方便点击小按钮 -->
</RelativeLayout>
<View
android:id="@+id/line"
android:layout_width="fill_parent"
android:layout_height="2dp"
/>
<!-- 错误提示 -->
<TextView
android:id="@+id/error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="3dp"
android:paddingBottom="3dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:background="@color/line_input_error_bg"
android:textColor="@color/line_input_error_tx"
android:textSize="12sp"
android:visibility="gone"
/>
</LinearLayout>
2)自定义编辑框LineEdit,
a)加载该布局,并且可以设置左边标题框的大小及内容。 b)自定义监听事件ICall,当编辑框变化的触发。
package com.lyg.edit.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.lyg.edit.R;
/**
* @author luyg
*
*/
public class LineEdit extends LinearLayout {
private LinearLayout rootView ;
/** 标题 */
private TextView textView;
/** 编辑框 */
private EditText editText;
/** 线 */
private View lineView;
/** 错误提示框 */
private TextView error;
/** 失去焦点的线颜色 */
private int normalColor=R.color.line_input_nomal;
/** 得到焦点线的颜色 */
private int selectColor=R.color.line_input_select;
/**回调*/
private IEditCall iCall;
/**处理替代密码获取到焦点时候,直接清空的回调*/
private IFouceCall iFouceCall ;
/**编辑框的内容是否合法*/
private boolean isLegal =false;
public interface IEditCall {
/**失去焦点或者输入完毕*/
void cheack(String text);
}
/**获取到焦点的时候触发*/
public interface IFouceCall{
void fouce(String text);
}
public LineEdit(Context context) {
super(context);
init(context, null);
}
public LineEdit(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
@SuppressLint("NewApi")
public LineEdit(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
public void init(Context context, AttributeSet attrs) {
// 留意,父组件是this,不是空
View allView = inflate(context, R.layout.edit_layout, this);
rootView = (LinearLayout)allView.findViewById(R.id.line_top);
lineView = (View) allView.findViewById(R.id.line);
editText = (EditText) allView.findViewById(R.id.edit);
textView = (TextView) allView.findViewById(R.id.text);
error = (TextView) allView.findViewById(R.id.error);
initAttribute(attrs);
setLister();
}
/**
* @param attrs : 配置属性
* 解析属性
*/
private void initAttribute(AttributeSet attrs) {
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.LineEdit);
String text = a.getString(R.styleable.LineEdit_nameText);
int size = a.getDimensionPixelSize(R.styleable.LineEdit_nameSize, 0);
if (size > 0) {
// 设置组件的大小
ViewGroup.LayoutParams layoutParams = textView.getLayoutParams();
layoutParams.width = size;
textView.setLayoutParams(layoutParams);
}
if (!TextUtils.isEmpty(text)) {
textView.setText(text);
}
}
boolean init = editText.isFocused();
setLineBg(init);
}
/**
* 设置监听
*/
public void setLister(){
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
setLineBg(hasFocus);
if (hasFocus) {
//获取焦点,影藏错误信息
error.setVisibility(View.GONE);
//得到焦点的回调
if (iFouceCall!=null) {
iFouceCall.fouce(getEditTextInfo());
}
}else {
//失去焦点时候在校验
if (iCall!=null) {
iCall.cheack(getEditTextInfo());
}
}
}
});
// 点击到这一行任何位置,编辑框都要设置焦点
rootView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View paramView) {
setLineBg(true);
editText.setFocusable(true);
editText.setFocusableInTouchMode(true);
editText.requestFocus();
editText.findFocus();
error.setVisibility(View.GONE);
}
});
editText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence paramCharSequence,
int paramInt1, int paramInt2, int paramInt3) {
}
@Override
public void beforeTextChanged(CharSequence paramCharSequence,
int paramInt1, int paramInt2, int paramInt3) {
}
@Override
public void afterTextChanged(Editable paramEditable) {
if (iCall!=null) {
iCall.cheack(paramEditable.toString());
}
}
});
}
/**
* 设置线的颜色
*/
public void setLineBg(boolean focus) {
if (focus) {
lineView.setBackgroundColor(getResources().getColor(selectColor));
} else {
lineView.setBackgroundColor(getResources().getColor(normalColor));
}
ViewGroup.LayoutParams lp = lineView.getLayoutParams();
lp.height = focus ? 3 : 1;
lineView.setLayoutParams(lp);
}
public View getRootView(){
return rootView ;
}
public TextView getTextView() {
return textView;
}
public void setTextView(TextView textView) {
this.textView = textView;
}
public EditText getEditText() {
return editText;
}
public void setEditText(EditText editText) {
this.editText = editText;
}
public IEditCall getiCall() {
return iCall;
}
public void setiCall(IEditCall iCall) {
this.iCall = iCall;
}
public void showErrMsg(String msg) {
isLegal = false ;
error.setVisibility(View.VISIBLE);
error.setText(msg);
}
public void setLegal(){
error.setVisibility(View.GONE);
isLegal = true ;
}
/**
* @param len : 输入框输入数据长度
*/
public void limitInput(int len){
editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(len)});
}
public boolean isLegal(){
return isLegal;
}
public boolean isFouce(){
return editText.isFocused();
}
/**
* @return 返回编辑框的信息
*/
public String getEditTextInfo(){
if (editText==null) {
return null;
}
return editText.getEditableText().toString();
}
/**
* 设置线的颜色
* @param normal : 正常的颜色值
* @param select : 选中的颜色值
*/
public void setLineColorId(int normal , int select){
if (normal>0) {
normalColor = normal;
}
if (select>0) {
selectColor = select ;
}
setLineBg(editText.isFocused());
}
public void setIFouceCall(IFouceCall iFouceCall) {
this.iFouceCall = iFouceCall;
}
public TextView getErrorText() {
return error;
}
/**
* 设置错误提示背景为默认色
*/
public void setErrorBgNormal(){
getErrorText().setBackgroundColor(getResources().getColor(R.color.line_input_error_bg));
}
/**
* 设置错误提示的背景色
* @param colorId :颜色的id值
*/
public void setErrorBg(int colorId){
getErrorText().setBackgroundColor(getResources().getColor(colorId));
}
}
3) 在main.xml布局文件里引入自定义的编辑框
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:lineEdit="http://schemas.android.com/apk/res/com.lyg.edit"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/general_body_bg"
android:orientation="vertical"
>
<com.lyg.edit.view.LineEdit
android:id="@+id/line_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp"
lineEdit:nameText="用户名"
lineEdit:nameSize="80dp"
/>
<com.lyg.edit.view.LineEdit
android:id="@+id/line_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="15dp"
lineEdit:nameText="密码"
lineEdit:nameSize="80dp"
/>
</LinearLayout>
4)MainActivity里展示及校验
package com.lyg.edit;
import com.lyg.edit.view.LineEdit;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
public class MainActivity extends Activity {
private LineEdit nameEdit;
private LineEdit passwordEdit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initUi();
}
public void initUi(){
nameEdit = (LineEdit)findViewById(R.id.line_name);
passwordEdit = (LineEdit)findViewById(R.id.line_password);
nameEdit.setiCall(new LineEdit.IEditCall() {
@Override
public void cheack(String text) {
if (TextUtils.isEmpty(text)) {
nameEdit.showErrMsg("用户名不能为空");
}
}
});
passwordEdit.setiCall(new LineEdit.IEditCall() {
@Override
public void cheack(String text) {
if (TextUtils.isEmpty(text)) {
passwordEdit.showErrMsg("密码不能为空");
}else if (text.length()<6) {
passwordEdit.showErrMsg("密码不能小于六位");
}
}
});
}
}
5)配置文件
a) attrs.xml 这里边是自定义属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="LineEdit">
<!-- 标题的大小 -->
<attr name="nameSize" format="dimension" />
<!-- 标题的内容 -->
<attr name="nameText" format = "reference|string" />
<!-- 编辑框选中的颜色 -->
<attr name="normalColor" format="color" />
<!-- 编辑框没选中的颜色 -->
<attr name="selcetColor" format="color" />
</declare-styleable>
</resources>
b) 颜色色值 color.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="white">#FFFFFF</color>
<color name="line_input_select">#00c6ff</color>
<color name="line_input_nomal">#d3d7dc</color>
<color name="line_color_title">#868e95</color>
<color name="line_color_edit">#36424e</color>
<color name="line_input_error_bg">#eaedf1</color>
<color name="line_input_error_tx">#f13838</color>
<color name="gray">#f0f0f0</color>
<color name="edit_background">#f1edea</color>
</resources>