前言:
获取控件是入门的基本的,相信这个不用说就知道怎么得到资源文件中的控件id
有findViewbyid
有注解方式
反射的方式
通过findViewbyid获取
原理
我们点击进入Activity.java类中看源码,通过源码我们发现返回的是getWindow.findViewById,这个window是什么呢?我们再次点击进去看看,
···
/**
* Finds a view that was identified by the id attribute from the XML that
* was processed in {@link #onCreate}.
*
* @return The view if found or null otherwise.
*/
@Nullable
public View findViewById(@IdRes int id) {
return getWindow().findViewById(id);
}
···
进入window发现是window,window是一个抽象类,window不能实现UI界面,那么这个getDecorView()返回的是一个VIew来管理Activity UI界面的
/**
* Finds a view that was identified by the id attribute from the XML that
* was processed in {@link android.app.Activity#onCreate}. This will
* implicitly call {@link #getDecorView} for you, with all of the
* associated side-effects.
*
* @return The view if found or null otherwise.
*/
@Nullable
public View findViewById(@IdRes int id) {
return getDecorView().findViewById(id);
}
//通过findViewbyid获取布局文件中的id
TextView tv=(TextView)findViewbyid(R.id.text);//
接下来我们看看注解方式
通过在线引用butterknife jar包就行了
//只需要在每个ID上设置对应的注解即可
@BindView(R.id.img1)
private ImageView img1;`对没有看错就是这么简单
再来看看反射获取的
/**
* 使用java反射机制
* 设置Activity不用findViewbyid
*/
private void smartInject() {
try {
Class extends Activity> clz = getClass();
while (clz != BaseActivity.class) {
Field[] fs = clz.getDeclaredFields();
Resources res = getResources();
String packageName = getPackageName();
for (Field field : fs) {
if (!View.class.isAssignableFrom(field.getType())) {
continue;
}
int viewId = res.getIdentifier(field.getName(), "id", packageName);
if (viewId == 0)
continue;
field.setAccessible(true);
try {
View v = findViewById(viewId);
field.set(this, v);
Class> c = field.getType();
Method m = c.getMethod("setOnClickListener", View.OnClickListener.class);
m.invoke(v, this);
} catch (Throwable e) {
}
field.setAccessible(false);
}
clz = (Class extends Activity>) clz.getSuperclass();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//这是我项目中封装在BaseActivity的,可以直接在BaseActivity中放在onCreate就行了,具体的看自己BaseActivity怎么封装了0.0
那么在Activity或者fragment中怎么使用的呢,很简单、个人觉得比findViewbyid和注解bindView方便多了,只需要跟布局文件中的id相同就行了,有点类似kotlin那样,不过还是没有kotlin Android那样简洁方便
end