4

我使用ActionbarSherlock和SlidingMenu。自定義Android TabHost慢片段

我的MainActivity不訪問數據庫,也沒有解析任何事情。一切都是靜態的。

根據您從SlidingMenu中選擇的「部分」動態生成標籤。 2次點擊後,該應用程序變得非常慢。

以下是我的主要觀點。

<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> 

使用的代碼管理Tabhost &片段:

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

@Marko答案並不差,我只是碰巧找到了'真正'的罪魁禍首。我將探索Marko指出的道路。

我發現在SlidingMenu適配器裏面有一個ViewBadger(lib),它沒有被正確地重用,每次我們改變片段時都會創建視圖。

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

您繼續UIThread你的整個工作,因此你最終在響應速度慢絆倒(例如,這是原因之一在最新的Android操作系統上禁止在UI線程上進行聯網)。嘗試改變你的概念一點點,並在不同線程的後臺做標籤創建。或者至少鎖定用戶界面並在您完成工作時顯示等待對話框,以便用戶獲得適當的用戶界面體驗。

希望這有助於和享受你的工作。