关于Android的必填项,包括登陆、注册等,因为Edittext比较少,所以大多数人选择gettext然后一一判空,但是如果Edittext比较多的时候,就比较繁琐了。考虑到优化方案有二:1、重写Edittext,然后利用注册,在保存时判定每个Edittext;二、考虑到所有的数据最后都会保存成一个类,所以不管Edittext,保存之前只判断自定义类。本文主要阐述第二种方式,第一种方式后续再发布。
判定类的数据是否为空,可以用Java反射;但是考虑到还需要有提示,那么就需要用到Java的另外一个高阶知识:annotation。如果想要具体了解annotation的同学,请百度自行搜索,本文只讲具体应用。
首先我定义一个自己的annotation,名字就叫FieldAnnotate:
package java.wen.com.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FieldAnnotate {
String annotate() default "";//注释
boolean necessary() default true;//是否必填
}
annotate作为类属性的注释,主要用做文本提示,necessary用做判定此属性是否为必填项,默认值为true好处是如果必填项只需要定义annotate就可以了
下一步我们定义一个User类,并使用FieldAnnotate注解:
package java.wen.com.entity;
import java.wen.com.annotation.FieldAnnotate;
public class User {
@FieldAnnotate(annotate = "用户名")
private String name;
@FieldAnnotate(annotate = "密码")
private String password;
@FieldAnnotate(annotate = "用户推荐码",necessary = false)
private String code;
}
可以看到,我们定义的name和password是必填项,用户推荐码是非必填项。用自定义annotation另外一个好处就是,以前写在类后面的属性注释,不但用来判定,还让代码一目了然,不需要多次注释了。
接下来,我们需要利用Java反射中的getDeclaredFields获得属性,然后用再获得相关注释:
package java.wen.com.util;
import android.content.Context;
import android.text.TextUtils;
import android.widget.Toast;
import java.lang.reflect.Field;
import java.wen.com.annotation.FieldAnnotate;
public class AnnotionUtils {
/**
* 通过反射判定所需字段是否不能为空
* @param context 上下文
* @param cs 类名
* @param object 带有值的实体类
* @return true为有必填项为空值
*/
public static boolean checkInfo(Context context,Class<?> cs,Object object) throws IllegalAccessException {
boolean result = false;
if(null != cs){
Field[] declaredFields = cs.getDeclaredFields();
for (Field field : declaredFields){
if(field.isAnnotationPresent(FieldAnnotate.class)){
FieldAnnotate annotation = field.getAnnotation(FieldAnnotate.class);
field.setAccessible(true);
if(annotation.necessary()){
Object obj = field.get(object);
result = obj == null;
if(!result){
result = TextUtils.isEmpty(obj.toString());
}
if(result) {
Toast.makeText(context, annotation.annotate() + "为空,创建失败!", Toast.LENGTH_SHORT).show();
break;
}
}
}
}
}
return result;
}
}
这样,我们只需要在判定的时候,将所有Edittext的数据设置到类里面,不需要考虑任何Edittext填写与否,之后checkInfo就可以知道用户哪些必填项没有写了,我们写一个前端应用:
public class MainActivity extends AppCompatActivity {
User user = new User();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
user.setName("张三");
AnnotionUtils.checkInfo(MainActivity.this,user.getClass(),user);
} catch (IllegalAccessException e) {
}
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
只需要在用户点击保存时轮询类的属性就可以了。我用系统提供的application简单测试一下:
因为我们设置了用户名,所以会直接略过用户名去提示密码。ok,这就是关于annotation的实际运用,Java真的还是非常强大的,可以把繁琐的程序都简单化下来