James Cosgrave
James Cosgrave

Reputation: 75

issue with replacing Fragment views in Navigation drawer

I am using the android Navigation drawer template and fragments to display different views.

as the normal there is a MainActivity, activity_main.xml and content_main.xml generated automatically.

I have created two java classes; MusicFragment and MainFragment and of course the layout files which I have content inside.

When I run the app the activity_main is the default layout launched which I have welcome content displaying, I am using the Navigation drawer to navigate to my MusicFragment and MainFragment, this code I using to replace the current view in the onNavigationItemSelected method is;

 if (id == R.id.nav_camara) {

        fm.beginTransaction().replace(R.id.content_frame, new MainFragment()).commit();


    } else if (id == R.id.nav_gallery) {

        fm.beginTransaction().replace(R.id.content_frame, new MusicFragment()).commit();

these both work fine with replacing each other although I have a big problem, when I select the nav drawer and hit the camera option it shows the fragment view but does not replace the content from activity_main it shows the fragment content on top of the content_main and doesn't replace it.

This is my MainActivity:

package com.justmikey.justmik;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentManager;
import android.support.v7.internal.widget.ButtonBarLayout;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.support.design.widget.NavigationView;
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.widget.Button;
import android.widget.TextView;
import JustMikey.Fragments.MainFragment;
import JustMikey.Fragments.MusicFragment;

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

//create a media player object called mp
MediaPlayer mp;
//declare my buttons play, pause and stop
Button play, pause,stop;

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

    //Set the textView scrollMain to scrollable
    TextView tv = (TextView) findViewById(R.id.scrollMain);
    tv.setMovementMethod(new ScrollingMovementMethod());

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
}




@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

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

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    android.app.FragmentManager fm = getFragmentManager();

    int id = item.getItemId();

    if (id == R.id.nav_camara) {

        fm.beginTransaction().replace(R.id.content_frame, new MainFragment()).commit();


    } else if (id == R.id.nav_gallery) {

        fm.beginTransaction().replace(R.id.content_frame, new MusicFragment()).commit();


    } else if (id == R.id.nav_slideshow) {

    } else if (id == R.id.nav_manage) {

    } else if (id == R.id.nav_share) {

    } else if (id == R.id.nav_send) {

    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}
}

content_main.xml:

<?xml version="1.0" encoding="utf-8"?>



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"     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"
app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/app_bar_main"
tools:context=".MainActivity"
android:background="#dbe4eb">



<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/content_frame">

    <ImageView
        android:layout_width="355dp"
        android:layout_height="wrap_content"
        android:src="@drawable/jmmain"
        android:id="@+id/imageView2"
        android:layout_gravity="center_horizontal|top"
        android:layout_alignRight="@+id/content_frame"
        android:layout_alignEnd="@+id/content_frame" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="274dp"
        android:text="hello hello hello hello hello hello hello hello"
        android:id="@+id/scrollMain"
        android:layout_gravity="center_horizontal|bottom"
        android:layout_alignBottom="@+id/scrollView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="28dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:background="#ffffff"
        android:padding="10dp"
        />

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/scrollView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_gravity="center">

    </ScrollView>


</FrameLayout>

</RelativeLayout>

Upvotes: 1

Views: 3328

Answers (2)

roghayeh hosseini
roghayeh hosseini

Reputation: 716

I had the same problem. I could not solve my problem with the said solutions. But i found two solutions to solve it!

1- You can present the content of the main page into an other view group. and hide it in onNavigationItemSelected, in the right place:

content_main.xml:

<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dbe4eb"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/app_bar_main">

<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<LinearLayout
    android:id="@+id/my_linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="355dp"
        android:layout_height="wrap_content"
        android:layout_alignEnd="@+id/content_frame"
        android:layout_alignRight="@+id/content_frame"
        android:layout_gravity="center_horizontal|top"
        android:src="@drawable/jmmain" />

    <TextView
        android:id="@+id/scrollMain"
        android:layout_width="fill_parent"
        android:layout_height="274dp"
        android:layout_alignBottom="@+id/scrollView"
        android:layout_alignParentEnd="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentStart="true"
        android:layout_gravity="center_horizontal|bottom"
        android:layout_marginBottom="28dp"
        android:background="#ffffff"
        android:padding="10dp"
        android:text="hello hello hello hello hello hello hello hello" />

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_gravity="center"></ScrollView>
</LinearLayout>
</RelativeLayout>

onNavigationItemSelected method in MainActivity.java:

public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.main) {
        findViewById(R.id.my_linearLayout).setVisibility(View.VISIBLE);
        fragmentManager.popBackStack("fragment", POP_BACK_STACK_INCLUSIVE);
    } else if (id == R.id.one) {
        findViewById(R.id.my_linearLayout).setVisibility(View.GONE);
        fragmentManager.beginTransaction().replace(R.id.content_frame, new OneFragment()).addToBackStack("fragment").commit();
    } else if (id == R.id.tow) {
        findViewById(R.id.my_linearLayout).setVisibility(View.GONE);
        fragmentManager.beginTransaction().replace(R.id.content_frame, new SecondFragment()).addToBackStack("fragment").commit();
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

2- The second way is to consider a fragment for the contents of the main page as well. and then in the onNavigationItemSelected method, we treat it Like the rest of the fragments:

onNavigationItemSelected method in MainActivity.java:

    public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.main) {
        fragmentManager.beginTransaction().replace(R.id.content_frame, new HomeFragment()).addToBackStack("fragment").commit();
    } else if (id == R.id.one) {
        fragmentManager.beginTransaction().replace(R.id.content_frame, new OneFragment()).addToBackStack("fragment").commit();
    } else if (id == R.id.tow) {
        fragmentManager.beginTransaction().replace(R.id.content_frame, new SecondFragment()).addToBackStack("fragment").commit();
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

note: To display the contents of the main page when opening the program enter the following code in onCreate() in MainActivity:

        fragmentManager.beginTransaction().replace(R.id.content_frame, new HomeFragment()).addToBackStack("fragment").commit();

Upvotes: 0

Mike M.
Mike M.

Reputation: 39191

FragmentTransactions only handle Fragments. They will not replace/remove anything not in a Fragment. Since those Views contained in the content_frame FrameLayout are only needed at startup, we can simply remove them upon the first FragmentTransaction.

To do this, we'll create a member boolean flag, isStartup, initialized to true. In the onNavigationItemSelected() method, we'll check the flag, and if it's true, remove the Views and change it to false.

Declare and initialize the boolean outside of any method:

private boolean isStartup = true;

Then do the check and removal in the onNavigationItemSelected() method.

public boolean onNavigationItemSelected(MenuItem item) {
    android.app.FragmentManager fm = getFragmentManager();
    int id = item.getItemId();

    if(isStartup) {
        ((FrameLayout) findViewById(R.id.content_frame)).removeAllViews();
        isStartup = false;
    }

    if (id == R.id.nav_camara) {
        ...

}

Upvotes: 2

Related Questions