应用程序在添加导航抽屉后开始崩溃

时间:2016-11-15 19:21:25

标签: java android crash navigation-drawer

所以我正在尝试通过添加app并将更多页面添加到app drawer来升级我的app,一切看起来都不错,但app在启动时崩溃,我从Androidhive.info得到了这个想法。错误是关于appDrawer的测量。附加了错误消息,MainActivity.javaactivity_main.xml文件。 错误消息

                  E/AndroidRuntime: FATAL EXCEPTION: main
              java.lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY.
                  at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1046)
                  at android.view.View.measure(View.java:15609)
                  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4916)
                  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
                  at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
                  at android.view.View.measure(View.java:15609)
                  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4916)
                  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1411)
                  at android.widget.LinearLayout.measureVertical(LinearLayout.java:698)
                  at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
                  at android.view.View.measure(View.java:15609)
                  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4916)
                  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
                  at android.view.View.measure(View.java:15609)
                  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4916)
                  at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1411)
                  at android.widget.LinearLayout.measureVertical(LinearLayout.java:698)
                  at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
                  at android.view.View.measure(View.java:15609)
                  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4916)
                  at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
                  at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2191)
                  at android.view.View.measure(View.java:15609)
                  at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2165)
                  at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1249)
                  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1443)
                  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1139)
                  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4879)
                  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
                  at android.view.Choreographer.doCallbacks(Choreographer.java:579)
                  at android.view.Choreographer.doFrame(Choreographer.java:548)
                  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
                  at android.os.Handler.handleCallback(Handler.java:725)
                  at android.os.Handler.dispatchMessage(Handler.java:92)
                  at android.os.Looper.loop(Looper.java:153)
                  at android.app.ActivityThread.main(ActivityThread.java:5297)
                  at java.lang.reflect.Method.invokeNative(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:511)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
                  at dalvik.system.NativeStart.main(Native Method)

MainActivity.java

package com.example.abdulkarim.justjava.activity;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.example.abdulkarim.justjava.R;
import com.example.abdulkarim.justjava.fragment.HomeFragment;
import com.example.abdulkarim.justjava.fragment.OrderFragment;
import com.example.abdulkarim.justjava.fragment.SettingsFragment;
import com.example.abdulkarim.justjava.other.CircleTransform;


public class MainActivity extends AppCompatActivity {
    private NavigationView navigationView;
    private DrawerLayout drawer;
    private View navHeader;
    private ImageView imgNavHeaderBg, imgProfile;
    private TextView txtName, txtWebsite;
    private Toolbar toolbar;
    private FloatingActionButton fab;

    // urls to find load navigation header background image
    //and profile image
    private static final String urlNavHeaderBg = "http://api.androidhive.info/images/nav-menu-header-bg.jpg";
    private static final String urlProfileImg = "https://lh3.googleusercontent.com/eCtE_G34M9ygdkmOpYvCag1vBARCmZwnVS6rS5t4JLzJ6QgQSBquM0nuTsCpLhYbKljoyS-txg";

    //index to identify current nav menu item
    public static int navItemIndex = 0;

    //tags used to attach the fragments
    private static final String TAG_HOME = "home";
    private static final String TAG_ORDER = "order";
    private static final String TAG_SETTINGS = "preferences";
    public static String CURRENT_TAG = TAG_HOME;

    //toolbar titles respected to selected nav menu item
    private String[] activityTitles;

    // flag to load home fragment when user presses back key
    private boolean shouldLoadHomeFragOnBackPress = true;
    private Handler mHandler;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mHandler = new Handler();

        drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        navigationView = (NavigationView) findViewById(R.id.nav_view);
        fab = (FloatingActionButton) findViewById(R.id.fab);

        //Navigation view header
        navHeader = navigationView.getHeaderView(0);
        txtName = (TextView) navHeader.findViewById(R.id.input_name);
        txtWebsite = (TextView) navHeader.findViewById(R.id.website);
        imgNavHeaderBg = (ImageView) navHeader.findViewById(R.id.img_header_bg);
        imgProfile = (ImageView) navHeader.findViewById(R.id.img_profile);

        //load toolbar titles from string resources
        activityTitles = getResources().getStringArray(R.array.nave_item_activity_titles);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Text", Snackbar.LENGTH_LONG).setAction("Action", null).show();
            }
        });

        // load nav menu header data
        loadNavHeader();

        // initializing navigation menu
        setUpNavigationView();

        if (savedInstanceState == null) {
            navItemIndex = 0;
            CURRENT_TAG = TAG_HOME;
            loadHomeFragment();
        }

    }

    /**
     * Load navigation menu header information
     * like background image, profile image name,
     * website, notifications action view (dot)
     */
    private void loadNavHeader() {
        // name, website
        txtName.setText("Abdulrahman Abdulkarim");
        txtWebsite.setText("www.shukura.com");

        //loading header background image
        Glide.with(this).load(urlNavHeaderBg)
                .crossFade()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(imgNavHeaderBg);
        // loading profile image
        Glide.with(this).load(urlProfileImg)
                .crossFade()
                .thumbnail(0.5f)
                .bitmapTransform(new CircleTransform(this))
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(imgProfile);

        // showing dot next to notification label
        navigationView.getMenu().getItem(3).setActionView(R.layout.menu_dot);
    }

    /**
     * Returns respected fragment that user selected from
     * navigation menu
     */
    private void loadHomeFragment() {
        //selecting appropriate nav menu item
        selectNavMenu();

        //set toolbar title
        setToolbarTitle();

        //if user select the current navigation menu again, don't do anything
        //just close the navigation drawer
        if (getSupportFragmentManager().findFragmentByTag(CURRENT_TAG) != null) {
            drawer.closeDrawers();

            //show or hide the fab
            toggleFab();
            return;
        }

        //Sometimes, when fragment has huge data, screen seems hanging
        //when switching between navigation menus
        //So using runnable, the fragment is loaded with cross fade effect
        //This effect can be seen in GMail app
        Runnable mPendingRunnable = new Runnable() {
            @Override
            public void run() {
                //update the main content by replacing fragments
                Fragment fragment = getHomeFragment();
                FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                fragmentTransaction.setCustomAnimations(android.R.anim.fade_in,
                        android.R.anim.fade_out);
                fragmentTransaction.replace(R.id.frame, fragment, CURRENT_TAG);
                fragmentTransaction.commitAllowingStateLoss();
            }
        };

        //if mPendingRunnable is not null, then add to the message queue
        if (mPendingRunnable != null) {
            mHandler.post(mPendingRunnable);
        }

        //show or hide the fab
        toggleFab();

        //closing drawer on item click
        drawer.closeDrawers();

        //refresh toolbar menu
        invalidateOptionsMenu();
    }

    private Fragment getHomeFragment() {
        switch (navItemIndex) {
            case 0:
                //home
                HomeFragment homeFragment = new HomeFragment();
                return homeFragment;
            case 1:
                //order
                OrderFragment orderFragment = new OrderFragment();
                return orderFragment;
            case 2:
                SettingsFragment settingsFragment = new SettingsFragment();
                return settingsFragment;
            default:
                return new HomeFragment();
        }
    }

    private void setToolbarTitle() {
        getSupportActionBar().setTitle(activityTitles[navItemIndex]);
    }

    private void selectNavMenu() {
        navigationView.getMenu().getItem(navItemIndex).setChecked(true);
    }

    private void setUpNavigationView() {
        //Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {

            //This method will trigger on item click of Navigation menu
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {

                //Check to see which item was being clicked and perform appropriate action
                switch (menuItem.getItemId()) {
                    //Replacing the main conten with Content Fragment which is our Inbox view
                    case R.id.nav_home:
                        navItemIndex = 0;
                        CURRENT_TAG = TAG_HOME;
                        break;
                    case R.id.nav_order:
                        navItemIndex = 1;
                        CURRENT_TAG = TAG_ORDER;
                        break;
                    case R.id.nav_settings:
                        navItemIndex = 2;
                        CURRENT_TAG = TAG_SETTINGS;
                        break;
                    case R.id.nav_about_us:
                        startActivity(new Intent(MainActivity.this, AboutUs.class));
                        drawer.closeDrawers();
                        return true;
                    case R.id.nav_contact:
                        startActivity(new Intent(MainActivity.this, ContactUs.class));
                        drawer.closeDrawers();
                        return true;
                    default:
                        navItemIndex = 0;
                }

                //Checking if the tiem is in checked state or not, if not check the item
                if (menuItem.isChecked()) {
                    menuItem.setChecked(false);
                } else {
                    menuItem.setChecked(true);
                }
                menuItem.setChecked(true);

                loadHomeFragment();

                return true;
            }
        });

        ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.openDrawer, R.string.closeDraer) {
            @Override
            public void onDrawerClosed(View drawerView) {
                //Code here will be triggered once the drawer closes as we don't want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                //Code here will be triggered once the drawer closes as we don't want anything to happen so we leave this blank
                super.onDrawerOpened(drawerView);
            }
        };

        //Setting the actionbarToggle to drawer layout
        drawer.setDrawerListener(actionBarDrawerToggle);

        //calling sync state is necessary or else your hamburger icon won't show up
        actionBarDrawerToggle.syncState();
    }

    @Override
    public void onBackPressed() {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawers();
            return;
        }

        //This code loads home fragment when back key is pressed
        //when useer is in other fragment than home

        if (shouldLoadHomeFragOnBackPress) {
            //checking if useer is on other navigation menu
            //rather than home
            if (navItemIndex != 0) {
                navItemIndex = 0;
                CURRENT_TAG = TAG_HOME;
                loadHomeFragment();
                ;
                return;
            }
        }

        super.onBackPressed();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //Inflate the menu; this adds items to the action bar if it is present

        //show menu only when home fragment is selected
        if (navItemIndex == 0) {
            getMenuInflater().inflate(R.menu.main, menu);
        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. the actionbar will
        //automatically handle clicks on the Home/Up button, so long
        //as you specify a parent activity in AndroidManifest.xml.
        return super.onOptionsItemSelected(item);
    }

    //show or hide the fab
    private void toggleFab() {
        if (navItemIndex == 0)
            fab.show();
        else
            fab.hide();
        ;
    }

}

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_man"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>

1 个答案:

答案 0 :(得分:0)

您在loadNavHeader()方法中获得空指针异常。你能否仔细检查你是否在OnCreate()中正确地实例化了该方法中的所有变量。

也值得发布您的@layout/nav_header_main布局。

编辑: android:layout_height="match_parent"