J'ai le code suivant :
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;
}
}
Je crée une application de bibliothèque dans laquelle la navigation se fait par onglets, le problème est à chaque fois que je passe du troisième onglet au premier ou du premier au troisième, le contenu des onglets est rafraîchissant, je veux empêcher le rafraîchissement, tout Aidez-moi, s'il vous plaît ?
Par défaut, ViewPager
recrée les fragments lorsque vous balayez la page. Pour éviter cela, vous pouvez essayer l'une des trois choses suivantes:
1. Dans la onCreate()
de vos fragments, appelez setRetainInstance(true)
.
2. Si le nombre de fragments est fixe et relativement petit, alors dans votre onCreate()
ajoutez le code suivant:
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(limit); /* limit is a fixed integer*/
3. Utilisez un FragmentPagerAdapter
dans le cadre de votre ViewPager
.
Si je me souviens bien, la deuxième option est plus prometteuse. Mais je vous exhorte à essayer les trois et à voir lesquels fonctionnent.
il faut d'abord instance de FragmentPagerAdapter
, puis .getCount()
retournera une valeur -
tandis que .getCount() - 1
doit être défini comme limite hors écran par défaut:
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);
vous pouvez gérer les loisirs de la vue en vérifiant si la vue est nulle ou non
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;
}
}
Dans onCreate () de vos fragments, appelez setRetainInstance (true)
Un peu tard pour cette question, mais grâce à Y.S., j'ai appris comment fonctionne ViewPager. Je construisais une application avec 4 onglets et à tout moment, j'ai remarqué que seulement deux onglets étaient en cours d'actualisation, ce qui, je suppose, était un comportement par défaut. Après des heures d'enquête, j'ai compris que Android rafraîchit plusieurs onglets pour apporter une performance de balayage fluide à l'utilisateur - vous remarquerez peut-être que vous auriez cliqué sur tab2, mais Android apporte les données de tab3 et les garde prêtes.
Bien que ce comportement soit bon, il a ses avantages et ses inconvénients. Avantages - vous obtenez une expérience de balayage fluide, sans que les données soient chargées à partir d'un serveur externe lorsque vous atterrissez dans cet onglet. Contre-votre implémentation de backstack dans les onglets pourrait aller de pair. Lorsque vous cliquez sur un onglet, le téléavertisseur de vue appelle en fait un onglet plus fluide et vous vous retrouverez dans un gros problème, si vos méthodes configurent backarrow (home) en haut à gauche en fonction de ce qui se trouve dans la backstack dans l'onglet cliqué.
setOffscreenPageLimit est la réponse à cela. Si vous souhaitez que votre infrastructure de backstack personnalisée fonctionne et que vous ne voulez pas que tab3 soit appelé lorsque vous cliquez sur tab2, vous devez simplement définir la valeur sur le nombre d'onglets. Par exemple, si vous avez 4 onglets, définissez setOffScreePageLimit (4). Cela signifierait que Android rafraîchirait initialement les 4 fragments, ce qui est un peu un surcoût de performance (que vous devriez gérer correctement). Mais, votre backstack et changement de tabulation restent intacts. aide.
Étant donné que l'activité implémente ActionBar.TabListener, onCreate () de l'activité est appelée à plusieurs reprises. Placez donc le code suivant dans la méthode 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) {
}
});
Dans mon cas, la suggestion ci-dessus ne fonctionne pas.
Pour restreindre la recréation d'un fragment, ce que j'ai fait:
Dans onCreateView
, vous pouvez stocker la vue gonflée dans une variable globale et l'initialiser uniquement si elle est null
, comme dans ce code:
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
}
Maintenant, si vous analysez des données et les remplissez dans RecyclerView
ou tout autre View
Créez une variable globale comme dans le code ci-dessus apiDataReceived
Définissez-le sur true si vous avez correctement analysé les données.
Avant apiCalls, placez une condition comme celle-ci:
if (! apiDataReceived) {apiCalls ()}
Donc, si apiCalls () ne sera appelé que si les données ne sont pas analysées.
Faites vos appels http et votre analyse ou toute autre chose dans la méthode qui a appelé après onCreateView
comme onStart
Le code ci-dessus est en kotlin, si vous rencontrez un problème, faites-le moi savoir dans les commentaires.