当我通过底部导航切换到另一个片段时,我的应用程序意外停止

时间:2018-02-07 11:19:04

标签: android android-fragments android-bottomnav

我刚开始学习 Android Studio 的布局和基本UI元素,以及它如何组织drawable, layouts, strings, activities等文件。

所以,我已经设法通过一些youtube教程将一个基本的navigation小部件添加到一个activity,其中包含5个导航项。响应点击的唯一navigation item是第一个信息中心。其余的返回“不幸的是应用已停止”对话框。

以下是我Activity.java

上的代码
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;

public class StudentActivity extends AppCompatActivity {
    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {

                case R.id.navigation_dashboard: //this works
                    AlertDialog.Builder builder1 = new AlertDialog.Builder(StudentActivity.this);
                    builder1.setMessage("Dashboard To.");
                    builder1.setCancelable(true);
                    builder1.show(); // I'm able to see the dialog here

                    setTitle("Dashboard");
                    DashboardFragment dashboard_fragment = new DashboardFragment();
                    FragmentTransaction transaction1 = getFragmentManager().beginTransaction();
                    transaction1.replace(R.id.frameLayout,dashboard_fragment);
                    return true;

                case R.id.navigation_learn: //this doesn't work
                    try {
                        AlertDialog.Builder builder2 = new AlertDialog.Builder(StudentActivity.this);
                        builder2.setMessage("Learn To.");
                        builder2.setCancelable(true);
                        builder2.show(); //dialog doesn't even show up

                        setTitle("Learn");
                        DashboardFragment learn_fragment = new DashboardFragment();
                        FragmentTransaction manager1 = getFragmentManager().beginTransaction();
                        manager1.replace(R.id.frameLayout, learn_fragment);
                        manager1.commit();
                    }catch(Exception e){
                        AlertDialog.Builder errorDialog = new AlertDialog.Builder(StudentActivity.this);
                        errorDialog.setMessage(e.getMessage());
                        errorDialog.setCancelable(true);
                        errorDialog.show();
                    }

                    return true;
           }
            return false;
        }
    };

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


        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
    }

}

以下是我navigation.xml的样子

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

    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_dashboard"
        android:title="Dashboard" />

    <item
        android:id="@+id/navigation_learn"
        android:icon="@drawable/ic_openbook2"
        android:title="Learn" />

    <item
        android:id="@+id/navigation_play"
        android:icon="@drawable/ic_game2"
        android:title="Play" />

    <item
        android:id="@+id/navigation_review"
        android:icon="@drawable/ic_shapes"
        android:title="Review" />

    <item
        android:id="@+id/navigation_profile"
        android:icon="@drawable/ic_user2"
        android:title="My Profile" />

</menu>

我已经确认所有drawable图标都存在且名称为小写

我确保包含正确导入import android.app.FragmentTransaction;。我做了一些研究,发现还有android.support.v4.app.FragmentTransaction,这是不正确的。

构建成功,我可以使用 Nox 模拟器启动应用。消息Gradle Build 窗口中没有消息。

enter image description here enter image description here

可能是什么原因?关于如何解决这个问题的任何建议?

提前致谢。 编辑: 这是我点击第二个导航项时得到的错误。

java.lang.IllegalArgumentException: No view found for id 0x7f0a004b (com.example.peace:id/frameLayout) for fragment LearnFragment{4bbf1c20 #1 id=0x7f0a004b}
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:882)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
at android.app.BackStackRecord.run(BackStackRecord.java:684)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)

这是LearnFragment.java

package com.example.peace.cai;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


/**
 * A simple {@link Fragment} subclass.
 */
public class LearnFragment extends Fragment {


    public LearnFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_learn, container, false);
    }
}

这里是fragment_learn.xml

<FrameLayout 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"
    tools:context="com.example.peace.cai.LearnFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

3 个答案:

答案 0 :(得分:0)

您正在为两个底部菜单按钮使用相同的片段。您从两个bottomNav按钮调用相同的片段,仅更改引用。

将此处DashboardFragment learn_fragment = new DashboardFragment();DashboardFragment()更改为LearnFragment learn_fragment = new LearnFragment ();或您拥有的内容。

以下是您的代码:

 case R.id.navigation_dashboard: //this works
                AlertDialog.Builder builder1 = new AlertDialog.Builder(StudentActivity.this);
                builder1.setMessage("Dashboard To.");
                builder1.setCancelable(true);
                builder1.show(); // I'm able to see the dialog here

                setTitle("Dashboard");
                DashboardFragment dashboard_fragment = new DashboardFragment();
                FragmentTransaction transaction1 = getFragmentManager().beginTransaction();
                transaction1.replace(R.id.frameLayout,dashboard_fragment);
                return true;

            case R.id.navigation_learn: //this doesn't work
                try {
                    AlertDialog.Builder builder2 = new AlertDialog.Builder(StudentActivity.this);
                    builder2.setMessage("Learn To.");
                    builder2.setCancelable(true);
                    builder2.show(); //dialog doesn't even show up

                    setTitle("Learn");
                    DashboardFragment learn_fragment = new DashboardFragment(); // Here need to change LearnFragment() 
                    FragmentTransaction manager1 = getFragmentManager().beginTransaction();
                    manager1.replace(R.id.frameLayout, learn_fragment);
                    manager1.commit();

将您的片段fragment_learn.xml更改为LinearLayoutRelativeLayout

    <LinearLayout 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:orientation="vertical"   
    tools:context="com.example.peace.cai.LearnFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</LinearLayout >

答案 1 :(得分:0)

在您的Activity.java类中,在第一种情况下R.id.navigation_dashboard,您将使用dashboard_fragment替换容器R.id.frameLayout中的任何内容,但您不提交该事务。在第二种情况下,R.id.navigation_learn用另一个片段LearnFragment替换同一个容器R.id.frameLayout中的任何内容并进行提交,所以此时在同一个事务中你试图将两个片段推入相同的布局这可能是导致崩溃的原因。通过像第二个事务那样提交第一个事务来解决问题。请参阅下面的代码。

case R.id.navigation_dashboard: //this works
                    AlertDialog.Builder builder1 = new AlertDialog.Builder(StudentActivity.this);
                    builder1.setMessage("Dashboard To.");
                    builder1.setCancelable(true);
                    builder1.show(); // I'm able to see the dialog here

                    setTitle("Dashboard");
                    DashboardFragment dashboard_fragment = new DashboardFragment();
                    FragmentTransaction transaction1 = getFragmentManager().beginTransaction();
                  transaction1.replace(R.id.frameLayout,dashboard_fragment).commit();
                    return true;

                case R.id.navigation_learn: //this doesn't work
                    try {
                        AlertDialog.Builder builder2 = new AlertDialog.Builder(StudentActivity.this);
                        builder2.setMessage("Learn To.");
                        builder2.setCancelable(true);
                        builder2.show(); //dialog doesn't even show up

                        setTitle("Learn");
                        LearnFragment learn_fragment = new LearnFragment ();
                        FragmentTransaction manager1 = getFragmentManager().beginTransaction();
                        manager1.replace(R.id.frameLayout, learn_fragment);
                        manager1.commit();
                    }catch(Exception e){
                        AlertDialog.Builder errorDialog = new AlertDialog.Builder(StudentActivity.this);
                        errorDialog.setMessage(e.getMessage());
                        errorDialog.setCancelable(true);
                        errorDialog.show();
                    }

                    return true;

答案 2 :(得分:0)

在片段中添加以下行。

if(getActivity() != null && isAdded) {
  //do your operation
}