【Android】登录界面的实现

来源:互联网 发布:局域网 9000端口 编辑:程序博客网 时间:2024/05/15 12:18

资料来源:https://github.com/tyzlmjj/AndroidUI/tree/master/ClearEditText

先把ClearEditText.java和PasswordEditText.java复制到java/包名/中,然后在布局文件中写入

<?xml version="1.0" encoding="utf-8"?><LinearLayout>    <ImageView/>    <包名.ClearEditText        android:hint="请输入注册手机号/账号"        android:theme="@style/MyEditText"        />    <包名.PasswordEditText        android:hint="请输入密码"        android:textSize="12sp"        android:inputType="numberPassword"        android:theme="@style/MyEditText"        />    <Button        android:text="登录"        />    <LinearLayout>        <TextView            android:text="忘记密码?"            />        <TextView            android:text="注册"            />    </LinearLayout></LinearLayout>

改变下划线的颜色,灰色和黄色
values/styles.xml

<resources>    <style        name="MyEditText"        parent="Theme.AppCompat.Light">        <item name="colorControlNormal">#a4a4a3</item>        <item name="colorControlActivated">#febf22</item>    </style></resources>

这里写图片描述

实现的效果是,输入内容就出现“x”,当密码输入到达6位时,登录按钮变色,然后点击登录会提示抖动密码错误

import android.app.Activity;import android.content.Intent;import android.graphics.Color;import android.os.Bundle;import android.support.annotation.Nullable;import android.text.Editable;import android.text.TextWatcher;import android.view.KeyEvent;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;/** * Created by 123 on 2017/08/07. */public class LoginActivity extends Activity implements View.OnClickListener{    private ClearEditText mAccountEditText;    private ClearEditText mPasswordEditText;    private Button mLoginButton;    private TextView mForgetPasswordTextView;    private TextView mSignTextView;    private String mAccountString;    private String mPasswordString;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        ActivityCollector.addActivity(this);        setContentView(R.layout.login_layout);        initView();        intiData();        initEvent();    }    private void initView(){        mAccountEditText=findViewById(R.id.id_login_account_edit_text);        mPasswordEditText=findViewById(R.id.id_login_password_edit_text);        mLoginButton=findViewById(R.id.id_login_login_button);        mForgetPasswordTextView=findViewById(R.id.id_login_forget_password_text_view);        mSignTextView=findViewById(R.id.id_login_sign_text_view);    }    private void intiData(){        mPasswordString=mPasswordEditText.getText().toString();    }    private void initEvent(){        mLoginButton.setOnClickListener(this);        mLoginButton.setClickable(false);        mForgetPasswordTextView.setOnClickListener(this);        mSignTextView.setOnClickListener(this);        //edit监听事件        mPasswordEditText.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) {            }            @Override            public void afterTextChanged(Editable editable) {                if (editable.toString().length()>5){                    setLoginButton(1);                }                else setLoginButton(0);            }        });    }    private void setLoginButton(int effective){        //按键有效        if (effective==1){            mLoginButton.setTextColor(Color.parseColor("#000000"));//黑            mLoginButton.setBackgroundColor(Color.parseColor("#febf22"));//黄杖            mLoginButton.setClickable(true);        }else {            mLoginButton.setClickable(false);            mLoginButton.setTextColor(Color.parseColor("#ffffff"));//白            mLoginButton.setBackgroundColor(Color.parseColor("#a4a4a3"));//灰        }    }    @Override    public void onClick(View view) {        switch (view.getId()){            case R.id.id_login_login_button:                mPasswordEditText.setError("密码输入错误");                mPasswordEditText.startShakeAnimation();                break;            case R.id.id_login_sign_text_view:                mAccountString=mAccountEditText.getText().toString();                Bundle bundle=new Bundle();                bundle.putString("account key",mAccountString);                //Intent intent=new Intent(this,SignActivity.class);                //intent.putExtra("login bundle",bundle);                //startActivity(intent);                break;            case R.id.id_login_forget_password_text_view:                pf("R.id.id_login_forget_password_text_view");                break;        }    }    @Override    protected void onDestroy() {        super.onDestroy();        ActivityCollector.removeActivity(this);    }    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if(keyCode == KeyEvent.KEYCODE_BACK){            ActivityCollector.finishAll();            System.exit(0);            return true;        }        return super.onKeyDown(keyCode, event);    }    private void pf(String string){        Toast.makeText(this, string,Toast.LENGTH_SHORT).show();    }}

ClearEditText.java

import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.PaintFlagsDrawFilter;import android.graphics.PixelFormat;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.support.v4.content.ContextCompat;import android.support.v4.graphics.drawable.DrawableCompat;import android.support.v7.widget.AppCompatEditText;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.animation.Animation;import android.view.animation.CycleInterpolator;import android.view.animation.TranslateAnimation;public class ClearEditText extends AppCompatEditText {    //按钮资源    private final int CLEAR = R.drawable.clearfill;    //动画时长    private final int ANIMATOR_TIME = 200;    //按钮左右间隔,单位DP    private final int INTERVAL = 5;    //清除按钮宽度,单位DP    private final int WIDTH_OF_CLEAR = 23;    //间隔记录    private int Interval;    //清除按钮宽度记录    private int mWidth_clear;    //右内边距    private int mPaddingRight;    //清除按钮的bitmap    private Bitmap mBitmap_clear;    //清除按钮出现动画    private ValueAnimator mAnimator_visible;    //消失动画    private ValueAnimator mAnimator_gone;    //是否显示的记录    private boolean isVisible = false;    //右边添加其他按钮时使用    private int mRight = 0;    public ClearEditText(final Context context) {        super(context);        init(context);    }    public ClearEditText(final Context context, final AttributeSet attrs) {        super(context, attrs);        init(context);    }    public ClearEditText(final Context context, final AttributeSet attrs, final int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mBitmap_clear = createBitmap(CLEAR,context);        Interval = dp2px(INTERVAL);        mWidth_clear = dp2px(WIDTH_OF_CLEAR);        mPaddingRight = Interval + mWidth_clear + Interval ;        mAnimator_gone = ValueAnimator.ofFloat(1f, 0f).setDuration(ANIMATOR_TIME);        mAnimator_visible = ValueAnimator.ofInt(mWidth_clear + Interval,0).setDuration(ANIMATOR_TIME);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //设置内边距        setPadding(getPaddingLeft(), getPaddingTop(), mPaddingRight+ mRight, getPaddingBottom());    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));//抗锯齿        if (mAnimator_visible.isRunning()) {            int x = (int) mAnimator_visible.getAnimatedValue();            drawClear(x,canvas);            invalidate();        }else if (isVisible){            drawClear(0,canvas);        }        if(mAnimator_gone.isRunning()){            float scale = (float) mAnimator_gone.getAnimatedValue();            drawClearGone(scale, canvas);            invalidate();        }    }    /**     * 绘制清除按钮出现的图案     * @param translationX 水平移动距离     * @param canvas     */    protected void drawClear( int translationX,Canvas canvas){        int right = getWidth()+getScrollX() - Interval - mRight +translationX;        int left = right-mWidth_clear;        int top = (getHeight()-mWidth_clear)/2;        int bottom = top + mWidth_clear;        Rect rect = new Rect(left,top,right,bottom);        canvas.drawBitmap(mBitmap_clear, null, rect, null);    }    /**     * 绘制清除按钮消失的图案     * @param scale 缩放比例     * @param canvas     */    protected void drawClearGone( float scale,Canvas canvas){        int right = (int) (getWidth()+getScrollX()- Interval - mRight -mWidth_clear*(1f-scale)/2f);        int left = (int) (getWidth()+getScrollX()- Interval - mRight -mWidth_clear*(scale+(1f-scale)/2f));        int top = (int) ((getHeight()-mWidth_clear*scale)/2);        int bottom = (int) (top + mWidth_clear*scale);        Rect rect = new Rect(left,top,right,bottom);        canvas.drawBitmap(mBitmap_clear, null, rect, null);    }    /**     * 开始清除按钮的显示动画     */    private void startVisibleAnimator() {        endAnaimator();        mAnimator_visible.start();        invalidate();    }    /**     * 开始清除按钮的消失动画     */    private void startGoneAnimator() {        endAnaimator();        mAnimator_gone.start();        invalidate();    }    /**     * 结束所有动画     */    private void endAnaimator(){        mAnimator_gone.end();        mAnimator_visible.end();    }    /**     * Edittext内容变化的监听     * @param text     * @param start     * @param lengthBefore     * @param lengthAfter     */    @Override    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {        super.onTextChanged(text, start, lengthBefore, lengthAfter);        if(text.length()>0) {            if (!isVisible) {                isVisible = true;                startVisibleAnimator();            }        }else{            if (isVisible) {                isVisible = false;                startGoneAnimator();            }        }    }    /**     * 触控执行的监听     * @param event     * @return     */    @Override    public boolean onTouchEvent(MotionEvent event) {        if (event.getAction() == MotionEvent.ACTION_UP) {            boolean touchable = ( getWidth() - Interval - mRight - mWidth_clear < event.getX() ) && (event.getX() < getWidth() - Interval - mRight);            if (touchable) {                setError(null);                this.setText("");            }        }        return super.onTouchEvent(event);    }    /**     * 开始晃动动画     */    public void startShakeAnimation(){        if(getAnimation() == null){            this.setAnimation(shakeAnimation(4));        }        this.startAnimation(getAnimation());    }    /**     * 晃动动画     * @param counts 0.5秒钟晃动多少下     * @return     */    private Animation shakeAnimation(int counts){        Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);        translateAnimation.setInterpolator(new CycleInterpolator(counts));        translateAnimation.setDuration(500);        return translateAnimation;    }    /**     * 给图标染上当前提示文本的颜色并且转出Bitmap     * @param resources     * @param context     * @return     */    public Bitmap createBitmap(int resources, Context context) {        final Drawable drawable = ContextCompat.getDrawable(context, resources);        final Drawable wrappedDrawable = DrawableCompat.wrap(drawable);        DrawableCompat.setTint(wrappedDrawable, getCurrentHintTextColor());        return drawableToBitamp(wrappedDrawable);    }    /**     * drawable转换成bitmap     * @param drawable     * @return     */    private Bitmap drawableToBitamp(Drawable drawable)    {        int w = drawable.getIntrinsicWidth();        int h = drawable.getIntrinsicHeight();        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;        Bitmap bitmap = Bitmap.createBitmap(w, h, config);        Canvas canvas = new Canvas(bitmap);        drawable.setBounds(0, 0, w, h);        drawable.draw(canvas);        return bitmap;    }    public int dp2px(float dipValue) {        final float scale = getResources().getDisplayMetrics().density;        return (int) (dipValue * scale + 0.5f);    }    //----------------以下方法为方便子类继承,只使用ClearEditText就没有用处---------------------------------------------------------------------    public int getInterval() {        return  Interval;    }    public int getmWidth_clear() {        return mWidth_clear;    }    public Bitmap getmBitmap_clear() {        return mBitmap_clear;    }    public void addRight(int right){        mRight += right;    }}

PasswordEditText .java

import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Rect;import android.text.method.HideReturnsTransformationMethod;import android.text.method.PasswordTransformationMethod;import android.util.AttributeSet;import android.view.MotionEvent;/** * Created by 家杰 on 2015/11/20. */public class PasswordEditText extends ClearEditText{    //资源    private final int INVISIBLE = R.drawable.close;    private final int VISIBLE = R.drawable.open;    //按钮宽度dp    private int mWidth;    //按钮的bitmap    private Bitmap mBitmap_invisible;    private Bitmap mBitmap_visible;    //间隔    private int Interval;    //内容是否可见    private boolean isVisible = false;    public PasswordEditText(final Context context) {        super(context);        init(context);    }    public PasswordEditText(final Context context, final AttributeSet attrs) {        super(context, attrs);        init(context);    }    public PasswordEditText(final Context context, final AttributeSet attrs, final int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        setSingleLine();        //设置EditText文本为隐藏的(注意!需要在setSingleLine()之后调用)        setTransformationMethod(PasswordTransformationMethod.getInstance());        mWidth = getmWidth_clear();        Interval = getInterval();        addRight(mWidth+Interval);        mBitmap_invisible = createBitmap(INVISIBLE,context);        mBitmap_visible = createBitmap(VISIBLE,context);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int right = getWidth()+getScrollX()- Interval ;        int left = right-mWidth;        int top = (getHeight()-mWidth)/2;        int bottom = top + mWidth;        Rect rect = new Rect(left,top,right,bottom);        if(isVisible){            canvas.drawBitmap(mBitmap_visible, null, rect, null);        }else{            canvas.drawBitmap(mBitmap_invisible, null, rect, null);        }    }    /**     * 改写父类的方法     */    @Override    protected void drawClear(int translationX, Canvas canvas) {        float scale = 1f - (float)(translationX)/(float)(getmWidth_clear()+Interval);        int right = (int) (getWidth()+getScrollX()- Interval-mWidth-Interval -getmWidth_clear()*(1f-scale)/2f);        int left = (int) (getWidth()+getScrollX()- Interval-mWidth-Interval -getmWidth_clear()*(scale+(1f-scale)/2f));        int top = (int) ((getHeight()-getmWidth_clear()*scale)/2);        int bottom = (int) (top + getmWidth_clear()*scale);        Rect rect = new Rect(left,top,right,bottom);        canvas.drawBitmap(getmBitmap_clear(), null, rect, null);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        if (event.getAction() == MotionEvent.ACTION_UP) {            boolean touchable = ( getWidth() - mWidth - Interval < event.getX() ) && (event.getX() < getWidth() - Interval);            if (touchable) {                isVisible = !isVisible;                if (isVisible){                    //设置EditText文本为可见的                    setTransformationMethod(HideReturnsTransformationMethod.getInstance());                }else{                    //设置EditText文本为隐藏的                    setTransformationMethod(PasswordTransformationMethod.getInstance());                }            }        }        return super.onTouchEvent(event);    }}