尝试通过扩展自定义重用工具栏时应用程序崩溃 activity
App crashes when trying to reuse toolbar by extending custom activity
我的自定义工具栏在toolbar_main.xml
中描述如下
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/app_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="@color/white"
android:textSize="40dp"
/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
它是从 activity_main.xml
和
调用的
<include
layout="@layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
在我的 MainActivity.OnCreate()
中,我将工具栏设置为操作栏并执行一些操作
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.ic_logo_linkshare);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
Typeface ralewaySemiBold = Typeface.createFromAsset(getAssets(), "Raleway-SemiBold.ttf");
Typeface ralewayItalic = Typeface.createFromAsset(getAssets(), "Raleway-Italic.ttf");
String text1 = "link";
String text2 = "share";
Spannable s = new SpannableString(text1+text2);
s.setSpan(new CustomTypefaceSpan(ralewaySemiBold), 0, text1.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
s.setSpan(new CustomTypefaceSpan(ralewayItalic), text1.length(), text1.length()+text2.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
TextView lettering = (TextView) findViewById(R.id.app_name);
lettering.setText(s);
因为我有一个 MainActivity
的自定义菜单(这与我想在其他活动中使用的菜单不同),我执行以下操作
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true; }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
[...]
}
}
因为我想在我的所有活动中显示这个工具栏(带有徽标和自定义标题)(但单独处理菜单)我考虑创建一个自定义 Activity 然后在我需要的地方扩展它.
public class MenuActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.ic_logo_linkshare);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
Typeface ralewaySemiBold = Typeface.createFromAsset(getAssets(), "Raleway-SemiBold.ttf");
Typeface ralewayItalic = Typeface.createFromAsset(getAssets(), "Raleway-Italic.ttf");
String text1 = "link";
String text2 = "share";
Spannable s = new SpannableString(text1+text2);
s.setSpan(new CustomTypefaceSpan(ralewaySemiBold), 0, text1.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
s.setSpan(new CustomTypefaceSpan(ralewayItalic), text1.length(), text1.length()+text2.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
TextView lettering = (TextView) findViewById(R.id.app_name);
lettering.setText(s);
}
}
基本上是从 MainActivity
移动设置代码,而不是扩展它
public class MainActivity extends MenuActivity
这导致我一启动应用程序就崩溃,logcat
中没有任何错误或警告
我是不是在做一些不应该做的事情?
--编辑1--
我发现如果我添加
<include
layout="@layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
到 activity_menu-xml
即:MenuActivity
的 xml,应用程序不会崩溃,但会显示一个空的工具栏
--编辑2--
> FATAL EXCEPTION: main
Process: com.dima.polimi.massimobortolamei.linkshare, PID: 17736
Theme: themes:{}
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dima.polimi.massimobortolamei.linkshare/com.dima.polimi.massimobortolamei.linkshare.activities.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setDisplayShowHomeEnabled(boolean)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setDisplayShowHomeEnabled(boolean)' on a null object reference
at com.dima.polimi.massimobortolamei.linkshare.activities.MenuActivity.onCreate(MenuActivity.java:23)
at com.dima.polimi.massimobortolamei.linkshare.activities.MainActivity.onCreate(MainActivity.java:94)
at android.app.Activity.performCreate(Activity.java:6251)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
您可能希望为工具栏包含项指定一个 ID。
<include
android:id="@+id/toolbar"
layout="@layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
而且您似乎缺少 MenuActivity
中的工具栏设置,这解释了 NullPointerException
setContentView(R.layout.activity_menu);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Find the view from the toolbar
TextView lettering = (TextView) toolbar.findViewById(R.id.app_name);
注意:一个好主意是制作一个 protected void setupToolbar()
方法,然后您可以通过继承将其隐藏在 MainActivity
之外。
public abstract class ToolbarActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutRes());
setupToolbar();
}
protected abstract int getLayoutRes();
protected void setupToolbar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Find the view from the toolbar
TextView lettering = (TextView) toolbar.findViewById(R.id.app_name);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.ic_logo_linkshare);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
Typeface ralewaySemiBold = Typeface.createFromAsset(getAssets(), "Raleway-SemiBold.ttf");
Typeface ralewayItalic = Typeface.createFromAsset(getAssets(), "Raleway-Italic.ttf");
String text1 = "link";
String text2 = "share";
Spannable s = new SpannableString(text1+text2);
s.setSpan(new CustomTypefaceSpan(ralewaySemiBold), 0, text1.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
s.setSpan(new CustomTypefaceSpan(ralewayItalic), text1.length(), text1.length()+text2.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
lettering.setText(s);
}
}
public class MainActivity extends ToolbarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected int getLayoutRes() {
return R.layout.activity_main;
}
我的自定义工具栏在toolbar_main.xml
中描述如下
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:minHeight="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/app_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="@color/white"
android:textSize="40dp"
/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
它是从 activity_main.xml
和
<include
layout="@layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
在我的 MainActivity.OnCreate()
中,我将工具栏设置为操作栏并执行一些操作
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.ic_logo_linkshare);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
Typeface ralewaySemiBold = Typeface.createFromAsset(getAssets(), "Raleway-SemiBold.ttf");
Typeface ralewayItalic = Typeface.createFromAsset(getAssets(), "Raleway-Italic.ttf");
String text1 = "link";
String text2 = "share";
Spannable s = new SpannableString(text1+text2);
s.setSpan(new CustomTypefaceSpan(ralewaySemiBold), 0, text1.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
s.setSpan(new CustomTypefaceSpan(ralewayItalic), text1.length(), text1.length()+text2.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
TextView lettering = (TextView) findViewById(R.id.app_name);
lettering.setText(s);
因为我有一个 MainActivity
的自定义菜单(这与我想在其他活动中使用的菜单不同),我执行以下操作
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true; }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
[...]
}
}
因为我想在我的所有活动中显示这个工具栏(带有徽标和自定义标题)(但单独处理菜单)我考虑创建一个自定义 Activity 然后在我需要的地方扩展它.
public class MenuActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.ic_logo_linkshare);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
Typeface ralewaySemiBold = Typeface.createFromAsset(getAssets(), "Raleway-SemiBold.ttf");
Typeface ralewayItalic = Typeface.createFromAsset(getAssets(), "Raleway-Italic.ttf");
String text1 = "link";
String text2 = "share";
Spannable s = new SpannableString(text1+text2);
s.setSpan(new CustomTypefaceSpan(ralewaySemiBold), 0, text1.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
s.setSpan(new CustomTypefaceSpan(ralewayItalic), text1.length(), text1.length()+text2.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
TextView lettering = (TextView) findViewById(R.id.app_name);
lettering.setText(s);
}
}
基本上是从 MainActivity
移动设置代码,而不是扩展它
public class MainActivity extends MenuActivity
这导致我一启动应用程序就崩溃,logcat
中没有任何错误或警告我是不是在做一些不应该做的事情?
--编辑1--
我发现如果我添加
<include
layout="@layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
到 activity_menu-xml
即:MenuActivity
的 xml,应用程序不会崩溃,但会显示一个空的工具栏
--编辑2--
> FATAL EXCEPTION: main
Process: com.dima.polimi.massimobortolamei.linkshare, PID: 17736
Theme: themes:{}
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dima.polimi.massimobortolamei.linkshare/com.dima.polimi.massimobortolamei.linkshare.activities.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setDisplayShowHomeEnabled(boolean)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setDisplayShowHomeEnabled(boolean)' on a null object reference
at com.dima.polimi.massimobortolamei.linkshare.activities.MenuActivity.onCreate(MenuActivity.java:23)
at com.dima.polimi.massimobortolamei.linkshare.activities.MainActivity.onCreate(MainActivity.java:94)
at android.app.Activity.performCreate(Activity.java:6251)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
您可能希望为工具栏包含项指定一个 ID。
<include
android:id="@+id/toolbar"
layout="@layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
而且您似乎缺少 MenuActivity
中的工具栏设置,这解释了 NullPointerException
setContentView(R.layout.activity_menu);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Find the view from the toolbar
TextView lettering = (TextView) toolbar.findViewById(R.id.app_name);
注意:一个好主意是制作一个 protected void setupToolbar()
方法,然后您可以通过继承将其隐藏在 MainActivity
之外。
public abstract class ToolbarActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutRes());
setupToolbar();
}
protected abstract int getLayoutRes();
protected void setupToolbar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Find the view from the toolbar
TextView lettering = (TextView) toolbar.findViewById(R.id.app_name);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.drawable.ic_logo_linkshare);
getSupportActionBar().setDisplayUseLogoEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
Typeface ralewaySemiBold = Typeface.createFromAsset(getAssets(), "Raleway-SemiBold.ttf");
Typeface ralewayItalic = Typeface.createFromAsset(getAssets(), "Raleway-Italic.ttf");
String text1 = "link";
String text2 = "share";
Spannable s = new SpannableString(text1+text2);
s.setSpan(new CustomTypefaceSpan(ralewaySemiBold), 0, text1.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
s.setSpan(new CustomTypefaceSpan(ralewayItalic), text1.length(), text1.length()+text2.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
lettering.setText(s);
}
}
public class MainActivity extends ToolbarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected int getLayoutRes() {
return R.layout.activity_main;
}