Android - Problem replacing Fragment

1

I'm doing a practice with Fragments.

There is only one activity with a vertical LinearLayout. When executing the App, a fragment is loaded with a TextView that can be modified using the buttons that contain a second fragment. In principle two buttons appear: Change text and Reset Text. So far it works.

When you press the first button, the original TextView text is changed, the second button restores it. In addition, the first button should replace the fragment where the buttons are with another button that adds a third button: Erase text. This fragment, with three buttons, must replace the original, with two buttons, but it is superimposed. That is, in the activity, the two original buttons remain and underneath they reappear next to the third one. The buttons of the new fragment are not functional ... Try applying this solution , that is, include the fragment within the main layout a FragmentLayout that carries its id: error that does not allow to load the app. I do not use emulators and I use to debug a real device with Android 4.1, the App uses API level 16.

Classes:

MainActivity.java

package com.example.orici.fragmentsdinamicos;

import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private boolean flag = false;

    final private FragmentManager fm = getFragmentManager();
    private FragmentTransaction ft = null;

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

        final TextView label = (TextView) findViewById( R.id.label );
        final Button btn_change = (Button) findViewById( R.id.btn1 );
        final Button btn_reset  = (Button) findViewById( R.id.btn2 );
        final Button btn_erase  = (Button) findViewById( R.id.btn3 );

        btn_change.setOnClickListener( new View.OnClickListener() {
            public void onClick( View v ) {
                label.setText( R.string.text2 );

                changeFrBtns();
            }
        });
        btn_reset.setOnClickListener( new View.OnClickListener() {
            public void onClick( View v ) {
                label.setText( R.string.text1 );
            }
        });

        if ( flag ) {
            btn_erase.setOnClickListener( new View.OnClickListener() {
                public void onClick( View v ) {
                    label.setText( "" );
                }
            });
        } //flag

    }

    private void changeFrBtns() {
        //Acciones para mostrar el fragment fr_btns2
        flag = true;
        ft   = fm.beginTransaction();
                ft.replace(
                        R.id.place_btns,
                        new FragmentBtns2()
                );

        ft.addToBackStack( null );
        ft.commit();
    }

    private void resetFrBtns() {
        //Acciones para mostrar el fragment fr_btns2
        flag = true;
        ft   = fm.beginTransaction();
                ft.replace(
                        R.id.place_btns,
                        new FragmentBtns1()
                );
        ft.addToBackStack( null );

        ft.commit();
    }

} //class

FragmentBtns1.java
Load fragment at the beginning with buttons

package com.example.orici.fragmentsdinamicos;

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

/**
 * Incluye fragmento con los botones en la actividad
 *
 */
public class FragmentBtns1 extends Fragment {

    @Override
    public View onCreateView(
            LayoutInflater inflater,
            ViewGroup container,
            Bundle savedInstanceState
    ) {

        // Inflate the layout for this fragment
        try {
            Log.d( "@", "Inflating the layout for buttons fragment..." );

            return inflater.inflate( R.layout.fr_btns1, container, false );

        } catch ( InflateException e ) {
            Log.e( "@Err", e.getMessage( ));
        }


        return null;
    }

} //class

FragmentBtns2.java
Load fragment dynamically with buttons

package com.example.orici.fragmentsdinamicos;

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

public class FragmentBtns2 extends Fragment {

    @Override
    public View onCreateView(
            LayoutInflater inflater,
            ViewGroup container,
            Bundle savedInstanceState
    ) {

        // Inflate the layout for this fragment
        try {
            Log.d( "@@@", "Inflating the layout for bottom fragment..." );

            return inflater.inflate( R.layout.fr_btns2, container, false );

        } catch ( InflateException e ) {
            Log.e( "@Err", e.getMessage( ));
        }


        return null;
    }

} //class

FragmentLabel.java
Load fragment with TextView at the beginning

package com.example.orici.fragmentsdinamicos;

import android.app.Fragment;
import android.os.Bundle;
import android.os.Trace;
import android.util.Log;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Incluye fragmento con TextView en la actividad
 *
 */
public class FragmentLabel extends Fragment {

    @Override
    public View onCreateView(
            LayoutInflater inflater,
            ViewGroup container,
            Bundle savedInstanceState
    ) {

        // Inflate the layout for this fragment
        try {
            Log.d( "@", "Inflating the layout for label fragment..." );

            return inflater.inflate( R.layout.fr_label, container, false );

        } catch ( InflateException e ) {
            Log.e( "@Err", e.getMessage( ));
        }


        return null;
    }

} //class

XML files

res / layout / activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="@dimen/activity_vertical_margin"
    tools:context="com.example.orici.fragmentsdinamicos.MainActivity">

    <!--/ Fragmento con el texto /-->
    <fragment android:name="com.example.orici.fragmentsdinamicos.FragmentLabel"
        android:id="@+id/fr_label"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <!--/ Fragmento con los botones /-->
    <!--/ Fragmento dinámico        /-->
    <FragmentLayout
        android:id="@+id/place_btns"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <fragment android:name="com.example.orici.fragmentsdinamicos.FragmentBtns1"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </FragmentLayout>

</LinearLayout>

res / layout / fr_btns1.xml
fragment with buttons that is loaded at the beginning

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/fr_btns1" >


    <Button
        android:text="@string/btn1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:id="@+id/btn1" />

    <Button
        android:text="@string/btn2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:id="@+id/btn2" />

</LinearLayout>

res / layout / fr_btns2.xml
fragment with buttons that are loaded dynamically

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@android:color/darker_gray"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/fr_btns2" >

    <Button
        android:text="@string/btn1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:id="@+id/btn1" />

    <Button
        android:text="@string/btn2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:id="@+id/btn2" />

    <!-- nuevo botón. No aparece al cargar la App -->
    <Button
        android:text="@string/btn3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:id="@+id/btn3" />
</LinearLayout>

res / layout / fr_label.xml
fragment with TextView that is loaded at the beginning

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:gravity="center"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:text="@string/text1"
        android:id="@+id/label" />

</LinearLayout>

res / values / strings.xml

<resources>
    <string name="app_name">FragmentsDinamicos</string>

    <string name="text1">Hola Mundo!</string>
    <string name="text2">Lorem ipsum lorem</string>

    <string name="btn1">Change text</string>
    <string name="btn2">Reset text</string>
    <string name="btn3">Erase text</string>
</resources>
    
asked by Orici 26.11.2016 в 00:50
source

1 answer

1

If the idea is to support previous versions, I would recommend using getSupportFragmentManager (), also I would not recommend that you store it in a variable level class, but that you get it every time it is going to be used. If doing so in this way you are worried about the repeated code, in MainActivity you could have a function like the following

    public void loadFragment(int idContainer, Fragment frag, String tag, boolean addToBackstack) {
         if(frag != null && findViewById(idContainer) != null) {
             FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
             ft.replace(idContainer, frag, tag);
             if (addToBackstack) {
                 ft.addToBackStack(tag);
             }
             ft.commit();
         }
    }
    
answered by 24.02.2017 в 22:53