java - software - Android cómo dejar de actualizar Fragmentos en el cambio de pestaña
desactivar actualizaciones de sistema android (7)
Dado que la actividad implementa ActionBar.TabListener, la actividad onCreate () está siendo llamada una y otra vez. Entonces coloque el siguiente código en el método onResume ():
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
Tengo el siguiente código :
MainActivity.java
package com.erc.library;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import com.erc.sayeghlibrary.adapter.TabsPagerAdapter;
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Stories", "Dictionaries", "eBooks"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int actionBarTitleId = Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
if (actionBarTitleId > 0) {
TextView title = (TextView) findViewById(actionBarTitleId);
if (title != null) {
title.setTextColor(Color.WHITE);
}
}
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// action with ID action_refresh was selected
case R.id.Favorites:
Toast.makeText(this, "Favorites selected", Toast.LENGTH_SHORT)
.show();
break;
// action with ID action_settings was selected
default:
break;
}
return true;
}
}
TabsPagerAdapter.java
package com.erc.library.adapter;
import com.erc.library.Dictionaries;
import com.erc.library.Ebooks;
import com.erc.library.Stories;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new Stories();
case 1:
return new Dictionaries();
case 2:
// Movies fragment activity
return new Ebooks();
}
return null;
}
@Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
Estoy haciendo una aplicación de biblioteca en la que la navegación se realiza mediante pestañas, el problema es que cada vez que voy de la tercera pestaña a la primera o la tercera a la tercera, el contenido de la pestaña se actualiza, quiero evitar la actualización, Cualquier ayuda por favor ?
De forma predeterminada, ViewPager
recrea los fragmentos cuando desliza la página. Para evitar esto, puedes probar una de estas dos cosas:
1. En el onCreate()
de sus fragmentos, llame a setRetainInstance(true)
.
2. Si el número de fragmentos es fijo y relativamente pequeño, en su onCreate()
agregue el siguiente código:
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(limit); /* limit is a fixed integer*/
Si recuerdo bien, la segunda opción es más prometedora. Pero te insto a que pruebes ambos y veas cuál de ellos funciona.
En el onCreate () de sus fragmentos, llame a setRetainInstance (true)
En mi caso anterior la sugerencia no funciona.
Para restringir la recreación de fragmentos, lo que hice:
En onCreateView
puede almacenar la vista inflada en una variable global e inicializarla solo si es null
, como en este código:
var root:View?=null
var apiDataReceived=false
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
if (root==null)
root=inflater!!.inflate(R.layout.fragment_layout, container, false)
return root
}
Ahora, si está analizando algunos datos y completándolos en RecyclerView
o en cualquier otra View
Haga una variable global como en el código anterior
apiDataReceived
Establézcalo en verdadero si ha analizado con éxito los datos.
Antes de que apiCalls coloque una condición como esta:
if (! apiDataReceived) {apiCalls ()}
Así que si se llamaría a apiCalls () solo si no se analizan los datos.
¿Hace usted llamadas http y análisis o cualquier otra cosa en el método que llame después de onCreateView
como onStart
El código anterior está en kotlin. Si tiene algún problema, hágamelo saber en los comentarios.
Puede manejar la recreación de la vista por cheque si la vista es nula o no.
public class FragmentExample extends Fragment {
private View rootView;
public FragmentExample() {}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
if (rootView == null) {
rootView = inflater.inflate(R.layout.fragment_example_layout, container, false);
// Initialise your layout here
} else {
((ViewGroup) rootView.getParent()).removeView(rootView);
}
return rootView;
}
}
Un poco tarde para esta pregunta, pero gracias a YS, pude saber cómo funciona ViewPager. Estaba creando una aplicación con 4 pestañas y, en cualquier momento, noté que solo se estaban actualizando dos pestañas, lo que supongo que era un comportamiento predeterminado. Después de horas de investigación, comprendí que Android actualiza múltiples pestañas para brindar un desempeño de deslizamiento suave para el usuario; es posible que note que hubiera hecho clic en tab2, pero Android trae los datos para tab3 y los mantiene listos.
Aunque este comportamiento es bueno, tiene sus pros y sus contras. Ventajas: obtiene una experiencia de deslizamiento suave, sin que los datos se carguen desde un servidor externo cuando llegue a esa pestaña. Contras: tu implementación de backstack en pestañas podría ir por un lanzamiento. Cuando hace clic en una pestaña, el paginador de la vista en realidad llama a la pestaña más suave y terminará en un gran problema, si sus métodos están configurando backarrow (inicio) en la parte superior izquierda según lo que se encuentra en el backstack en la pestaña en la que se hizo clic.
setOffscreenPageLimit es la respuesta a esto. Si desea que funcione su marco backstack personalizado, y no desea que se llame a tab3 cuando se hace clic en tab2, simplemente debe establecer el valor en el número de pestañas. Por ejemplo, si tiene 4 pestañas, configure setOffScreePageLimit (4). Esto significaría que Android actualizaría los 4 fragmentos inicialmente, lo que representa una sobrecarga de rendimiento (que debe administrar correctamente). Pero, tu backstack y cambio de tabulación permanecen intactos. Espero que esto ayude.
uno tiene que .getCount()
el FragmentPagerAdapter
primero, luego .getCount()
devolverá un valor -
mientras que .getCount() - 1
debe configurarse como el límite predeterminado fuera de la pantalla:
TabsPagerAdapter adapter = new TabsPagerAdapter(getSupportFragmentManager());
/* the ViewPager requires a minimum of 1 as OffscreenPageLimit */
int limit = (adapter.getCount() > 1 ? adapter.getCount() - 1 : 1);
ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(limit);