tutorial studio from fragments con activity android android-fragments

studio - navigation view fragment android



¿Cómo cambio la vista dentro de un fragmento? (9)

Tengo un fragmento que crea su vista dentro deCreateView como era de esperar. Sin embargo, quiero cambiar la vista periódicamente.

Mi caso de uso es que el fragmento muestra algunos datos de un servicio web. Cuando un usuario elige una opción de una lista (otro fragmento), este fragmento debe cambiar a una barra de progreso, luego, una vez cargado, volver a la vista de datos.

Podría hacer dos fragmentos: el fragmento de carga y el fragmento que se muestra, pero parece que, dado que se trata de un evento encapsulado, preferiría hacerlo todo dentro del fragmento.

Básicamente lo que estoy preguntando es cuál es el equivalente de setContentView dentro de un fragmento.


Aquí hay una solución más simple: guarde el inflador y el contenedor que recibe en CreateView y úselos más adelante. Por ejemplo:

private LayoutInflater mInflater; private ViewGroup mRootView; public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mInflater = inflater; mRootView = container; return null; } public void someCallBackLater() { // mRootView.removeAllViews(); // in case you call this callback again... mInflater.inflate(R.layout.my_layout, mRootView); }


Crear una vista predeterminada "ficticia"

<?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" > </LinearLayout>

Infla la vista predeterminada "ficticia" en el método onCreateView del fragmento y úsalo como marcador de posición para agregar vistas según sea necesario

private LayoutInflater mInflater; private ViewGroup mContainer; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){ mInflater = inflater; mContainer = container; View v =inflater.inflate(R.layout.home_view,container,false); placeholder = (ViewGroup) v; return placeholder; }

Para cambiar la vista a una nueva vista, primero elimine todas las vistas anteriores, luego infle la nueva vista y agregue

View newView = mInflater.inflate(R.layout.custom_dash, mContainer, false); placeholder.removeAllViews(); placeholder.addView(newView);


Esto que funcionó para mí:

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View v = inflater.inflate(R.layout.fragment_recipe, container, false); Button recipeBuyButton = (Button) v.findViewById( R.id.recipe_buy_button); Typeface tf = Typeface.createFromAsset(getActivity().getAssets(), "fonts/GE_SS_Two_Medium.otf"); recipeBuyButton.setTypeface(tf); return v;


Podría usar FrameLayout para alternar entre su barra de progreso y vista de datos, por ej.

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/cover_image" android:scaleType="fitCenter" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <ProgressBar android:id="@+id/cover_progress" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_gravity="center"/> </FrameLayout>

En onViewCreate() , entonces almacenaría ambas vistas en campos de instancia

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... image = (ImageView) container.findViewById(R.id.cover_image); progress = container.findViewById(R.id.cover_progress); ... }

y siempre que quiera cambiar entre los dos (recuerde hacer esto en su UI / hilo principal), simplemente haga algo como

progress.setVisibility(View.INVISIBLE); image.setVisibility(View.VISIBLE);


Si por algún motivo desea cambiar toda la vista de fragmento (por ejemplo, solicitud de URL asíncrona que cambiará la vista si tiene éxito), puede usar FragmentTransaction en la actividad principal y crear un nuevo fragmento sobre la marcha.

O puede guardar el fragmento y llamar a un método de este fragmento que se actualizará. Ejemplo: en la actividad principal, construyo y List<RefreshFragment> mFragmentList una lista de fragmentos List<RefreshFragment> mFragmentList .

Aquí está la clase RefreshFragment (y todos mis fragmentos extienden esta en mi ejemplo):

public class RefreshFragment extends Fragment { protected Data data; // here your asynchronously loaded data public void setData(Data data) { this.data = data; // The reload fragment code here ! if (! this.isDetached()) { getFragmentManager().beginTransaction() .detach(this) .attach(this) .commit(); } } }

Luego, en mi actividad callback asíncrono puedo llamar:

for (RefreshFragment f : mFragmentList) f.setData(data);

Por lo tanto, cada fragmento se actualizará con los datos correctos y el fragmento adjunto se actualizará de inmediato. Tienes que proporcionarte tu propio enCreateView en los fragmentos, por supuesto.

Lo importante es que un fragmento puede volver a getFragmentManager() con getFragmentManager() .


Tengo el mismo problema, fragment.getView () siempre devuelve nulo, aunque Fragment.onCreateView ya se invocó antes

no podemos cambiar el contenido del fragmento en tiempo de ejecución porque mi fragmento se agregó a ViewPager, así que intento usar otro método para obtener vista:

View view = viewPager.getChildAt(0); TextView text = (TextView) (view.findViewById(R.id.textView)); text.setText("12345");

Este problema ahora fue resuelto, espero que pueda ayudarte


U puede usar Transaction remove y add. Usé un Fragmento en el que puedo cargar cualquier vista. El Constructor del Fragmento debe tener un entero, ese entero es R.layout ... Simplemente elimino el fragmento anterior y pongo algo nuevo. !!! Solo funciona si haces que este fragmento sea dinámico y no en el diseño xml. Solo crea algo como LinearLayout R.id.fragment_layout

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.wundlist_fragmente); Log.v("WoundListActivity", "WoundListActivity gestartet..."); Log.v("WoundListActivity", "Liste..."); //dynamisch hinzufügen... wlf=new WoundListFragment(); fm.beginTransaction().add(R.id.fragment_layout,wlf).commit(); } //If Menubutton Clicked change @Override public boolean onOptionsItemSelected(MenuItem item) { if(item.getItemId()==R.id.itemaddwound){ Log.v("List", "neue Wunde Activity"); fm.beginTransaction().remove(wlf).commit(); fm.beginTransaction().add(R.id.fragment_layout, new NewWoundFragment()).commit(); } return super.onOptionsItemSelected(item); }


Usando la respuesta de Solostaran, estoy haciendo esto ahora:

Interfaz:

public interface FragmentReattachListener { public void reAttach(); }

Fragmento:

public class MyFragment extends Fragment implements FragmentReattachListener { //... @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //... App.registerFragmentReattachListener(this); //... } //... @Override public void reAttach() { FragmentManager f = getFragmentManager(); if (f != null) { f.beginTransaction() .detach(this) .attach(this) .commit(); } } }

de la clase de aplicación:

private static void reattachFragments() { if (fragmentReattachListeners.size() > 0) { for (FragmentReattachListener listener : fragmentReattachListeners) { listener.reAttach(); } } }