Appbar /工具栏不起作用

时间:2016-04-21 15:34:11

标签: java android xml

我通过针对api 13+制作一个android项目。我需要在我的应用中的每个活动的顶部都有一个appbar /工具栏而不是操作栏。我试过搜索过许多博客和SO本身但没有任何成功。

我创建了一个基本活动类,我的所有活动都继承自这个类:

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.support.v7.widget.Toolbar;


public class BaseActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Toolbar tb = (Toolbar) findViewById(R.id.appToolbar);
        setSupportActionBar(tb);
        getSupportActionBar().setDisplayShowTitleEnabled(true);
        getSupportActionBar().setTitle("oh yeah");
    }
    ...
}

我已经为这个类中的工具栏完成了内务管理工作,下面的类是应用程序启动时显示的活动:

import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;


public class SplashScreen extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // api level < 16 and > 16 have different
        // ways of removing the status bar
        if(Build.VERSION.SDK_INT < 16) {
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        } else {
            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
        }
        setContentView(R.layout.activity_splash_screen);

        // Create a new thread and delay for 3 sec
        // to handle the start of the main screen.
        Handler h = new Handler();
        h.postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent i = new Intent().setClass(getApplicationContext(), MainScreen.class);
                startActivity(i);
            }
        }, 3000);
    }

这是在启动画面后启动的活动:

import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;


public class MainScreen extends BaseActivity {

    private ImageButton btnLoyaltyForm;
    private ImageButton btnFeedbackForm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_screen);

        btnLoyaltyForm = (ImageButton) findViewById(R.id.btnLoyaltyForm);
        btnFeedbackForm = (ImageButton) findViewById(R.id.btnFeedbackForm);

        btnLoyaltyForm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent().setClass(getApplicationContext(), LoyaltyFormScreen.class);
                startActivity(i);
            }
        });

        btnFeedbackForm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent().setClass(getApplicationContext(), FeedbackFormScreen.class);
                startActivity(i);
            }
        });
    }
}

以下是我的appbar的XML:

<android.support.v7.widget.Toolbar

android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/actionbar_background_color"
android:minHeight="?attr/actionBarSize"
xmlns:android="http://schemas.android.com/apk/res/android" />

以下是我的MainScreen活动的XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context="com.tarz.MainScreen">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <include
        android:id="@+id/appToolbar"
        layout="@layout/app_bar" />

    </LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="false"
        android:layout_alignParentBottom="false"
        android:layout_alignWithParentIfMissing="false"
        android:gravity="center">

        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btnLoyaltyForm"
            android:layout_gravity="center_horizontal"
            android:src="@drawable/btn_form1" />

        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btnFeedbackForm"
            android:layout_gravity="center"
            android:src="@drawable/btn_form2" />
    </LinearLayout>

</RelativeLayout>

这是我的应用程序的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tarz" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".SplashScreen"
            android:label="@string/title_activity_splash_screen" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainScreen"
            android:label="@string/title_activity_main_screen" >
        </activity>
        <activity
            android:name=".BaseActivity"
            android:label="@string/title_activity_base" >
        </activity>
    </application>

</manifest>

这是我的colors.xml:

n="1.0" encoding="utf-8"?>
<resources>
    <color name="actionbar_background_color">#2d3135</color>
    <color name="actionbar_text_color">#ffffff</color>
    <color name="app_background_color">#f7f6f0</color>
    <color name="button_background_color">#2d3135</color>
    <color name="button_text_color">#ffffff</color>
</resources>

这是我的styles.xml:

<resources xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="android:background">@color/app_background_color</item>
        <!--<item name="colorPrimaryDark">@color/colorPrimaryDark</item>-->
        <!--<item name="colorAccent">@color/colorAccent</item>-->
    </style>

    <style name="ActionBarTheme" parent="ThemeOverlay.AppCompat.ActionBar">
        <item name="android:background">@color/actionbar_background_color</item>
        <item name="colorPrimary">@color/actionbar_background_color</item>
    </style>

</resources>

当我运行应用程序时,启动画面会显示,然后崩溃并出现以下错误:

java.lang.NullPointerException:尝试调用虚方法&#39; void android.support.v7.app.ActionBar.setDisplayShowTitleEnabled(boolean)&#39;在空对象引用上

java.lang.NullPointerException:尝试调用虚方法&#39; void android.support.v7.app.ActionBar.setDisplayShowTitleEnabled(boolean)&#39;在空对象引用上

这是日志:

4059-4059/com.tarz E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.tarz, PID: 4059
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tarz/com.tarz.MainScreen}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setDisplayShowTitleEnabled(boolean)' on a null object reference
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            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.setDisplayShowTitleEnabled(boolean)' on a null object reference
            at com.tarz.MainScreen.onCreate(MainScreen.java:28)
            at android.app.Activity.performCreate(Activity.java:6237)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            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)

如何使用我在colors.xml中定义的颜色,以便我的工具栏可以有不同的颜色,我的应用程序可以有不同的颜色,我的工具栏的文本可以有不同的颜色。

此外,每个活动的菜单会有所不同,因此工具栏应根据活动进行调整,我该怎么办呢?

请帮助,谢谢。 :)

编辑1:

@Rod表示在设置contentView后初始化工具栏后,它清除了NPE但是没有显示工具栏:

enter image description here

此方法添加在BaseActivity类的顶部:

public void initToolbar() {
    Toolbar tb = (Toolbar) findViewById(R.id.appToolbar);
    setSupportActionBar(tb);
    getSupportActionBar().setDisplayShowTitleEnabled(true);
    getSupportActionBar().setTitle("oh yeah");
}

并且onCreate现在只有超级调用。此外,MainScreen类现在initToolbar();setContentView();方法中调用了onCreate();

1 个答案:

答案 0 :(得分:0)

我要指出的一些事情:

  1. 您没有在onCreate() {/ 1}} BaseActivity中夸大布局
  2. 我认为官方工具栏教程都使用AppCompatActivity而不是ActionBarActivity
  3. 您可以定义不同的工具栏主题并将其应用于不同的活动。更多信息here
  4. 每个活动都有自己的工具栏,因此您不必担心为每个活动支持不同的菜单。您只需为onCreateOptionsMenu()中的活动扩充菜单XML。
  5. 编辑1:在基本活动中夸大适当的布局:

    public abstract class BaseActivity extends AppCompatActivity {
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(getLayoutResId());
            final Toolbar toolbar = findViewById(<your toolbar id>);
            // the rest of your logic
        }
    
        // This abstract method will provide a way for extending activities to give the id of their layout, so you can inflate it, before trying to set the toolbar
        @LayoutRes
        protected abstract getLayoutResId();
    } 
    

    编辑2:自定义工具栏 与其他每个小部件一样,工具栏可以使用样式进行自定义。要控制工具栏背景颜色,间距等,您需要为其设置自定义样式。您还可以使用相同的机制更改工具栏标题和字幕外观。 Here是一个很棒的链接,可以显示有关创建和应用自定义工具栏样式的所有信息。