Android SherlockNavigationDrawer实现问题
我正在尝试实现Sherlock导航抽屉 但是我有一些问题。在解决了大多数问题之后,现在我在启动活动时得到了非法状态异常。我不知道为什么Android SherlockNavigationDrawer实现问题,android,actionbarsherlock,navigation-drawer,android-navigation,Android,Actionbarsherlock,Navigation Drawer,Android Navigation,我正在尝试实现Sherlock导航抽屉 但是我有一些问题。在解决了大多数问题之后,现在我在启动活动时得到了非法状态异常。我不知道为什么 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/AndroidRunt
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类,我也修改了它,这样我就可以处理多个片段了(我把tabs改成了这个,这就是为什么它们被称为TabFragment)
public类MainFragment扩展了SherlockFragment{
TabFragment1 fragment1;
TabFragment2 fragment2;
TabFragment3 fragment3;
私人抽屉布局mDrawerLayout;
私有列表视图列表视图;
//私有文本视图mContent;
私人ActionBarHelper mActionBar;
私人夏洛克行动律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所律师事务所;
公共静态片段newInstance(){
片段f=新的MainFragment();
返回f;
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
fragment1=新选项卡fragment1();
fragment2=新选项卡fragment2();
fragment3=新选项卡fragment3();
setRetainInstance(真);
设置选项菜单(真);
}
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
视图=充气机。充气(R.layout.activity\u抽屉,容器,假);
mDrawerLayout=(抽屉布局)视图.findViewById(R.id.drawer\u布局);
listView=(listView)view.findViewById(R.id.left\u抽屉);
//mContent=(TextView)view.findViewById(R.id.content\u text);
setDrawerLayout.setDrawerListener(新的DestrawerListener());
mDrawerLayout.setDrawerShadow(R.drawable.drawer\u shadow,GravityCompat.START);
字符串[]标题={
“Tu Codigo”,
“地区”,
“Mapa”,
“常见问题”,
“条款与条件”,
“Cerrar Sesion”
};
setAdapter(新的ArrayAdapter(this.getActivity(),android.R.layout.simple_list_item_1,TITLES));
setOnItemClickListener(新的DroperItemClickListener());
setCacheColorHint(0);
listView.SetScrolingCacheEnabled(false);
setScrollContainer(false);
setFastScrollEnabled(true);
listView.setSmoothScrollbarEnabled(true);
mActionBar=createActionBarHelper();
mActionBar.init();
//ActionBarDrawerToggle为捆绑在一起提供了方便的帮助
//
//顶层滑动抽屉和
//动作条。
mDrawerToggle=新的SherlockActionBarDrawerToggle(this.getActivity(),mDrawerLayout,R.drawable.ic_drawer_light,R.string.drawer_open,R.string.drawer_close);
mDrawerToggle.syncState();
返回视图;
}
@凌驾
创建选项菜单(菜单菜单,菜单充气机){
充气器=((SherlockFragmentActivity)getActivity()).getSupportMenuInflater();
充气机。充气(右菜单。主菜单,菜单);
super.onCreateOptions菜单(菜单,充气机);
}
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
/*
*操作栏home/up操作应打开或关闭抽屉。
*mDrawerToggle会处理这个问题。
*/
如果(MDRAWERTOGLE.onOptionsItemSelected(项目)){
返回true;
}
返回super.onOptionsItemSelected(项目);
}
@凌驾
公共无效OnConfiguration已更改(配置newConfig){
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
/**
*此列表项单击侦听器通过以下方式实现非常简单的视图切换
*更改主要内容文本。选择时抽屉关闭
*是制造的。
*/
私有类DrawerItemClickListener实现ListView.OnItemClickListener{
@凌驾
public void onItemClick(AdapterView父对象、视图、整型位置、长id){
//空调开关位置e ir cambiando
选择项目(位置);
mDrawerLayout.closeDrawer(listView);
}
}
私有void selectItem(内部位置){
FragmentTransaction ft=getSherlockActivity().getSupportFragmentManager().beginTransaction();
//定位
开关(位置){
案例0:
ft.replace(R.id.抽屉内容框架,碎片1,“标签碎片1”);
ft.addToBackStack(“TabFragment1”);
打破
案例1:
ft.replace(R.id.抽屉内容框架,碎片2,“标签碎片2”);
ft.addToBackStack(“TabFragment2”);
打破
案例2:
ft.replace(R.id.抽屉内容框架,碎片3,“标签碎片3”);
ft.addToBackStack(“TabFragment3”);
打破
}
ft.commit();
mDrawerLayout.closeDrawer(listView);
}
/**
*抽屉侦听器可用于响应抽屉事件,例如
*完全打开或关闭。您应该始终更喜欢执行
*昂贵的操作,例如在没有动画时进行剧烈的重新播放
*当前正在进行中,在抽屉设置动画之前或之后。
*
*使用ActionBarDrawerToggle时,所有抽屉布局侦听器方法
*如果ActionBarDrawerToggle未用作
*直接使用抽屉布局侦听器。
*/
私有类DestrawerListener实现了DroperLayout.DroperListener{
@凌驾
打开图纸上的公共空白(视图抽屉视图){
mDrawerToggle.onDrawerOpened(抽屉视图);
mActionBar.onDrawerOpened();
}
@凌驾
图纸上的公共空白已关闭(视图抽屉视图){
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;
}
}
}