-2

I have just started learning layouts and basic UI elements of Android Studio as well as how it organizes the files which are drawable, layouts, strings, activities etc.

So, I have managed to add a basic navigation widget to one activity that has 5 navigation items by following some youtube tutorial. The only navigation item that responds to a tap is the first one which is the dashboard. The rest returns an "Unfortunately the app has stopped" dialog.

Here's the code on my 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);
    }

}

And below is how my navigation.xml looks like

<?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>

I have verified that all drawable icons are present and are in lower case names.

I made sure that correct import of import android.app.FragmentTransaction; is included. I did some research and found that there is also an android.support.v4.app.FragmentTransaction which is not the correct one.

Build was successful and I'm able to launch the app using Nox emulator.There are no messages in Message Gradle Build window.

enter image description here enter image description here

What could be the cause? Any suggestions on how to go about fixing this?

Thanks in advance. EDIT: Here's the error I get when I tap on the 2nd navigation item.

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)

Here's the 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);
    }
}

And here the 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>
heisenberg
  • 1,784
  • 4
  • 33
  • 62

3 Answers3

0

You are using same fragment for both of the bottom menu buttons. You are calling same fragment from both bottomNav buttons only reference is changed.

Change DashboardFragment learn_fragment = new DashboardFragment(); here, DashboardFragment() to LearnFragment learn_fragment = new LearnFragment (); or what you have.

Below is your Code :

 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();

Change your fragment fragment_learn.xml to LinearLayout or RelativeLayout.

    <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 >
Abhishek kumar
  • 4,347
  • 8
  • 29
  • 44
0

In your Activity.java class, in the first case R.id.navigation_dashboard you are replacing whatever was in the container R.id.frameLayout with dashboard_fragment but you are not committing that transaction. In the second case R.id.navigation_learn you are replacing whatever was in the same container R.id.frameLayout with another fragment LearnFragment and doing the commit, so at this time in the same transaction you are trying to push two fragments into same layout and probably this is causing the crash. Fix the issue by committing the first transaction like you do for the second one. See the code below.

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;
Angel Gruevski
  • 127
  • 1
  • 5
0

Add below line in your fragment.

if(getActivity() != null && isAdded) {
  //do your operation
}
Dilan
  • 2,610
  • 7
  • 23
  • 33