首页
登录 | 注册

自定义登录界面的 EditText(上)

项目中经常会有登录界面,包含输入用户名、手机号、验证码、密码等。输入手机号,会有一键删除。于是自定义这些,方便今后使用。

1、效果图

自定义登录界面的 EditText(上)
自定义登录界面的 EditText(上)

2、代码

自定义登录界面的 EditText(上)

1、MyApplication.java
记得在清单文件中修改 application name

package com.gyq.test.base;

import android.app.Application;
import android.content.Context;

/**
 * Created by DELL on 2018/5/23.
 */

public class MyApplication extends Application {
    private static Context appContext;

    @Override
    public void onCreate() {
        super.onCreate();
        appContext = this.getApplicationContext();
    }

    public static Context getContext() {
        return appContext;
    }
}

2、ForgetActivity.java

public class ForgetActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_forget);
    }
}

3、LoginActivity.java

package com.gyq.test.ui.activity;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.gyq.test.R;
import com.gyq.test.widget.InputView;
import com.gyq.test.widget.InputViewWithCode;

public class LoginActivity extends AppCompatActivity {
    private LinearLayout llcodeLogin, llpwdLogin;
    private TextView codeLogin, pwdLogin,forgetPwd;
    private InputView codeInputPhone, pwdInputPhone, pwdInputPwd;
    private InputViewWithCode codeInputCode;
    private Button login, wxLogin;

    private final int CODE_LOGIN = 1;
    private final int PWD_LOGIN = 2;
    private int currentMode = CODE_LOGIN;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        llcodeLogin = (LinearLayout) findViewById(R.id.ll_code_login);
        llpwdLogin = (LinearLayout) findViewById(R.id.ll_pwd_login);
        codeLogin = (TextView) findViewById(R.id.code_login);
        pwdLogin = (TextView) findViewById(R.id.pwd_login);
        codeLogin.getPaint().setFakeBoldText(true);
        codeLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                llcodeLogin.setVisibility(View.VISIBLE);
                llpwdLogin.setVisibility(View.INVISIBLE);
                codeLogin.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
                codeLogin.getPaint().setFakeBoldText(true);
                pwdLogin.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17);
                pwdLogin.getPaint().setFakeBoldText(false);
                currentMode = CODE_LOGIN;
            }
        });
        pwdLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                llcodeLogin.setVisibility(View.INVISIBLE);
                llpwdLogin.setVisibility(View.VISIBLE);
                codeLogin.setTextSize(TypedValue.COMPLEX_UNIT_SP, 17);
                codeLogin.getPaint().setFakeBoldText(false);
                pwdLogin.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
                pwdLogin.getPaint().setFakeBoldText(true);
                currentMode = PWD_LOGIN;
            }
        });


        forgetPwd= (TextView) findViewById(R.id.forget_password);
        forgetPwd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent toForget = new Intent(LoginActivity.this, ForgetActivity.class);
                startActivity(toForget);
            }
        });
    }
}

工具类

4、EmojiTools.java

package com.gyq.test.utils;

import android.text.TextUtils;

/**
 * Created by DELL on 2018/5/23.
 */

public class EmojiTools {
    public static boolean containsEmoji(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }

        for (int i = 0; i < str.length(); i++) {


            int cp = str.codePointAt(i);


            if (isEmojiCharacter(cp)) {
                return true;
            }
        }
        return false;
    }

    private static boolean isEmojiCharacter(int first) {



       /* 1F30D - 1F567
        1F600 - 1F636
        24C2 - 1F251
        1F680 - 1F6C0
        2702 - 27B0
        1F601 - 1F64F*/

        return !
                ((first == 0x0) ||
                        (first == 0x9) ||
                        (first == 0xA) ||
                        (first == 0xD) ||
                        ((first >= 0x20) && (first <= 0xD7FF)) ||
                        ((first >= 0xE000) && (first <= 0xFFFD)) ||
                        ((first >= 0x10000))) ||


                (first == 0xa9 || first == 0xae || first == 0x2122 ||
                        first == 0x3030 || (first >= 0x25b6 && first <= 0x27bf) ||
                        first == 0x2328 || (first >= 0x23e9 && first <= 0x23fa))
                || ((first >= 0x1F000 && first <= 0x1FFFF))
                || ((first >= 0x2702) && (first <= 0x27B0))
                || ((first >= 0x1F601) && (first <= 0x1F64F))

                ;


    }

    public static String filterEmoji(String str) {

        if (!containsEmoji(str)) {
            return str;
        } else {
        }
        StringBuilder buf = null;
        int len = str.length();
        for (int i = 0; i < len; i++) {
            char codePoint = str.charAt(i);
            if (!isEmojiCharacter(codePoint)) {
                if (buf == null) {
                    buf = new StringBuilder(str.length());
                }
                buf.append(codePoint);
            } else {

            }
        }

        if (buf == null) {
            return "";
        } else {
            return buf.toString();
        }

    }
}

5、SystemUtil.java

package com.gyq.test.utils;

import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Base64;
import android.util.Log;

import com.gyq.test.R;
import com.gyq.test.base.MyApplication;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 获取系统相关信息工具
 * Created by DELL on 2018/5/23.
 */

public class SystemUtil {
    /**
     * 获取当前横竖屏状态
     *
     * @return 返回 true 为 竖屏
     * false为横屏
     */
    public static boolean isScreenPort(Context context) {
        Configuration mConfiguration = context.getResources().getConfiguration();
        int ori = mConfiguration.orientation;
        if (ori == Configuration.ORIENTATION_PORTRAIT) {
            return true;
        } else {
            return false;
        }
    }

    public static boolean ableToStartImageCaptureIntent(Context context) {
        return (!isCameraPermissionDeclaredInManifest(context)
                || isPermissionGranted(context, Manifest.permission.CAMERA));
    }

    public static boolean isCameraPermissionDeclaredInManifest(Context context) {
        return isPermissionInManifest(context, Manifest.permission.CAMERA);
    }

    public static boolean isPermissionGranted(Context context, String permission) {
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
    }

    public static boolean isPermissionInManifest(Context context, String permission) {
        final String packageName = context.getPackageName();
        try {
            final PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
            final String[] requestedPermissions = packageInfo.requestedPermissions;
            if (requestedPermissions != null && requestedPermissions.length > 0) {
                for (String p : requestedPermissions) {
                    if (p.equals(permission)) {
                        return true;
                    }
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static void requestStartImageCapturePermissions(Activity activity, int requestCode) {
        ArrayList<String> requestPermissions = new ArrayList<>(2);
        // 根据android文档,如果在manifest中声明了CAMERA权限却没有取得此权限,则调用START_CAPTURE时会抛出SecurityException
        if (!isCameraPermissionDeclaredInManifest(activity)
                || isPermissionGranted(activity, Manifest.permission.CAMERA)) {
            try {
                throw new RuntimeException("All permissions have been granted!");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, requestCode);
    }

    public static boolean readContentUriToFile(Context context, Uri uri, File file) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            inputStream = context.getContentResolver().openInputStream(uri);
            if (inputStream == null) {
                return false;
            }

            outputStream = new FileOutputStream(file);

            byte[] buffer = new byte[1024];
            int read = 0;
            while ((read = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, read);
            }

            return true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 获取图片的中心区域,以短边为边长的正方形
     *
     * @param bitmap
     * @return
     */
    public static Bitmap getCenterBitmap(Bitmap bitmap) {
        if (bitmap == null || bitmap.getWidth() == 0 || bitmap.getHeight() == 0) {
            return null;
        }

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        int minLength = Math.min(width, height);

        return Bitmap.createBitmap(bitmap, (width - minLength) / 2, (height - minLength) / 2,
                minLength, minLength);
    }

    /**
     * 放大缩小图片
     *
     * @param bitmap
     * @param w
     * @param h
     * @return
     */
    public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidht = ((float) w / width);
        float scaleHeight = ((float) h / height);
        matrix.postScale(scaleWidht, scaleHeight);
        Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
        return newbmp;
    }

    /**
     * 获得圆角图片
     *
     * @param bitmap
     * @param roundPx
     * @return
     */
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }


    /**
     * bitmap转为base64
     *
     * @param bitmap
     * @return
     */
    public static String bitmapToBase64(Bitmap bitmap) {

        String result = null;
        ByteArrayOutputStream baos = null;
        try {
            if (bitmap != null) {
                baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

                baos.flush();
                baos.close();

                byte[] bitmapBytes = baos.toByteArray();
                result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (baos != null) {
                    baos.flush();
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * base64转为bitmap
     *
     * @param base64Data
     * @return
     */
    public static Bitmap base64ToBitmap(String base64Data) {
        byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    /**
     * 通过Base32将Bitmap转换成Base64字符串
     *
     * @param bit
     * @return
     */
    public static String Bitmap2StrByBase64(Bitmap bit) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bit.compress(Bitmap.CompressFormat.JPEG, 40, bos);//参数100表示不压缩
        byte[] bytes = bos.toByteArray();
        return Base64.encodeToString(bytes, Base64.DEFAULT);
    }

    /**
     * get App versionCode
     *
     * @param context
     * @return
     */
    public static String getVersionCode(Context context) {
        PackageManager packageManager = context.getPackageManager();
        PackageInfo packageInfo;
        String versionCode = "";
        try {
            packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            versionCode = packageInfo.versionCode + "";
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionCode;
    }

    /**
     * get App versionName
     *
     * @param context
     * @return
     */
    public static String getVersionName(Context context) {
        PackageManager packageManager = context.getPackageManager();
        PackageInfo packageInfo;
        String versionName = "";
        try {
            packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            versionName = packageInfo.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionName;
    }

    /**
     * 检测网络
     * @return ture:有可用网络 ,false:没有网络
     */
    public static boolean checkNetwork(){
        boolean result;
        Context con = MyApplication.getContext();
        ConnectivityManager connectivity = (ConnectivityManager) con.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity == null) {
            result = false;
        } else {
            NetworkInfo info = connectivity.getActiveNetworkInfo();
            result = info != null && info.isConnected();
        }
        if (!result)
            ToastUtil.showToast(con.getString(R.string.net_request_time_out));
        return result;
    }

    /**
     * 判断应用是否已经启动
     * @param context 一个context
     * @param packageName 要判断应用的包名
     * @return boolean
     */
    public static boolean isAppAlive(Context context, String packageName){
        ActivityManager activityManager =
                (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> processInfos
                = activityManager.getRunningAppProcesses();
        for(int i = 0; i < processInfos.size(); i++){
            if(processInfos.get(i).processName.equals(packageName)){
                Log.i("NotificationLaunch",
                        String.format("the %s is running, isAppAlive return true", packageName));
                return true;
            }
        }
        Log.i("NotificationLaunch",
                String.format("the %s is not running, isAppAlive return false", packageName));
        return false;
    }

    private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>();
    private static final Object object = new Object();
    /**
     * 将日期字符串转化为另一日期字符串。失败返回null。
     *
     * @param date         旧日期字符串
     * @param olddDteStyle 旧日期风格
     * @param newDateStyle 新日期风格
     * @return 新日期字符串
     */
    /*public static String StringToString(String date, DateStyle olddDteStyle, DateStyle newDateStyle) {
        String dateString = null;
        if (olddDteStyle != null && newDateStyle != null) {
            dateString = StringToString(date, olddDteStyle.getValue(), newDateStyle.getValue());
        }
        return dateString;
    }*/

    /**
     * 将日期字符串转化为另一日期字符串。失败返回null。
     *
     * @param date        旧日期字符串
     * @param olddPattern 旧日期格式
     * @param newPattern  新日期格式
     * @return 新日期字符串
     */
    public static String StringToString(String date, String olddPattern, String newPattern) {
        return DateToString(StringToDate(date, olddPattern), newPattern);
    }

    /**
     * 将日期转化为日期字符串。失败返回null。
     *
     * @param date    日期
     * @param pattern 日期格式
     * @return 日期字符串
     */
    public static String DateToString(Date date, String pattern) {
        String dateString = null;
        if (date != null) {
            try {
                dateString = getDateFormat(pattern).format(date);
            } catch (Exception e) {
            }
        }
        return dateString;
    }

    /**
     * 将日期字符串转化为日期。失败返回null。
     *
     * @param date    日期字符串
     * @param pattern 日期格式
     * @return 日期
     */
    public static Date StringToDate(String date, String pattern) {
        Date myDate = null;
        if (date != null) {
            try {
                myDate = getDateFormat(pattern).parse(date);
            } catch (Exception e) {
            }
        }
        return myDate;
    }

    /**
     * 获取SimpleDateFormat
     *
     * @param pattern 日期格式
     * @return SimpleDateFormat对象
     * @throws RuntimeException 异常:非法日期格式
     */
    private static SimpleDateFormat getDateFormat(String pattern) throws RuntimeException {
        SimpleDateFormat dateFormat = threadLocal.get();
        if (dateFormat == null) {
            synchronized (object) {
                if (dateFormat == null) {
                    dateFormat = new SimpleDateFormat(pattern);
                    dateFormat.setLenient(false);
                    threadLocal.set(dateFormat);
                }
            }
        }
        dateFormat.applyPattern(pattern);
        return dateFormat;
    }

    public static String getTopActivityClassName(Context context) {
        String result = "";
        try {
            ActivityManager manager = ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE));
            List localList = manager.getRunningTasks(1);
            ActivityManager.RunningTaskInfo localRunningTaskInfo = (ActivityManager.RunningTaskInfo)localList.get(0);
            result = localRunningTaskInfo.topActivity.getClassName();
        }catch (Exception e){
        }
        return result;
    }


    public static boolean isAppIsInBackground(Context context) {
        boolean isInBackground = false;
        try {
            ActivityManager manager = ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE));
            List localList = manager.getRunningTasks(1);
            ActivityManager.RunningTaskInfo localRunningTaskInfo = (ActivityManager.RunningTaskInfo)localList.get(0);
            if(localRunningTaskInfo.topActivity.getPackageName().equals(context.getPackageName())){
                isInBackground = false;
            }else{
                isInBackground = true;
            }
        }catch (Exception e){
            isInBackground = false;
        }
        return isInBackground;
    }
}

6、ToastUtil.java

package com.gyq.test.utils;

import android.os.Looper;
import android.widget.Toast;

import com.gyq.test.base.MyApplication;

/**
 * Created by DELL on 2018/5/23.
 */

public class ToastUtil {
    public static void showToast(String msg){
        if(isMainThread()){
            Toast.makeText(MyApplication.getContext(),msg,Toast.LENGTH_SHORT).show();
        }else{
            Looper.prepare();
            Toast.makeText(MyApplication.getContext(),msg,Toast.LENGTH_SHORT).show();
            Looper.loop();
        }
    }

    public static void showLongToast(String msg){
        if(isMainThread()){
            Toast.makeText(MyApplication.getContext(),msg,Toast.LENGTH_LONG).show();
        }else{
            Looper.prepare();
            Toast.makeText(MyApplication.getContext(),msg,Toast.LENGTH_LONG).show();
            Looper.loop();
        }
    }

    public static boolean isMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }
}

7、ContainsEmojiEditText.java

package com.gyq.test.widget;

import android.content.Context;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.EditText;

import com.gyq.test.R;
import com.gyq.test.utils.EmojiTools;
import com.gyq.test.utils.ToastUtil;

/**
 * Created by DELL on 2018/5/23.
 */

public class ContainsEmojiEditText extends EditText {
    //输入表情前的光标位置
    private int cursorPos;
    //输入表情前EditText中的文本
    private String inputAfterText;
    //是否重置了EditText的内容
    private boolean resetText;

    private Context mContext;
    private CharSequence input;

    public ContainsEmojiEditText(Context context) {
        super(context);
        this.mContext = context;
        initEditText();
    }

    public ContainsEmojiEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        initEditText();
    }

    public ContainsEmojiEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        initEditText();
    }

    // 初始化edittext 控件
    private void initEditText() {
        addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int before, int count) {
                if (!resetText) {
                    cursorPos = getSelectionEnd();
                    // 这里用s.toString()而不直接用s是因为如果用s,
                    // 那么,inputAfterText和s在内存中指向的是同一个地址,s改变了,
                    // inputAfterText也就改变了,那么表情过滤就失败了
                    inputAfterText = s.toString();

                    Log.i("itgoyo", "beforeTextChanged--> " + inputAfterText);
                    Log.i("itgoyo", "cursorPos--> " + cursorPos);
                }

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (!resetText) {
                    if (count >= 1) {//表情符号的字符长度最小为2
                        if (count - before == 20) {
                            input = s.toString().subSequence(start, count);
                        } else {
                            input = s.toString().subSequence(start, start + count);
                        }
                        if (EmojiTools.containsEmoji(input.toString())) {
                            resetText = true;
                            //是表情符号就将文本还原为输入表情符号之前的内容
                            ToastUtil.showToast(mContext.getString(R.string.base_xx_no_support));
                            setText(inputAfterText);
                            CharSequence text = getText();
                            if (text instanceof Spannable) {
                                Spannable spanText = (Spannable) text;
                                Selection.setSelection(spanText, text.length());
                            }
                        }
                    }
                } else {
                    resetText = false;
                }


            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }
}

8、InputView.java

package com.gyq.test.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.gyq.test.R;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * Created by DELL on 2018/5/23.
 */

public class InputView extends LinearLayout{
    private Context context;

    private ImageView imgIcon, imgDelete, imgPwd;
    private EditText edtText;
    private View bottomLine;
    private RelativeLayout deleteRl, pwdRl;

    private int iconFocusId;
    private int iconNormalId;
    private int iconDeleteId;
    private int iconShowPedId;
    private int iconHidePwdId;
    private String hintText = "";
    private String inputType = "";
    private boolean hasBottomLine = true;
    private boolean hasIcon = true;
    private boolean isPwdShow = false;

    public InputView(Context context) {
        this(context, null);
    }

    public InputView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public InputView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        initView();
        initAttrs(attrs);
        initData();
    }

    private void initAttrs(AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.input_view);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.input_view_iconNormal:
                    iconNormalId = a.getResourceId(attr, R.drawable.icon_as_logo);
                    break;
                case R.styleable.input_view_iconFocus:
                    iconFocusId = a.getResourceId(attr, R.drawable.icon_as_logo);
                    break;
                case R.styleable.input_view_iconDelete:
                    iconDeleteId = a.getResourceId(attr, R.drawable.icon_as_logo);
                    break;
                case R.styleable.input_view_hintText:
                    hintText = a.getString(attr);
                    break;
                case R.styleable.input_view_typeInput:
                    inputType = a.getString(attr);
                    break;
                case R.styleable.input_view_hasBottomLine:
                    hasBottomLine = a.getBoolean(attr, true);
                    break;
                case R.styleable.input_view_hasIcon:
                    hasIcon = a.getBoolean(attr, true);
                    break;
                case R.styleable.input_view_showPwd:
                    iconShowPedId = a.getResourceId(attr, R.drawable.icon_as_logo);
                    break;
                case R.styleable.input_view_hidePwd:
                    iconHidePwdId = a.getResourceId(attr, R.drawable.icon_as_logo);
                    break;
            }
        }
        a.recycle();
    }

    private void initView() {
        View view = View.inflate(context, R.layout.common_item_input, this);
        imgIcon = (ImageView) view.findViewById(R.id.img_icon);
        imgDelete = (ImageView) view.findViewById(R.id.img_delete);
        imgPwd = (ImageView) view.findViewById(R.id.img_pwd);
        edtText = (EditText) view.findViewById(R.id.edt_input);
        bottomLine = view.findViewById(R.id.bottom_line);
        deleteRl = (RelativeLayout) view.findViewById(R.id.delete_rl);
        pwdRl = (RelativeLayout) view.findViewById(R.id.pwd_rl);
    }

    private void initData() {
        edtText.setHint(hintText);
        if (!hasBottomLine) bottomLine.setVisibility(GONE);
        if (!hasIcon) imgIcon.setVisibility(GONE);
        edtText.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                imgIcon.setImageResource(hasFocus ? iconFocusId : iconNormalId);
                if(inputType.equals("pass")){
                    deleteRl.setVisibility(INVISIBLE);
                }else{
                    deleteRl.setVisibility(hasFocus ? View.VISIBLE : View.INVISIBLE);
                }
            }
        });
        edtText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
        deleteRl.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                edtText.setText("");
            }
        });
        imgIcon.setImageResource(iconNormalId);
        imgDelete.setImageResource(iconDeleteId);
        deleteRl.setVisibility(View.INVISIBLE);
        imgPwd.setImageResource(iconHidePwdId);
        pwdRl.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isPwdShow) {
                    imgPwd.setImageResource(iconHidePwdId);
                    edtText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                    edtText.setSelection(edtText.getText().length());
                    isPwdShow = false;
                } else {
                    edtText.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
                    edtText.setSelection(edtText.getText().length());
                    imgPwd.setImageResource(iconShowPedId);
                    isPwdShow = true;
                }
            }
        });
        if (!TextUtils.isEmpty(inputType)) {
            System.out.println("InputType.TYPE_TEXT_VARIATION_PASSWORD");
            if (inputType.equals("text")) {
                edtText.setInputType(InputType.TYPE_CLASS_TEXT);
            } else if (inputType.equals("phone")) {
                edtText.setInputType(InputType.TYPE_CLASS_PHONE);
            } else if (inputType.equals("pass")) {
                edtText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                pwdRl.setVisibility(View.VISIBLE);
                setTextChangeListener(new MyPassTextWatcher());
            }else if(inputType.equals("email")){
                edtText.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
            }
        }
    }

    public String getInputText() {
        return edtText.getText().toString().trim();
    }

    public void setInputText(String msg) {
        edtText.setText(msg);
    }

    public void setEnable(boolean enable) {
        edtText.setEnabled(enable);
    }

    public void setTextChangeListener(TextWatcher textWatcher) {
        edtText.addTextChangedListener(textWatcher);
    }

    public class MyPassTextWatcher implements TextWatcher {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            String editable = edtText.getText().toString();
            String str = stringFilter(editable.toString());
            if (!editable.equals(str)) {
                edtText.setText(str);
                edtText.setSelection(str.length());
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    }

    public static String stringFilter(String str) throws PatternSyntaxException {
        // 只允许字母、数字和汉字
        String regEx = "[^a-zA-Z0-9]";//
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();
    }

    public void setHintText(String hintText){
        edtText.setHint(hintText);
    }

    public void setInputType(int inputType){
        edtText.setInputType(inputType);
    }
}

9、InputViewWithCode.java

package com.gyq.test.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.gyq.test.R;
import com.gyq.test.utils.SystemUtil;
import com.gyq.test.utils.ToastUtil;

/**
 * Created by DELL on 2018/5/23.
 */

public class InputViewWithCode extends LinearLayout {
    private static final String TAG = "InputViewWithCode";
    private boolean sending = false;
    private int DEFAULT_COUNT = 60;
    private static final int DEFAULT_CHANGE_TIME = 1000;
    private static final int WHAT_CHANGE_COUNT = 11;

    private Context context;

    private ImageView imgIcon;
    private EditText edtText;
    private TextView txtGetCheck;

    private int iconFocusId;
    private int iconNormalId;
    private int iconCheckId = -1;
    private String hintText = "";
    private String check = getResources().getString(R.string.lab_input_get_check);

    private int codeType = 1;
    private boolean registState = true;

    private String phoneNumber;

    private boolean hasIcon = true;


    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case WHAT_CHANGE_COUNT:
                    changeCount();
                    break;
            }
        }
    };

    public InputViewWithCode(Context context) {
        this(context, null);
    }

    public InputViewWithCode(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public InputViewWithCode(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        initView();
        initAttrs(attrs);
        initData();
    }

    private void initAttrs(AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.input_view);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.input_view_iconNormal:
                    iconNormalId = a.getResourceId(attr, R.drawable.icon_msg_type_other);
                    break;
                case R.styleable.input_view_iconFocus:
                    iconFocusId = a.getResourceId(attr, R.drawable.icon_msg_type_other);
                    break;
                case R.styleable.input_view_hintText:
                    hintText = a.getString(attr);
                    break;
                case R.styleable.input_view_iconCheck:
                    iconCheckId = a.getResourceId(attr, R.drawable.icon_msg_type_other);
                    break;
                case R.styleable.input_view_codeType:
                    codeType = a.getInt(attr, 1);
                    break;
                case R.styleable.input_view_hasIcon:
                    hasIcon = a.getBoolean(attr, true);
                    break;
            }
        }
        a.recycle();
    }

    private void initView() {
        View view = View.inflate(context, R.layout.common_item_input_with_code, this);
        imgIcon = (ImageView) view.findViewById(R.id.img_icon);
        edtText = (EditText) view.findViewById(R.id.edt_input);
        txtGetCheck = (TextView) view.findViewById(R.id.txt_check);
    }

    private void initData() {
        txtGetCheck.setText(check);
        edtText.setHint(hintText);
        imgIcon.setImageResource(iconNormalId);
        if (!hasIcon) imgIcon.setVisibility(GONE);
        txtGetCheck.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (sending) {
                    return;
                }
                if (SystemUtil.checkNetwork())
                    getCheck(phoneNumber);
            }
        });
        edtText.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                imgIcon.setImageResource(hasFocus ? iconFocusId : iconNormalId);
            }
        });
    }

    public String getInputText() {
        return edtText.getText().toString().trim();
    }

    public void setInputText(String msg) {
        edtText.setText(msg);
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void changeCount() {
        sending = true;
        txtGetCheck.setClickable(false);
        DEFAULT_COUNT--;
        txtGetCheck.setText("  " + DEFAULT_COUNT + " s  ");
        txtGetCheck.setTextColor(getResources().getColor(R.color.black_55));
        txtGetCheck.setBackground(getResources().getDrawable(R.drawable.btn_code_rq_pre));
        if (DEFAULT_COUNT > 0) {
            mHandler.sendEmptyMessageDelayed(WHAT_CHANGE_COUNT, DEFAULT_CHANGE_TIME);
        } else {
            DEFAULT_COUNT = 60;
            txtGetCheck.setText(check);
            txtGetCheck.setTextColor(Color.parseColor("#ee862c"));
            txtGetCheck.setBackground(getResources().getDrawable(R.drawable.btn_code_rq_nor));
            txtGetCheck.setClickable(true);
            sending = false;
        }
    }

    private void getCheck(String phoneNumber) {
        if (sending) {
            return;
        }
        /*if (TextUtils.isEmpty(phoneNumber)) {
            ToastUtil.showToast(getContext().getString(R.string.info_user_null));
            return;
        }

        if(MyApplication.isChinaLanguage()){
            if (!RegularUtil.isMobileNO(phoneNumber)) {
                ToastUtil.showToast(getContext().getString(R.string.info_phone_error));
                return;
            }
        }else{
            if (!RegularUtil.isEmail(phoneNumber)) {
                ToastUtil.showToast(getContext().getString(R.string.info_email_error));
                return;
            }
        }*/

        /*CnUserHandler.getCode(phoneNumber, codeType, new MyRequestCallBack<CommonResponse>() {
            @Override
            public void onStart() {
                MLog.d(TAG, "onStart loginHandler.requestGetCheck");
                ToastUtil.showToast(context.getString(R.string.login_get_check_code));
            }

            @Override
            public void onSuccess(CommonResponse response) {
                MLog.d(TAG, "onSuccess =" + response);
                if (response.getCode().equals("1")) {
                    registState = true;
                    mHandler.sendEmptyMessage(WHAT_CHANGE_COUNT);
                }else{
                    String error = response.getMsg();
                    if(!TextUtils.isEmpty(error)){
                        ToastUtil.showToast(error);
                    }else{
                        ToastUtil.showToast(response.getCode());
                    }
                }
            }

            @Override
            public void onFail(String error) {
                MLog.d(TAG, "onFail = " + error);
                if (error != null && error.contains(context.getString(R.string.login_not_regist))) {
                    mHandler.sendEmptyMessage(WHAT_CHANGE_COUNT);
                    registState = false;
                } else
                    ToastUtil.showToast(error);
            }
        });*/

    }

    public int getCodeType() {
        return codeType;
    }

    public void setCodeType(int codeType) {
        this.codeType = codeType;
    }

    public boolean getRegistState(){
        return registState;
    }
}

由于篇幅原因,下一篇加上相应的布局文件。



2020 jeepxie.net webmaster#jeepxie.net
10 q. 0.009 s.
京ICP备10005923号