Fragment模擬Tab以及簡單優化

一、前言
在郭霖大大的博客(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);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章