前言:
獲取控件是入門的基本的,相信這個(gè)不用說就知道怎么得到資源文件中的控件id
- 有findViewbyid
- 有注解方式
- 反射的方式
通過findViewbyid獲取
-
原理
我們點(diǎn)擊進(jìn)入Activity.java類中看源碼,通過源碼我們發(fā)現(xiàn)返回的是getWindow.findViewById,這個(gè)window是什么呢?我們?cè)俅吸c(diǎn)擊進(jìn)去看看,
···
/**
* 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);
}
···
- 進(jìn)入window發(fā)現(xiàn)是window,window是一個(gè)抽象類,window不能實(shí)現(xiàn)UI界面,那么這個(gè)getDecorView()返回的是一個(gè)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包就行了
//只需要在每個(gè)ID上設(shè)置對(duì)應(yīng)的注解即可
@BindView(R.id.img1)
private ImageView img1;`對(duì)沒有看錯(cuò)就是這么簡單
再來看看反射獲取的
/**
* 使用java反射機(jī)制
* 設(shè)置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();
}
}
//這是我項(xiàng)目中封裝在BaseActivity的,可以直接在BaseActivity中放在onCreate就行了,具體的看自己BaseActivity怎么封裝了0.0
那么在Activity或者fragment中怎么使用的呢,很簡單、個(gè)人覺得比findViewbyid和注解bindView方便多了,只需要跟布局文件中的id相同就行了,有點(diǎn)類似kotlin那樣,不過還是沒有kotlin Android那樣簡潔方便
end