0

我試着去實現福爾摩斯抽屜式導航SherlockNavigationDrawer執行問題

GITHUB LINK

到我的項目,但有一些問題IM。解決大部分問題後,現在我在啓動活動時收到非法狀態異常。我不知道爲什麼。

02-05 15:09:32.994: E/AndroidRuntime(28194): FATAL EXCEPTION: main 
02-05 15:09:32.994: E/AndroidRuntime(28194): Process: com.uy.cocoapp, PID: 28194 
02-05 15:09:32.994: E/AndroidRuntime(28194): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.uy.cocoapp/com.uy.cocoapp.DrawerActivity}: java.lang.IllegalStateException: MainFragment must be attached to a SherlockFragmentActivity. 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2269) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.app.ActivityThread.access$800(ActivityThread.java:139) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.os.Handler.dispatchMessage(Handler.java:102) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.os.Looper.loop(Looper.java:136) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.app.ActivityThread.main(ActivityThread.java:5102) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at java.lang.reflect.Method.invokeNative(Native Method) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at java.lang.reflect.Method.invoke(Method.java:515) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at dalvik.system.NativeStart.main(Native Method) 
02-05 15:09:32.994: E/AndroidRuntime(28194): Caused by: java.lang.IllegalStateException: MainFragment must be attached to a SherlockFragmentActivity. 
02-05 15:09:32.994: E/AndroidRuntime(28194): at com.actionbarsherlock.app.SherlockFragment.onAttach(SherlockFragment.java:25) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:883) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:570) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1194) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.app.Activity.performStart(Activity.java:5258) 
02-05 15:09:32.994: E/AndroidRuntime(28194): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2182) 
02-05 15:09:32.994: E/AndroidRuntime(28194): ... 11 more 

從GitHub上提供的示例中,我改變了佈局,替換TextView的用於幀

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/drawer_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <FrameLayout 
     android:id="@+id/drawer_content_frame" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

    <ListView android:id="@+id/left_drawer" 
       android:layout_width="300dp" 
       android:layout_height="match_parent" 
       android:layout_gravity="left" 
       android:background="@android:color/white"/> 
</android.support.v4.widget.DrawerLayout> 

,這是MainFragment類,我還修改,所以我可以處理多個片段(IM從標籤切換到這一點,這就是爲什麼他們被稱爲TabFragment)

public class MainFragment extends SherlockFragment { 

    TabFragment1 fragment1; 
    TabFragment2 fragment2; 
    TabFragment3 fragment3; 

    private DrawerLayout mDrawerLayout; 
    private ListView listView; 
    //private TextView mContent; 

    private ActionBarHelper mActionBar; 

    private SherlockActionBarDrawerToggle mDrawerToggle; 

    public static Fragment newInstance() { 
     Fragment f = new MainFragment(); 
     return f; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     fragment1 = new TabFragment1(); 
     fragment2 = new TabFragment2(); 
     fragment3 = new TabFragment3(); 

     setRetainInstance(true); 
     setHasOptionsMenu(true); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.activity_drawer, container, false); 

     mDrawerLayout = (DrawerLayout) view.findViewById(R.id.drawer_layout); 
     listView = (ListView) view.findViewById(R.id.left_drawer); 
     //mContent = (TextView) view.findViewById(R.id.content_text); 

     mDrawerLayout.setDrawerListener(new DemoDrawerListener()); 
     mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); 

     String[] TITLES = { 
       "Tu Codigo", 
       "Locales", 
       "Mapa",  
       "FAQ", 
       "Terms & Cond", 
       "Cerrar Sesion" 
     }; 

     listView.setAdapter(new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_list_item_1, TITLES)); 
     listView.setOnItemClickListener(new DrawerItemClickListener()); 
     listView.setCacheColorHint(0); 
     listView.setScrollingCacheEnabled(false); 
     listView.setScrollContainer(false); 
     listView.setFastScrollEnabled(true); 
     listView.setSmoothScrollbarEnabled(true); 

     mActionBar = createActionBarHelper(); 
     mActionBar.init(); 

     // ActionBarDrawerToggle provides convenient helpers for tying together 
     // the 
     // prescribed interactions between a top-level sliding drawer and the 
     // action bar. 
     mDrawerToggle = new SherlockActionBarDrawerToggle(this.getActivity(), mDrawerLayout, R.drawable.ic_drawer_light, R.string.drawer_open, R.string.drawer_close); 
     mDrawerToggle.syncState(); 
     return view; 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     inflater = ((SherlockFragmentActivity)getActivity()).getSupportMenuInflater(); 
     inflater.inflate(R.menu.main, menu); 
     super.onCreateOptionsMenu(menu, inflater); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     /* 
     * The action bar home/up action should open or close the drawer. 
     * mDrawerToggle will take care of this. 
     */ 
     if (mDrawerToggle.onOptionsItemSelected(item)) { 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
     super.onConfigurationChanged(newConfig); 
     mDrawerToggle.onConfigurationChanged(newConfig); 
    } 

    /** 
    * This list item click listener implements very simple view switching by 
    * changing the primary content text. The drawer is closed when a selection 
    * is made. 
    */ 
    private class DrawerItemClickListener implements ListView.OnItemClickListener { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      //hacer switch con position e ir cambiando 

      selectItem(position); 

      mDrawerLayout.closeDrawer(listView); 
     } 
    } 

    private void selectItem(int position) { 

     FragmentTransaction ft = getSherlockActivity().getSupportFragmentManager().beginTransaction(); 
     // Locate Position 
     switch (position) { 
     case 0: 
      ft.replace(R.id.drawer_content_frame, fragment1, "TabFragment1"); 
      ft.addToBackStack("TabFragment1"); 
      break; 
     case 1: 
      ft.replace(R.id.drawer_content_frame, fragment2, "TabFragment2"); 
      ft.addToBackStack("TabFragment2"); 
      break; 
     case 2: 
      ft.replace(R.id.drawer_content_frame, fragment3, "TabFragment3"); 
      ft.addToBackStack("TabFragment3"); 
      break; 
     } 
     ft.commit(); 
     mDrawerLayout.closeDrawer(listView); 
    } 


    /** 
    * A drawer listener can be used to respond to drawer events such as 
    * becoming fully opened or closed. You should always prefer to perform 
    * expensive operations such as drastic relayout when no animation is 
    * currently in progress, either before or after the drawer animates. 
    * 
    * When using ActionBarDrawerToggle, all DrawerLayout listener methods 
    * should be forwarded if the ActionBarDrawerToggle is not used as the 
    * DrawerLayout listener directly. 
    */ 
    private class DemoDrawerListener implements DrawerLayout.DrawerListener { 
     @Override 
     public void onDrawerOpened(View drawerView) { 
      mDrawerToggle.onDrawerOpened(drawerView); 
      mActionBar.onDrawerOpened(); 
     } 

     @Override 
     public void onDrawerClosed(View drawerView) { 
      mDrawerToggle.onDrawerClosed(drawerView); 
      mActionBar.onDrawerClosed(); 
     } 


     @Override 
     public void onDrawerSlide(View drawerView, float slideOffset) { 
      mDrawerToggle.onDrawerSlide(drawerView, slideOffset); 
     } 

     @Override 
     public void onDrawerStateChanged(int newState) { 
      mDrawerToggle.onDrawerStateChanged(newState); 
     } 
    } 

    /** 
    * Create a compatible helper that will manipulate the action bar if 
    * available. 
    */ 
    private ActionBarHelper createActionBarHelper() { 
     return new ActionBarHelper(); 
    } 



    private class ActionBarHelper { 
     private final ActionBar mActionBar; 
     private CharSequence mDrawerTitle; 
     private CharSequence mTitle; 

     private ActionBarHelper() { 
      mActionBar = ((SherlockFragmentActivity)getActivity()).getSupportActionBar(); 
     } 

     public void init() { 
      mActionBar.setDisplayHomeAsUpEnabled(true); 
      mActionBar.setHomeButtonEnabled(true); 
      mTitle = mDrawerTitle = getActivity().getTitle(); 
     } 

     /** 
     * When the drawer is closed we restore the action bar state reflecting 
     * the specific contents in view. 
     */ 
     public void onDrawerClosed() { 
      mActionBar.setTitle(mTitle); 
     } 

     /** 
     * When the drawer is open we set the action bar to a generic title. The 
     * action bar should only contain data relevant at the top level of the 
     * nav hierarchy represented by the drawer, as the rest of your content 
     * will be dimmed down and non-interactive. 
     */ 
     public void onDrawerOpened() { 
      mActionBar.setTitle(mDrawerTitle); 
     } 

     public void setTitle(CharSequence title) { 
      mTitle = title; 
     } 
    } 

} 

感謝

回答

1

logcat說:

引起:java.lang.IllegalStateException:MainFragment必須連接到SherlockFragmentActivity。

即,您的活動必須延長SherlockFragmentActivity

+0

神智障礙者。我沒有複製粘貼全班,忘了班級聲明。 9小時的節目會殺死你。謝謝 – klifa

+0

我有另一個問題,你知道,與該代碼,爲什麼即時切換片段,似乎應用程序凍結了一秒。並且片段切換 - 抽屜關閉並不流暢 – klifa

+1

我首先啓用[StrictMode](http://developer.android.com/reference/android/os/StrictMode.html),並確保您沒有做任何事情在UI線程上長時間運行的操作。除此之外,在您運行碎片事務的同時抽屜關閉的轉換在系統上可能會很費勁 - 我使用的一種技術是保存待選項選擇,觸發抽屜關閉,然後使用[DrawerListener ](http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.DrawerListener.html)實際上改變'onDrawerClosed'內容' – ianhanniballake