uso tutorial studio start manager fragments example dinamicos activity android-fragments visibility

android-fragments - tutorial - start fragment



Mostrar/Ocultar Fragmentos y cambiar el atributo de visibilidad mediante programaciĆ³n (1)

En FragmentB intenta obtener una vista que no está en su contenido.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_b, container, false); // this is in fragment_b layout ListView listView = (ListView) view.findViewById(R.id.listView1); Button button = (Button) view.findViewById(R.id.button); /* ... */ // **************************************** // this is NOT in fragment_b layout, which causes null // **************************************** final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.fragment_C); /* ... */ }

Tratar:

final FrameLayout frameLayout = (FrameLayout) getActivity().getWindow().findViewById(R.id.fragment_C);

Mientras que R.id.fragment_C está inflado y configurado en MainActivity.

Además, tuve el mismo problema hasta que use una bandera adicional

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); final Fragment fragmentC = new FragmentC(); fragmentTransaction.add(R.id.fragment_C, fragmentC); fragmentTransaction.commit(); menuIsOn = false; final View fragmentCView = findViewById(R.id.fragment_C); final Button btn = (Button) findViewById(R.id.btn); btnPowers.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!menuIsOn) { fragmentCView.setVisibility(View.VISIBLE); } else { fragmentCView.setVisibility(View.INVISIBLE); } menuIsOn = !menuIsOn; } });

Este es un problema de 2 partes. Lo que estoy teniendo es un diseño de 3 Fragmentos donde el 3er Fragmento (FragmentC) se agrega dinámicamente cuando el usuario toca un botón que se encuentra en otro fragmento. Luego, después de agregarlo, el 3er. Fragmento tiene un botón para maximizarlo / minimizarlo.

ACTUALIZACIÓN: Scrool al final para SOLUCIÓN



PROBLEMA 1:

Estoy intentando cambiar el atributo de visibilidad de un FrameLayout que actúa como un contenedor para el fragmento 3''rd (R.id.fragment_C).

Lo que se supone que el código debe hacer es generar otro fragmento que, originalmente, tiene un archivo XML que contiene android: visibility = "gone". Luego, el Fragmento se agrega al tocar un botón y se supone que la visibilidad cambia a VISIBLE.

Sé que esto se ha cubierto antes, pero después de 4 horas de tratar de hacerlo funcionar, decidí preguntarme qué estoy haciendo mal.

PROBLEMA 2:

Después de que se genera el fragmento 3''rd, tengo un botón minimizar / maximizar que se supone que oculta los primeros 2 fragmentos y permite que el 3 ° Fragmento llene la pantalla.

El problema es que las Vistas de los primeros 2 Fragmentos no se eliminan cuando se usa .setVisibility (View.GONE). Esto también se ha cubierto anteriormente, pero no puedo entender por qué no funciona en mi código.

El código hasta el momento (lo siento si es detallado, pero creo que es mejor incluir todos los detalles para ustedes):

main_activity.xml

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingLeft="0dp" android:paddingRight="0dp" android:orientation="vertical" > <FrameLayout android:id="@+id/fragment_A" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:background="#CCCCCC" > </FrameLayout> <FrameLayout android:id="@+id/fragment_B" android:layout_width="fill_parent" android:layout_height="300dp" android:layout_below="@id/fragment_A" android:layout_centerHorizontal="true" android:layout_marginTop="15dp" android:background="#B4B4B4" > </FrameLayout> <FrameLayout android:id="@+id/fragment_C" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_below="@id/fragment_B" android:layout_centerHorizontal="true" android:layout_marginTop="0dp" android:background="#A3A3A3" android:visibility="gone" > </FrameLayout> </RelativeLayout>

land / main_activity.xml

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" android:paddingLeft="0dp" android:paddingRight="0dp" > <LinearLayout android:id="@+id/fragments_container" android:layout_width="fill_parent" android:layout_height="200dp" android:baselineAligned="false" > <FrameLayout android:id="@+id/fragment_A" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="#CCCCCC" > </FrameLayout> <FrameLayout android:id="@id/fragment_B" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.5" android:background="#B4B4B4" > </FrameLayout> </LinearLayout> <FrameLayout android:id="@+id/fragment_C" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_below="@id/fragment_container" android:layout_centerHorizontal="true" android:layout_marginTop="0dp" android:background="#A3A3A3" android:visibility="gone" > </FrameLayout> </RelativeLayout>

MainActivity.java

package com.example.android.fragments_proto.activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import com.example.android.fragments_proto.R; import com.example.android.fragments_proto.fragment.GMC_DateSelectionFragment; import com.example.android.fragments_proto.fragment.GMC_ProdUnitSelectionFragment; public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); FragmentManager fm = getSupportFragmentManager(); Fragment fragmentA = fm.findFragmentById(R.id.fragment_A); Fragment fragmentB = fm.findFragmentById(R.id.fragment_B); if (fragmentA == null) { FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.fragment_A, new FragmentA()); ft.commit(); } if (fragmentB == null) { FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.fragment_B, new FragmentB()); ft.commit(); } } }

Ahora los archivos XML y .java para el primer Fragmento.

fragment_A.xml

<?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:gravity="center_horizontal" > <DatePicker android:id="@+id/datePicker1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>

FragmentA.java

package com.example.android.fragments_proto.fragment; import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.widget.DatePicker; import android.widget.Toast; import com.example.android.fragments_proto.R; public class FragmentA extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_A, container, false); DatePicker datePicker = (DatePicker) view.findViewById(R.id.datePicker1); datePicker.setCalendarViewShown(true); datePicker.setSpinnersShown(false); datePicker.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Activity activity = getActivity(); if (activity != null) { Toast.makeText(activity, "You Touched ME!", Toast.LENGTH_SHORT).show(); } return false; } }); return view; } }

Ahora los archivos XML y .java para el Fragmento que contiene el botón que cuando se toca agrega el contenido en R.id.fragment_C

fragment_B.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="0.1" > <ListView android:id="@+id/listView1" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ListView> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:orientation="horizontal" android:gravity="center" android:layout_height="wrap_content"> <Button android:id="@+id/button" android:text="@string/btn_fragment" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>

FragmentB.java

package com.example.android.fragments_proto.fragment; import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import com.example.android.fragments_proto.R; public class FragmentB extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragmentB, container, false); ListView listView = (ListView) view.findViewById(R.id.listView1); Button button = (Button) view.findViewById(R.id.button); String[] machines = new String[] { "MachineId-001", "MachineId-002", "MachineId-003", "MachineId-004", "MachineId-005", "MachineId-006", "MachineId-007", "MachineId-008"}; listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listView.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_multichoice, machines)); final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.fragment_C); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Activity activity = getActivity(); if (activity != null) { getFragmentManager().beginTransaction().replace(R.id.fragment_C, new FragmentC()).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).addToBackStack(null).commit(); frameLayout.setVisibility(View.VISIBLE); } } }); return view; } }

Los archivos XML y .java para el Fragmento que se supone que debe agregarse.

fragment_C.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:orientation="horizontal" android:gravity="center" android:layout_height="wrap_content"> <Button android:id="@+id/maximize_button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Maximize Me!" /> </LinearLayout> <TextView android:id="@+id/text_view" android:textIsSelectable="true" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FF33FF" /> </LinearLayout>

FragmentC.java

package com.example.android.fragments_proto.fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import com.example.android.fragments_proto.R; public class FragmentC extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_C, container, false); TextView textView = (TextView) view.findViewById(R.id.text_view); final Fragment fragmentA = getFragmentManager().findFragmentById(R.id.fragment_A); final Fragment fragmentB = getFragmentManager().findFragmentById(R.id.fragment_B); button.setOnClickListener(new OnClickListener() { public void onClick(View v) { FragmentTransaction ft = getFragmentManager().beginTransaction(); if (fragmentA.isVisible() && fragmentB.isVisible()) { ft.hide(fragmentA); ft.hide(fragmentB); fragmentA.getView().setVisibility(View.GONE); fragmentB.getView().setVisibility(View.GONE); button.setText("Minimize Me!"); ft.addToBackStack(null); } else { ft.show(fragmentA); ft.show(fragmentB); fragmentA.getView().setVisibility(View.VISIBLE); fragmentB.getView().setVisibility(View.VISIBLE); button.setText("Maximize Me!"); ft.addToBackStack(null); } ft.commit(); } }); return view; } }




Encontrado el problema y una solución gracias a Moesio

PROBLEMA:

Mi error fue que estaba tratando de encontrar una vista (en FragmentB.java) con

frameLayout final frameLayout = (FrameLayout) view.findViewById (R.id.fragment_C);

Esta línea devolvía nulo, por lo que cuando el código llegaba al punto donde se suponía que debía hacer una .setVisibility (), entonces la aplicación. devolvería una nullPointerException.

Lo mismo ocurrió con FragmentC.java (por lo que mis 2 problemas estaban relacionados). Las vistas no se eliminaron porque mi findViewById era nulo.


SOLUCIÓN:

Simplemente busque su Vista con getActivity .findViewById (R.id.your_view);