文章转载自第一代码原创文章:https://www.diyidaima.com/android/164.html
在实际开发中,会经常使用到findViewById获取控件,但是业务一旦复杂起来,难免满屏都是findViewById代码,功能类似,繁复。那有没有办法避免写一大堆的findViewById代码呢?答案肯定是有的。开源框架butterknife、ViewBinding、DataBin ding等都可以彻底解决这个问题。如果仅仅只是干掉findViewById,显得有点大材小用了。现在我们基于butterknife原理实现替代findViewById的工具类。
首先,我们需要定义一个注解。由于是作用于成员变量的,所以@Target值应该为ElementType.FIELD。要实现在运行时获取到控件ID并且赋值的目的,则@Retention必须为RetentionPolicy.RUNTIME。由于value()只接受控件ID,所以应该给value()加上@IdRes声明。具体代码如下:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewFinds {
@IdRes int value();
}
定义好了注解之后,我们还需要定义工具类。这里我们仅仅以Activity为例子:
public class ViewFindUtil {
public static void find(Activity activity) {
Class<? extends Activity> cls = activity.getClass();
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(ViewFinds.class)) {
ViewFinds viewFinds = field.getAnnotation(ViewFinds.class);
int viewId = viewFinds.value();
View view = activity.findViewById(viewId);
field.setAccessible(true);
try {
field.set(activity, view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
现在注解和工具类都定义好了,我们来试试效果。先定义一个页面activity_main和一个MainActivity:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@ViewFinds(R.id.btn_ok)
private Button btn_ok;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewFindUtil.find(this);
btn_ok.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Toast.makeText(this, "Success!", Toast.LENGTH_SHORT).show();
}
}
最终测试成功,图片就不贴出来了。
|