一、前言
在郭霖大大的博客(http://blog.csdn.net/guolin_blog/article/details/13171191)的基礎上試着進行代碼優化。
二、分析
有4個tab頁:message,contacts,news,setting。每個tab頁的點擊事件流程基本一致。相應的ui組件命名規則一致(都以tab名爲前綴)。
原文用switch語句寫了4遍點擊事件(作爲給新手看的教程無可厚非),作爲一個程序猿,試着來優化一下。
三、優化前準備
1 使用數組存放tab名,用到tab名的地方從數組取。
String tabs[] = {"message", "contacts", "news", "setting"};
2 ui組件也和tab名相關,怎麼根據數組tabs獲取ui呢?使用getResources().getIdentifier
(相比直接用findViewById耗費些許性能)
//name爲ui的id名,type傳入"id"
private View findView(String name, String type) {
int resId = getResources().getIdentifier(name, type, "com.shadow.zyw.sdu.fragmenttabs");
Log.d("test", "find view:" + name + resId);
View view = (View) findViewById(resId);
return view;
}
3 對於xml佈局文件和圖片資源等,需要用java發射機制
//mipmap下圖片資源id
private Integer findImage(String name) {
Integer value = null;
Class<R.mipmap> cls = R.mipmap.class;
try {
value = cls.getDeclaredField(name).getInt(null);
} catch (Exception e) {
Log.d("test", "findimage error" + name);
}
return value;
}
//返回佈局文件id
private Integer findLayout(String name) {
Integer value = null;
Class<R.layout> cls = R.layout.class;
try {
value = cls.getDeclaredField(name).getInt(null);
} catch (Exception e) {
Log.d("test", "findlayout error" + name);
}
return value;
}
四、優化開始
1 對於tabs綁定監聽器可以使用for循環
for (int i = 0; i < tabs.length; i++) {
View view = findView(tabs[i] + "_layout", "id");
view.setOnClickListener(this);
//將id和tas名保存,可以知道哪個控件被點擊
map.put(String.valueOf(view.getId()), tabs[i]);
}
2 fragment對象的生成:有2種方式
(1)使用java發射機制,動態根據類名生成對象
private static Object newInstance(String className) throws Exception {
//類名首字母大寫
StringBuilder sb = new StringBuilder(className);
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
className = sb.toString();
Log.d("test", "classname:" + className);
Class clazz = Class.forName("com.shadow.zyw.sdu.fragmenttabs." + className);
return clazz.newInstance();
}
fragment = (Fragment) newInstance(name + "Frag");
(2)在fragment的onCreateView中根據tabs名,引入不同的佈局文件。(感覺這樣靈活性很差,這裏只是練手,擴展思路)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(findLayout(xml), container, false);
Log.d("test", "frag create" + xml);
return view;
}
fragObject = new FragObject();
fragObject.setXml(name + "_layout");
3 onclick事件
@Override
public void onClick(View v) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Log.d("test", String.valueOf(v.getId()));
String name = map.get(String.valueOf(v.getId()));
Log.d("test", "name" + name);
fragObject = new FragObject();
fragObject.setXml(name + "_layout");
try {
fragment = (Fragment) newInstance(name + "Frag");
} catch (Exception e) {
e.printStackTrace();
Log.d("test", "cannot create class:" + name);
return;
}
ImageView imageView = (ImageView) findView(name + "_image", "id");
imageView.setImageResource(findImage(name + "_selected"));
TextView textView = (TextView) findView(name + "_text", "id");
textView.setTextColor(Color.WHITE);
fragmentTransaction.add(R.id.content, fragment);
// fragmentTransaction.add(R.id.content, fragObject);
fragmentTransaction.commit();
}
4 判斷是否已經產生過fragment,清空fragment等,使用Map保存fragment對象
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (fragmentMap.get(name) == null) {
try {
fragment = (Fragment) newInstance(name + "Frag");
fragInterface = (FragInterface) newInstance(name + "Frag");
} catch (Exception e) {
e.printStackTrace();
Log.d("test", "cannot create class:" + name);
return;
}
fragmentMap.put(name, fragment);
fragmentTransaction.add(R.id.content, fragment);
} else {
fragment = fragmentMap.get(name);
fragmentTransaction.show(fragment);
}
fragmentTransaction.commit();
5 清空點擊狀態
private void clearSelected() {
for (int i = 0; i < tabs.length; i++) {
ImageView imageView = (ImageView) findView(tabs[i] + "_image", "id");
imageView.setImageResource(findImage(tabs[i] + "_unselected"));
TextView textView = (TextView) findView(tabs[i] + "_text", "id");
textView.setTextColor(Color.parseColor("#82858b"));
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (fragmentMap.get(tabs[i]) != null) {
fragmentTransaction.hide(fragmentMap.get(tabs[i]));
}
fragmentTransaction.commit();
}
}
6 優化後
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getFragmentManager();
for (int i = 0; i < tabs.length; i++) {
View view = findView(tabs[i] + "_layout", "id");
map.put(String.valueOf(view.getId()), tabs[i]);
view.setOnClickListener(this);
}
setSelected(tabs[0]);
}
@Override
public void onClick(View v) {
Log.d("test", String.valueOf(v.getId()));
String name = map.get(String.valueOf(v.getId()));
Log.d("test", "name" + name);
clearSelected();
setSelected(name);
}
private void clearSelected() {
for (int i = 0; i < tabs.length; i++) {
ImageView imageView = (ImageView) findView(tabs[i] + "_image", "id");
imageView.setImageResource(findImage(tabs[i] + "_unselected"));
TextView textView = (TextView) findView(tabs[i] + "_text", "id");
textView.setTextColor(Color.parseColor("#82858b"));
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (fragmentMap.get(tabs[i]) != null) {
fragmentTransaction.hide(fragmentMap.get(tabs[i]));
}
fragmentTransaction.commit();
}
}
private void setSelected(String name) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (fragmentMap.get(name) == null) {
try {
fragment = (Fragment) newInstance(name + "Frag");
fragInterface = (FragInterface) newInstance(name + "Frag");
} catch (Exception e) {
e.printStackTrace();
Log.d("test", "cannot create class:" + name);
return;
}
fragmentMap.put(name, fragment);
fragmentTransaction.add(R.id.content, fragment);
} else {
fragment = fragmentMap.get(name);
fragmentTransaction.show(fragment);
}
fragmentTransaction.commit();
ImageView imageView = (ImageView) findView(name + "_image", "id");
imageView.setImageResource(findImage(name + "_selected"));
TextView textView = (TextView) findView(name + "_text", "id");
textView.setTextColor(Color.WHITE);
}