工具栏和导航抽屉
Posted
技术标签:
【中文标题】工具栏和导航抽屉【英文标题】:Toolbar and NavigationDrawer 【发布时间】:2014-12-23 22:28:45 【问题描述】:我正在尝试在使用 NavigationFragment 的现有项目中包含材料设计。
所以我尝试使用工具栏而不是操作栏。
我按照this 指导,将所有getActionBar()
替换为getSupportActionBar()
,但我的应用程序总是在启动时崩溃。
activity_main.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_
android:layout_
tools:context="com.andreapivetta.mypckg.MainActivity">
<FrameLayout
android:id="@+id/container"
android:layout_
android:layout_ />
<fragment
android:id="@+id/navigation_drawer"
android:name="com.andreapivetta.mypckg.NavigationDrawerFragment"
android:layout_
android:layout_
android:layout_gravity="start" />
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_
android:layout_
android:background="?attr/colorPrimaryDark"/>
</android.support.v4.widget.DrawerLayout>
主活动
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks
private NavigationDrawerFragment mNavigationDrawerFragment;
private CharSequence mTitle;
private static SharedPreferences mSharedPreferences;
static final String PREF_KEY_TWITTER_LOGIN = "isTwitterLogedIn";
static final String PREF_SELECTED_INDEX = "SELECTED_POSITION";
private ConnectionDetector connectionDetector;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null)
setSupportActionBar(toolbar);
mSharedPreferences = getSharedPreferences("MyPref", 0);
setContentView(R.layout.activity_main);
connectionDetector = new ConnectionDetector(this);
startService(new Intent(getApplicationContext(), StartupService.class));
@Override
public void onResume()
super.onResume();
if (isTwitterLoggedInAlready())
mNavigationDrawerFragment = (NavigationDrawerFragment)
getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
setDrawerLeftEdgeSize(this, mDrawerLayout, 0.3f);
mNavigationDrawerFragment.setUp(R.id.navigation_drawer, mDrawerLayout);
if (mSharedPreferences.getBoolean("FIRST_LAUNCH", true))
mSharedPreferences.edit().putBoolean("FIRST_LAUNCH", false).apply();
else
if (connectionDetector.isConnectingToInternet())
Fragment fragment = new LoginFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment).commit();
else
Toast.makeText(this, "internet connection required",
Toast.LENGTH_LONG).show();
@Override
public void onNavigationDrawerItemSelected(int position)
Fragment fragment;
FragmentManager fragmentManager = getSupportFragmentManager();
mSharedPreferences.edit().putInt(PREF_SELECTED_INDEX, position).apply();
switch (position)
case 0:
fragment = new MainFragment();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment).commit();
setTitle(getResources().getString(R.string.app_name));
break;
case 1:
...
case 2:
...
case 3:
...
@Override
public void setTitle(CharSequence title)
mTitle = title;
getSupportActionBar().setTitle(mTitle);
public void restoreActionBar()
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
日志
10-28 14:20:29.085 32367-32367/com.andreapivetta.mypckg E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.andreapivetta.mypckg, PID: 32367
java.lang.RuntimeException: Unable to start activity ComponentInfocom.andreapivetta.mypckg/com.andreapivetta.mypckg.MainActivity: android.view.InflateException: Binary XML file line #20: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(ActionBarActivityDelegateBase.java:228)
at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:102)
at com.andreapivetta.mypckg.MainActivity.onCreate(MainActivity.java:56)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
at com.andreapivetta.mypckg.MainActivity.setTitle(MainActivity.java:155)
at com.andreapivetta.mypckg.MainActivity.onNavigationDrawerItemSelected(MainActivity.java:128)
at com.andreapivetta.mypckg.NavigationDrawerFragment.selectItem(NavigationDrawerFragment.java:247)
at com.andreapivetta.mypckg.NavigationDrawerFragment.onCreate(NavigationDrawerFragment.java:93)
at android.app.Fragment.performCreate(Fragment.java:1678)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:859)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1040)
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1142)
at android.app.Activity.onCreateView(Activity.java:4786)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at android.support.v7.app.ActionBarActivityDelegateBase.setContentView(ActionBarActivityDelegateBase.java:228)
at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:102)
at com.andreapivetta.mypckg.MainActivity.onCreate(MainActivity.java:56)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
我做错了什么?
【问题讨论】:
你需要显示你的代码,特别是MainActivity.java:155
@tyczj 我刚刚添加了 MainActivity 最重要的部分
您在 MainActivity 中导入了哪个 Toolbar,android.support.v7.widget.Toolbar?
【参考方案1】:
在您的 onCreate
中,您从未在尝试访问工具栏视图之前设置内容
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null)
setSupportActionBar(toolbar);
mSharedPreferences = getSharedPreferences("MyPref", 0);
setContentView(R.layout.activity_main);
您需要先为您的活动设置内容,然后才能访问它
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null)
setSupportActionBar(toolbar);
mSharedPreferences = getSharedPreferences("MyPref", 0);
【讨论】:
谢谢,我改变了这个并删除了 ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true);从我的 NavigationDrawer 开始,现在应用程序不会崩溃,但工具栏的高度与屏幕相同:D 好吧,你的工具栏不应该放在DrawerLayout
中,它应该在外面。
你是对的。我现在无法测试我的代码,我会尽快将您的答案标记为正确
我在使用AndroidAnnotations 时遇到了同样的问题。必须为使用@ViewById 注入的视图定义一个方法并使用@AfterViews 对其进行注释,因为此类字段未在 onCreate() 方法中初始化【参考方案2】:
您必须按照 tyczy 的建议更改 onCreate() 方法中的代码。
您的布局存在另一个问题。 您在 DrawerLayout 中使用了 3 个视图,而您应该使用 2 个视图。
您必须更改布局,例如:
<android.support.v4.widget.DrawerLayout>
<LinearLayout>
<Toolbar..>
<FrameLayout
android:id="@+id/container"
android:layout_
android:layout_ />
</LinearLayout>
<fragment
android:id="@+id/navigation_drawer"
android:name="com.andreapivetta.mypckg.NavigationDrawerFragment"
android:layout_
android:layout_
android:layout_gravity="start" />
</DrawerLayout>
【讨论】:
是的,答案是正确的,但感谢 tyczj 的评论,我已经做到了:)【参考方案3】:我遇到了类似的问题。为我解决的问题是我将NavigationDrawerFragment
中的selectItem(..)
方法从onCreateView()
移动到onActivityCreated()
。
@Override
public void onActivityCreated(Bundle savedInstanceState)
selectItem(mCurrentSelectedPosition);
super.onActivityCreated(savedInstanceState);
【讨论】:
以上是关于工具栏和导航抽屉的主要内容,如果未能解决你的问题,请参考以下文章