第一步: 自定义注解
package com
.example
.myapplication
.core
.annon
;
import java
.lang
.annotation
.*
;
@Target({ElementType
.TYPE
,ElementType
.FIELD
})
@Retention(RetentionPolicy
.RUNTIME
)
@Inherited
@Documented
public @
interface BindView {
int view();
}
package com
.example
.myapplication
.core
.annon
;
import java
.lang
.annotation
.*
;
@Target({ElementType
.FIELD
})
@Retention(RetentionPolicy
.RUNTIME
)
@Inherited
@Documented
public @
interface ViewModel {
}
第二步,使用模板方法 实现一个 BaseActivity
package com
.example
.myapplication
.core
;
import android
.os
.Bundle
;
import android
.util
.Log
;
import androidx
.annotation
.Nullable
;
import androidx
.databinding
.DataBindingUtil
;
import androidx
.lifecycle
.AndroidViewModel
;
import androidx
.lifecycle
.ViewModelProviders
;
import com
.example
.myapplication
.core
.annon
.BindView
;
import com
.example
.myapplication
.core
.annon
.ViewModel
;
import com
.example
.myapplication
.databinding
.ActivityMainBinding
;
import java
.lang
.reflect
.Field
;
public abstract class BaseAnnotationActivity extends BaseActivity {
protected ActivityMainBinding binding
;
protected int viewId
= -1;
@Override
protected final void onCreate(@Nullable Bundle savedInstanceState
) {
super.onCreate(savedInstanceState
);
initCustomView();
fieldAutoInject();
autoDataBind();
onCreateCustom();
}
private void initCustomView() {
BindView bindView
= this.getClass().getAnnotation(BindView
.class);
if (bindView
!= null
) {
this.viewId
= bindView
.view();
setContentView(viewId
);
}
}
private void fieldAutoInject() {
for (Field f
: getClass().getDeclaredFields()) {
f
.setAccessible(true);
BindView view
= f
.getAnnotation(BindView
.class);
if (view
!= null
) {
int id
= view
.view();
try {
f
.set(this, findViewById(id
));
} catch (IllegalAccessException e
) {
Log
.e("init error", "绑定视图出现了异常");
}
}
}
}
private void autoDataBind() {
for (Field f
: getClass().getDeclaredFields()) {
f
.setAccessible(true);
ViewModel viewModel
= f
.getAnnotation(ViewModel
.class);
Class
type = f
.getType();
if (viewModel
!= null
&& AndroidViewModel
.class.isAssignableFrom(type
)) {
try {
f
.set(this, ViewModelProviders
.of(this).get(type
));
AndroidViewModel vm
= (AndroidViewModel
) f
.get(this);
binding
= DataBindingUtil
.setContentView(this, viewId
);
setViewModel(binding
);
binding
.setLifecycleOwner(this);
} catch (Exception e
) {
Log
.e("bindView", "绑定数据异常");
}
break;
}
}
}
protected abstract void onCreateCustom();
protected abstract void setViewModel(ActivityMainBinding binding
);
}
示例代码
package com
.example
.myapplication
;
import android
.util
.Log
;
import android
.view
.View
;
import android
.widget
.Button
;
import android
.widget
.TextView
;
import com
.example
.myapplication
.core
.BaseAnnotationActivity
;
import com
.example
.myapplication
.core
.annon
.BindView
;
import com
.example
.myapplication
.databinding
.ActivityMainBinding
;
@BindView(view
= R
.layout
.activity_main
)
public class MainActivity extends BaseAnnotationActivity implements View.OnClickListener {
@BindView(view
= R
.id
.btn_clear
)
Button btnClear
;
@BindView(view
= R
.id
.username
)
TextView username
;
@BindView(view
= R
.id
.password
)
TextView password
;
@Override
protected void onCreateCustom() {
Log
.i("info", "on create ...");
Log
.i("info", btnClear
.toString());
Log
.i("info", username
.toString());
btnClear
.setOnClickListener(this);
}
@Override
protected void setViewModel(ActivityMainBinding binding
) {
}
@Override
public void onClick(View v
) {
switch (v
.getId()) {
case R
.id
.btn_clear
: {
Log
.i("click,trigger","设置焦点");
username
.setText("");
password
.setText("");
username
.requestFocus();
}
}
}
}
注意项
如果使用 DataBinding 的话,绑定事件的方法就不好用了,目前还没有办法解决这个问题