Custom Android TabHost Slow Fragments

≯℡__Kan透↙ 提交于 2019-12-23 12:29:26

问题


I use ActionbarSherlock and SlidingMenu.

My MainActivity does not access a DB and no Parsing of what ever. Everything is static.

Tabs are generated dynamicly depending on the "Section" you choose from the SlidingMenu. After 2 click the app becomes awefully slow.

Below is my main view.

    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >

            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal" />

            <FrameLayout
                android:id="@+id/content_frame"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:background="#0000FF" >
            </FrameLayout>

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="0dp"
                android:layout_height="0dp" >

            </FrameLayout>

        </LinearLayout>
    </TabHost>

</LinearLayout>

The code used to manage Tabhost & Fragments :

public void selectPage(MenuPageItem page, Page subNavigationPage) {
    if (page == null || subNavigationPage == null
            || (page.equals(selectedPage) && subNavigationPage.equals(selectedSubNavigation))) {
        return;
    }
    Log.d(TAG, "Show the page: " + page.getTitle() + " / subNavigationPage: " + subNavigationPage.getTitle());

    boolean needUpdateTabUI = !(page.equals(selectedPage));
    selectedPage = page;
    selectedSubNavigation = subNavigationPage;

    // 1) Manage tabHost
    if (needUpdateTabUI) {
        Log.d(TAG, "need to update tab layout");
        updatePageTabUI();
    }
    // Change selected tab
    mTabHost.setCurrentTabByTag(selectedSubNavigation.getTitle());

    // 2) Change Contentfragment
    Log.d(TAG, "update fragment");
    // TODO: check the current fragment is not already the good one and just
    // call its updateData method
    updatePageFragment();

    // Close the sliding menu if opened
    if (getSlidingMenu().isShown()) {
        Handler h = new Handler();

        h.postDelayed(new Runnable() {
            public void run() {
                getSlidingMenu().showContent();
            }
        }, 50);
    }
}

private void updatePageTabUI() {
    if (selectedPage.getPages().size() > 1) {
        // More than one sub navigation -> show the tab host
        // mTabHost.setVisibility(View.VISIBLE);
        mTabHost.setup();
        mTabHost.clearAllTabs();
        int i = 0;
        for (final Page subnav : selectedPage.getPages()) {
            Log.d(TAG, "add tab tag=" + subnav.getTitle() + " title=" + subnav.getTitle());
            mTabHost.addTab(mTabHost.newTabSpec(subnav.getTitle()).setIndicator(subnav.getTitle())
                    .setContent(new EmptyTabFactory()));
            mTabHost.getTabWidget().getChildAt(i).setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    selectPage(selectedPage, subnav);
                }
            });
            i++;
        }

    } else {
        // Only one sub navigation -> hide the tab host
        // mTabHost.setVisibility(View.GONE);
        mTabHost.setup();
        mTabHost.clearAllTabs();
    }
    mTabHost.requestLayout();
    mTabHost.invalidate();
}

private void updatePageFragment() {
    try {
        PageFragment fragContent = (PageFragment) selectedSubNavigation.getFragmentClass().newInstance();
        fragContent.setSubNavigationPage(selectedSubNavigation);
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.content_frame, fragContent);
        fragmentTransaction.commit();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

回答1:


You keep your entire work on UIThread and therefore you eventually stumble upon slow response (For example this is one of the reasons why it is forbidden on latest Android OS to do networking on UI thread). Try changing your concept a little bit and do your tab creation in background on different thread. Or at least lock UI and show wait dialog when you do your work in order for user to have proper UI experience.

Hope this helps and enjoy your work.




回答2:


@Marko answer isn't bad, I just happen to found the 'real' culprit. I will be exploring the path Marko pointed out.

What I found is that inside SlidingMenu adapter we had a ViewBadger (lib) and it wasn't re-used properly, creating views each time we change fragment.

BadgeView b = new BadgeView(getActivity(), holder.icon);
holder.badger = b;
convertView.setTag(holder);


来源:https://stackoverflow.com/questions/16545655/custom-android-tabhost-slow-fragments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!