尝试通过扩展自定义重用工具栏时应用程序崩溃 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;
    }