Android之必填项的便捷判定--TypedArray(下)

关于Android的必填项,包括登陆、注册等,因为Edittext比较少,所以大多数人选择gettext然后一一判空,但是如果Edittext比较多的时候,就比较繁琐了。考虑到优化方案有二:1、重写Edittext,然后利用注册,在保存时判定每个Edittext;二、考虑到所有的数据最后都会保存成一个类,所以不管Edittext,保存之前只判断自定义类。本文主要阐述第一种方式,优点是不需要反射,耗时短。

首先,我们看效果图:

Android之必填项的便捷判定--TypedArray(下)_第1张图片

实现方法:用单例模式建立注册器,支持动态注册,注册方式有xml,view以及自定义的Edittext,考虑到多Activity的操作与复用,Edittext集合采用CopyOnWriterArrayList,全局集合采用ConcurrentHashMap。最后解绑的时候只需要在基类Activity的onDestroy方法中进行UNRegister即可,非常的方便。

最后,前端Activity的代码:

public class CustomEditActivity extends Activity {

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

    public void onCheck(View view){
        EditTextUtil.getInstance().checkEmpty(this);
    }

    @Override
    protected void onDestroy() {
        EditTextUtil.getInstance().unRegister(this);
        super.onDestroy();
    }
}

与其对应的xml文件:



    
    
    

    

自定义的EditText,支持xml中配置必填项与提示:

public class EmptyEditText extends EditText {

    private boolean necessary = false;
    private String toastString = "";

    public EmptyEditText(Context context) {
        super(context);
    }

    public EmptyEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    public EmptyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    private void init(Context context, @Nullable AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.EmptyEditText);
        if(null != ta) {
            toastString = ta.getString(R.styleable.EmptyEditText_toast_text);
            necessary = ta.getBoolean(R.styleable.EmptyEditText_necessary,false);
            ta.recycle();
        }
    }

    public boolean checkEmpty(){
        return checkEmpty(false);
    }

    public boolean checkEmpty(boolean toast){
        if(necessary) {
            Object value = getText();
            if (null == value || TextUtils.isEmpty(value.toString().trim())) {
                if (toast && !TextUtils.isEmpty(toastString)) {
                    Toast.makeText(getContext(), toastString, Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        }
        return false;
    }
}

最后就是单例模式的注册器,懒加载的模式:

public class EditTextUtil {
    static volatile EditTextUtil defaultInstance;

    private static ConcurrentHashMap> textMap = new ConcurrentHashMap<>();

    public static EditTextUtil getInstance(){
        if(defaultInstance == null)
            defaultInstance = new EditTextUtil();
        return defaultInstance;
    }

    public void register(Context context,int xml){
        View view = LayoutInflater.from(context).inflate(xml,null);
        register(context,view);
    }

    public void register(Context context, View view){
        List textList = getChildEdit(view);
        register(context,textList);
    }

    public void register(Context context, List textList){
        CopyOnWriteArrayList editList = new CopyOnWriteArrayList<>();
        editList.addAll(textList);
        textMap.put(context, editList);
    }

    public void register(Context context, EmptyEditText textList){
        CopyOnWriteArrayList editList = null;
        if(textMap.containsKey(context)){
            editList= textMap.get(context);
        }
        if(null == editList){
            editList = new CopyOnWriteArrayList<>();
        }
        editList.add(textList);
        textMap.put(context, editList);
    }

    private List getChildEdit(View view){
        List textList = new ArrayList<>();
        getChildEdit(textList,view);
        return textList;
    }

    private List getChildEdit(List textList,View view){
        if(view instanceof ViewGroup) {
            ViewGroup vp = (ViewGroup) view;
            for (int i = 0; i < vp.getChildCount(); i++) {
                View viewchild = vp.getChildAt(i);
                if(viewchild instanceof ViewGroup){
                    getChildEdit(textList,viewchild);
                }else if(viewchild instanceof EmptyEditText){
                    textList.add((EmptyEditText) viewchild);
                }
            }
        }
        return textList;
    }

    public boolean checkEmpty(Context context){
        CopyOnWriteArrayList data = textMap.get(context);
        if(null == data || data.size() ==0){
            if(context instanceof Activity){
                List textList = getAllViews((Activity) context);
                register(context,textList);
                return checkEmpty(textList);
            }
            return checkEmpty(data);
        }
        return checkEmpty(data);
    }

    public boolean checkEmpty(CopyOnWriteArrayList editList){
        boolean result = false;
        if(null == editList || editList.size() ==0){
            return result;
        }
        for (EmptyEditText edittext:editList) {
            if(edittext.checkEmpty(true)){
                result = true;
                break;
            }
        }
        return result;
    }

    private List getAllViews(Activity act) {
        return getAllChildViews(act.getWindow().getDecorView());
    }

    private List getAllChildViews(View view) {
        List allchildren = new ArrayList<>();
        if (view instanceof ViewGroup) {
            ViewGroup vp = (ViewGroup) view;
            for (int i = 0; i < vp.getChildCount(); i++) {
                View viewchild = vp.getChildAt(i);
                if(viewchild instanceof EmptyEditText){
                    allchildren.add((EmptyEditText) viewchild);
                }else if(viewchild instanceof ViewGroup){
                    //再次 调用本身(递归)
                    allchildren.addAll(getAllChildViews(viewchild));
                }
            }
        }
        return allchildren;
    }

    public boolean checkEmpty(List data){
        CopyOnWriteArrayList editList = new CopyOnWriteArrayList<>();
        editList.addAll(data);
        return checkEmpty(editList);
    }

    public void unRegister(Context context){
        textMap.remove(context);
    }
}

values中自定义EditText所需要的提示与是否必须:


        
        
    

至此,目前两种Android必填项判空的方式已完成,如果只是单纯的登陆界面无所谓,但是如果是大量添加表单的页面,这样精简还是很有必要的。另外这样的注册器还有一个问题,就是当采用xml的注册方式时,EditText的getText值一直为空,希望大家有好的解决方式!

你可能感兴趣的:(Andorid,UI)