第一步:自定义属性(/res/values/attrs.xml)
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <declare-styleable name="delete_edittext">
- <attr name="height" format="reference|dimension" />
- <attr name="paddingleft" format="reference|dimension" />
- <attr name="hint" format="reference|string" />
- <attr name="hint_size" format="reference|dimension" />
- <attr name="hint_color" format="reference|color" />
- <attr name="delete_edittype" format="string" />
- </declare-styleable>
- </resources>
第二步:自定义View(LoginEditText.java)
- public class LoginEditText extends RelativeLayout {
- //取消按钮
- private ImageView cancelIm;
- private EditText searchEt;
- //ed的高度
- private float edHieght;
- //距离左边的距离
- private float edPaddingleft;
- //提示文字
- private String hint;
- private float hintSize;
- private int hintColor;
- //ed的类型
- private String edittype;
- public LoginEditText(Context context) {
- super(context);
- }
- public LoginEditText(Context context, AttributeSet attrs) {
- super(context, attrs);
- initView(context,attrs);
- }
- public EditText getSearchEt() {
- return searchEt;
- }
- private void initView(Context context,AttributeSet attrs) {
- LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- inflater.inflate(R.layout.login_edittext, this); //<span style="color:#ff0000;">这是引用了布局文件</span>
- cancelIm=(ImageView) findViewById(R.id.cancel_im);
- searchEt = (EditText) findViewById(R.id.search_et);
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.delete_edittext);//得到属性数组
- edHieght = a.getDimension(R.styleable.delete_edittext_height, 60f);//得到高度属性值,
- edPaddingleft = a.getDimension(R.styleable.delete_edittext_paddingleft, 10f);//得到padding属性值,
- hint = a.getString(R.styleable.delete_edittext_hint);//得到hint属性值,
- hintSize = a.getDimension(R.styleable.delete_edittext_hint_size,19f);//得到hintsize属性值,
- hintColor = a.getColor(R.styleable.delete_edittext_hint_color,context.getResources().getColor(R.color.c_c));//得到hintcolor属性值,
- edittype = a.getString(R.styleable.delete_edittext_delete_edittype);
- if("pwd".equals(edittype)) {
- searchEt.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
- }
- searchEt.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,(int)edHieght));
- searchEt.setPadding((int)edPaddingleft, 0, 0, 0);
- searchEt.setHint(hint);
- searchEt.setHintTextColor(hintColor);
- searchEt.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- }
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- if(TextUtils.isEmpty(charSequence)) {
- cancelIm.setVisibility(GONE);
- } else {
- cancelIm.setVisibility(VISIBLE);
- }
- }
- @Override
- public void afterTextChanged(Editable editable) {
- }
- });
- cancelIm.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- searchEt.setText("");
- }
- });
- }
- public LoginEditText(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- initView(context,attrs);
- }
- }
第三步:布局文件(/res/layout/login_edittext.xml)
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_below="@+id/head">
- <EditText
- android:id="@+id/search_et"
- android:layout_width="fill_parent"
- android:layout_height="@dimen/s_59dp"
- android:layout_centerVertical="true"
- android:layout_marginLeft="@dimen/s_10dp"
- android:layout_marginRight="@dimen/s_10dp"
- android:layout_marginTop="@dimen/s_9dp"
- android:background="@drawable/category_search_shape" //<span style="color:#ff0000;">这里引用了shape</span>
- android:paddingLeft="@dimen/s_40dp"
- android:paddingRight="@dimen/s_40dp"
- android:singleLine="true"
- android:textColor="@color/login_ed_hintcolor"
- android:textSize="@dimen/s_17dp" />
- <RelativeLayout
- android:id="@+id/cancel_click"
- android:layout_width="@dimen/s_35dp"
- android:layout_height="@dimen/s_36dp"
- android:layout_alignRight="@+id/search_et"
- android:layout_centerVertical="true">
- <ImageView
- android:id="@+id/cancel_im"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:layout_marginRight="@dimen/s_6dp"
- android:src="@drawable/qx"
- android:visibility="gone" />
- </RelativeLayout>
- </RelativeLayout>
第四步:shape文件(/res/drawable/category_search_shape.xml)
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="#00000000" />
- </shape>
第五步:整体布局(activity_main.xml)
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:offcn="http://schemas.android.com/apk/res-auto" //<span style="color:#ff0000;">引用自定义属性</span>
- android:background="@drawable/dt"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <LinearLayout
- android:id="@+id/user_input"
- android:layout_width="fill_parent"
- android:layout_height="@dimen/s_120dp"
- android:background="@drawable/login_shape" //<span style="color:#ff0000;">引用了shape</span>
- android:layout_marginLeft="@dimen/s_15dp"
- android:layout_marginRight="@dimen/s_15dp"
- android:layout_marginTop="@dimen/s_192dp"
- android:orientation="vertical"
- >
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <cn.zanelove.smscaptcha.DeleteEditText //<span style="color:#ff0000;">引用自定义View</span>
- android:id="@+id/username_ed"
- android:layout_width="fill_parent"
- android:layout_height="@dimen/s_59dp"
- offcn:height="@dimen/s_59dp"
- offcn:hint="请输入您的用户名"
- offcn:hint_color="#2cc597"
- offcn:paddingleft="@dimen/s_60dp"
- />
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/yh"
- android:layout_centerVertical="true"
- android:layout_marginLeft="@dimen/s_20dp"
- />
- </RelativeLayout>
- <View android:layout_width="fill_parent"
- android:layout_height="@dimen/s_1dp"
- android:background="#10a679"
- />
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <cn.zanelove.smscaptcha.DeleteEditText
- android:id="@+id/pwd_ed"
- android:layout_width="fill_parent"
- android:layout_height="@dimen/s_59dp"
- offcn:height="@dimen/s_59dp"
- offcn:hint="请输入密码"
- offcn:hint_color="#2cc597"
- offcn:paddingleft="@dimen/s_60dp"
- />
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/mm"
- android:layout_centerVertical="true"
- android:layout_marginLeft="@dimen/s_20dp"
- />
- </RelativeLayout>
- </LinearLayout>
- </LinearLayout>
第六步:
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/login_shape"/>
- <corners android:radius="@dimen/s_5dp"/>
- </shape>
在布局文件中:
- <TextView
- android:id="@+id/login"
- style="@style/login_btn"
- android:text="@string/login"
- />
在上面的代码中不难发现,我们使用了style引用,因此在style_layout.xml中:
- <!-- 登录注册等按钮-->
- <style name="login_btn">
- <item name="android:layout_width">fill_parent</item>
- <item name="android:layout_height">@dimen/s_55dp</item>
- <item name="android:textColor">@color/f</item>
- <item name="android:textSize">@dimen/s_21dp</item>
- <item name="android:layout_marginLeft">@dimen/s_15dp</item>
- <item name="android:layout_marginRight">@dimen/s_15dp</item>
- <item name="android:background">@drawable/loginbtn_selector</item>
- <item name="android:gravity">center</item>
- </style>
仔细看的话,我们还引用了background,因此在/res/drawable/下,创建loginbtn_selector.xml文件:
在loginbtn_selector.xml中:
- <?xml version="1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/login_loginbtn_press_shape" />
- <item android:drawable="@drawable/login_loginbtn_shape"/>
- </selector>
在login_loginbtn_press_shape.xml中:
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <corners android:radius="@dimen/s_3dp"/>
- <solid android:color="@color/login_loginbtn_press"/> //502fc89a
- </shape>
在login_loginbtn_shape.xml中:
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <corners android:radius="@dimen/s_3dp"/>
- <solid android:color="@color/login_loginbtn"/> //#902fc89a
- </shape>
注册UI:
在布局文件中:
- <LinearLayout
- android:id="@+id/user_regedit_input"
- android:layout_width="fill_parent"
- android:layout_height="@dimen/s_181dp"
- android:orientation="vertical"
- android:layout_marginLeft="@dimen/s_15dp"
- android:layout_marginRight="@dimen/s_15dp"
- android:background="@drawable/login_shape"
- android:layout_marginTop="@dimen/s_112dp"
- >
- <com.offcn.android.wangxiao.view.RegeditEdittext
- android:id="@+id/username_ed"
- android:layout_width="fill_parent"
- android:layout_height="@dimen/s_60dp"
- offcn:text="@string/regedit_username_text"
- offcn:hint_rg="@string/regedit_username_hint"
- offcn:hint_color_rg="@color/color_999" //#999999
- <span style="white-space:pre"> </span>/>
- <View android:layout_width="fill_parent"
- android:layout_height="@dimen/s_1dp"
- android:background="@color/login_ed_division"
- />
- <com.offcn.android.wangxiao.view.RegeditEdittext
- android:id="@+id/pwd_ed"
- android:layout_width="fill_parent"
- android:layout_height="@dimen/s_60dp"
- offcn:text="@string/regedit_pwd_text"
- offcn:edittype="pwd"
- offcn:hint_rg="@string/regedit_pwd_hint"
- offcn:hint_color_rg="@color/regedit_hint" //#bbbbbb
- />
- <View android:layout_width="fill_parent"
- android:layout_height="@dimen/s_1dp"
- android:background="@color/login_ed_division"
- />
- <com.offcn.android.wangxiao.view.RegeditEdittext
- android:id="@+id/repwd_ed"
- android:layout_width="fill_parent"
- android:layout_height="@dimen/s_60dp"
- offcn:text="@string/regedit_repwd_text"
- offcn:edittype="pwd"
- offcn:hint_rg="@string/regedit_pwd_hint"
- offcn:hint_color_rg="@color/regedit_hint"
- />
- <View android:layout_width="fill_parent"
- android:layout_height="@dimen/s_1dp"
- android:background="@color/login_ed_division" //#10a679
- />
- </LinearLayout>
此处使用了自定义EditText(RegeditEdittext):
- /**
- * 注册页面edittext
- * edittype传入email检测email,传入其他则是检验长度是否满足6-10位
- */
- public class RegeditEdittext extends RelativeLayout {
- //输入内容是否合法的状态图片
- private ImageView checkIm;
- private EditText edit;
- private String edittype;
- private String inputtype;
- //是否通过校验
- private boolean isCheck;
- //控件左边的文字
- private String text;
- private TextView tv;
- //提示文字
- private String hint;
- private float hintSize;
- private int hintColor;
- public RegeditEdittext(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- initView(context, attrs);
- }
- public RegeditEdittext(Context context) {
- super(context);
- }
- public RegeditEdittext(Context context, AttributeSet attrs) {
- super(context, attrs);
- initView(context, attrs);
- }
- public ImageView getCheckIm() {
- return checkIm;
- }
- public EditText getEdit() {
- return edit;
- }
- public boolean isCheck() {
- return isCheck;
- }
- private void initView(Context context, AttributeSet attrs) {
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- inflater.inflate(R.layout.regedit_edittext, this);
- edit = (EditText) findViewById(R.id.regedit_et);
- checkIm = (ImageView) findViewById(R.id.checkIm);
- tv = (TextView) findViewById(R.id.tv);
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.regedit_edittext);//得到属性数组
- edittype = a.getString(R.styleable.regedit_edittext_edittype);//得到属性值,可以指定默认值
- inputtype = a.getString(R.styleable.regedit_edittext_inputtype);
- hint = a.getString(R.styleable.regedit_edittext_hint_rg);//得到hint属性值,
- hintSize = a.getDimension(R.styleable.regedit_edittext_hint_size_rg,19f);//得到hintsize属性值,
- hintColor = a.getColor(R.styleable.regedit_edittext_hint_color_rg,context.getResources().getColor(R.color.c_c));//得到hintcolor属性值,
- text = a.getString(R.styleable.regedit_edittext_text);
- edit.setHint(hint);
- edit.setHintTextColor(hintColor);
- tv.setText(text);
- if ("pwd".equals(edittype)) {
- edit.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
- }
- //1代表数字 2代表文字
- if ("1".equals(inputtype)) {
- edit.setInputType(InputType.TYPE_CLASS_NUMBER);
- } else if ("2".equals(inputtype)) {
- edit.setInputType(InputType.TYPE_CLASS_TEXT);
- }
- edit.setLongClickable(false);
- edit.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- }
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- if (!TextUtils.isEmpty(charSequence)) {
- checkIm.setVisibility(VISIBLE);
- //如果是邮箱类型的et,则正则检测邮箱
- if ("email".equals(edittype)) {
- if (checkEmail(charSequence.toString())) {
- checkIm.setImageResource(R.drawable.zq);
- isCheck = true;
- } else {
- checkIm.setImageResource(R.drawable.cw);
- isCheck = false;
- }
- //如果是其他类型,则正则检测长度
- } else if ("nocheck".equals(edittype)) {
- checkIm.setVisibility(GONE);
- } else {
- if (checkEditLength(charSequence.toString())) {
- checkIm.setImageResource(R.drawable.zq);
- isCheck = true;
- } else {
- checkIm.setImageResource(R.drawable.cw);
- isCheck = false;
- }
- }
- }
- }
- @Override
- public void afterTextChanged(Editable editable) {
- }
- });
- }
- /**
- * 验证邮箱地址是否正确
- */
- public boolean checkEmail(String email) {
- boolean flag = false;
- String check = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
- Pattern regex = Pattern.compile(check);
- Matcher matcher = regex.matcher(email);
- flag = matcher.matches();
- return flag;
- }
- public boolean checkEditLength(String str) {
- boolean flag = false;
- String check = "([0-9]|[A-Za-z]|[\u4e00-\u9fa5]){6,10}";
- Pattern regex = Pattern.compile(check);
- Matcher matcher = regex.matcher(str);
- flag = matcher.matches();
- return flag;
- }
- }
注册逻辑代码:
- /**
- * 注册
- */
- public class RegeditActivity extends BaseActivity {
- //账号
- @ViewInject(R.id.username_ed)
- private RegeditEdittext username;
- //输入密码ed
- @ViewInject(R.id.pwd_ed)
- private RegeditEdittext pwd;
- //确认密码ed
- @ViewInject(R.id.repwd_ed)
- private RegeditEdittext rePwd;
- //注册
- @ViewInject(R.id.regedit)
- private TextView regedit;
- private String emailStr;
- private String pwdStr;
- private String rePwdStr;
- private Toast toast;
- private InputMethodManager inputMethodManager;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_regedit);
- AppManager.getAppManager().addActivity(this);
- ViewUtils.inject(this);
- toast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
- checkRePwd();
- inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
- }
- /**
- * 检查密码是否与第一次一致
- */
- private void checkRePwd() {
- rePwd.getEdit().addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- }
- @Override
- public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- if (!TextUtils.isEmpty(charSequence) && pwd.getEdit().getText() != null) {
- if (charSequence.toString().equals((pwd.getEdit().getText().toString()))) {
- rePwd.getCheckIm().setImageResource(R.drawable.zq);
- } else {
- rePwd.getCheckIm().setImageResource(R.drawable.cw);
- }
- }
- }
- @Override
- public void afterTextChanged(Editable editable) {
- }
- });
- }
- /**
- * 注册
- * @param v
- */
- @OnClick(R.id.regedit)
- public void regedit(View v) {
- emailStr = username.getEdit().getText().toString().trim();
- pwdStr = pwd.getEdit().getText().toString().trim();
- rePwdStr = rePwd.getEdit().getText().toString().trim();
- if (TextUtils.isEmpty(emailStr)) {
- toast.setText("邮箱不能为空");
- toast.show();
- return;
- }
- if (!username.isCheck()) {
- toast.setText("邮箱格式不正确,请重新输入");
- toast.show();
- return;
- }
- if (TextUtils.isEmpty(pwdStr)) {
- toast.setText("密码不能为空,请重新输入");
- toast.show();
- return;
- }
- if (!pwd.isCheck()) {
- toast.setText("密码格式不正确,请重新输入");
- toast.show();
- return;
- }
- if (!pwdStr.equals(rePwdStr)) {
- toast.setText("两次密码输入不一致,请重新输入");
- toast.show();
- return;
- }
- regedit.setClickable(false);
- regeditSuccess(username.getEdit().getText().toString(),pwd.getEdit().getText().toString());
- }
- /**
- * 去登录
- * @param v
- */
- @OnClick(R.id.tologin)
- public void toLogin(View v) {
- Intent intent = new Intent();
- intent.setClass(this,LoginActivity.class);
- startActivity(intent);
- finish();
- }
- /**
- * 注册成功
- */
- private void regeditSuccess(final String email, final String password) {
- mDialog.showDialog();
- inputMethodManager.hideSoftInputFromWindow(rePwd.getEdit().getWindowToken(), 0);
- HttpUtils httpUtils = new HttpUtils();
- httpUtils.send(HttpRequest.HttpMethod.GET, OnlineSchoolUtil.getRegUrl(email, password), new RequestCallBack<String>() {
- @Override
- public void onSuccess(ResponseInfo<String> responseInfo) {
- prepare(responseInfo.result,email,password);
- }
- @Override
- public void onFailure(HttpException e, String s) {
- mDialog.cancelDialog();
- toast.setText("注册失败");
- toast.show();
- }
- });
- }
- private void prepare(String result,String email,String password) {
- FlagBean entity = GsonUtil.json2Bean(this, result, FlagBean.class);
- if(entity != null && entity.getFlag().equals("3")) {
- mDialog.cancelDialog();
- Intent intent = new Intent();
- intent.setClass(this, RegeditSuccessActivity.class);
- intent.putExtra("username", email);
- intent.putExtra("pwd", password);
- startActivity(intent);
- finish();
- }else {
- mDialog.cancelDialog();
- toast.setText("注册失败");
- toast.show();
- }
- }
- private void regedutfaild(){
- toast.setText("登录失败");
- toast.show();
- }
- }
在regedit_edittext.xml中:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <TextView android:id="@+id/tv"
- android:layout_width="@dimen/s_85dp"
- android:layout_height="wrap_content"
- android:text="asfg"
- android:layout_centerVertical="true"
- android:gravity="end"
- android:textColor="@color/color_333"
- android:textSize="@dimen/s_18dp"
- />
- <EditText
- android:id="@+id/regedit_et"
- android:layout_width="fill_parent"
- android:layout_height="@dimen/s_60dp"
- android:background="#00000000"
- android:paddingLeft="@dimen/s_106dp"
- android:paddingRight="@dimen/s_40dp"
- android:singleLine="true"
- android:textSize="@dimen/s_14dp"
- />
- <ImageView
- android:id="@+id/checkIm"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignRight="@+id/regedit_et"
- android:layout_centerVertical="true"
- android:layout_marginRight="@dimen/s_10dp"
- android:src="@drawable/cw"
- android:visibility="gone"/>
- </RelativeLayout>
属性数组(regedit_eidttext):
- <declare-styleable name="regedit_edittext">
- <attr name="edittype" format="string" />
- <attr name="inputtype" format="reference|enum">
- <enum name="string" value="0"/>
- <enum name="num" value="1"/>
- </attr>
- <attr name="text" format="string"/>
- <attr name="hint_rg" format="reference|string" />
- <attr name="hint_size_rg" format="reference|dimension" />
- <attr name="hint_color_rg" format="reference|color" />
- </declare-styleable>
Icon Image:

Theme Zone:
Android
Include in RSS:
1