it-swarm.com.de

Android wie man das Aktualisieren von Fragmenten bei einem Tabwechsel beendet

Ich habe folgenden Code:

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;
    }

}

Ich erstelle eine Bibliotheksanwendung, bei der die Navigation über Registerkarten erfolgt. Das Problem ist, dass jedes Mal, wenn ich von der dritten Registerkarte zur ersten oder ersten zur dritten Registerkarte wechsle, der Inhalt der Registerkarte aktualisiert wird. Ich möchte die Aktualisierung verhindern Hilfe bitte ?

36
Monzer Yaghi

Standardmäßig erstellt ViewPager die Fragmente neu, wenn Sie die Seite wischen. Um dies zu verhindern, können Sie eine der folgenden drei Methoden ausprobieren:

1. Rufen Sie in der onCreate() Ihrer Fragmente setRetainInstance(true) auf.

2. Wenn die Anzahl der Fragmente fest und relativ klein ist, fügen Sie in Ihrer onCreate() den folgenden Code hinzu:

mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(limit);         /* limit is a fixed integer*/

3. Verwenden Sie FragmentPagerAdapter als Teil Ihres ViewPager.

Wenn ich mich richtig erinnere, ist die zweite Option vielversprechender. Aber ich fordere Sie dringend auf, alle drei zu testen und zu sehen, welche von ihnen funktionieren.

107
Y.S

man muss zuerst den FragmentPagerAdapter instanziieren, dann gibt .getCount() einen Wert zurück -

while .getCount() - 1 sollte als Standardlimit für Off-Screen festgelegt werden:

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);
21
Martin Zeitler

sie können die Neuerstellung von Ansichten verwalten, indem Sie prüfen, ob die Ansicht null ist oder nicht

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;
    }
}
4
Ahmad Nasser

Rufen Sie im onCreate () Ihrer Fragmente setRetainInstance (true) auf.

3
Mohsen mokhtari

Ein bisschen spät zu dieser Frage, aber dank Y.S. habe ich erfahren, wie ViewPager funktioniert. Ich habe eine App mit 4 Registerkarten erstellt und zu jedem Zeitpunkt festgestellt, dass nur zwei Registerkarten aktualisiert wurden, was vermutlich ein Standardverhalten war. Nach Stunden der Untersuchung, verstand ich, dass Android Auffrischungen mehrere Tabs für den Benutzer in einer glatten swiping Leistung zu bringen - Sie könnten feststellen, dass Sie tab2 geklickt haben würde, aber Android Bringt die Daten für tab3 ein und hält sie bereit.

Obwohl dieses Verhalten gut ist, hat es Vor- und Nachteile. Vorteile - Sie erhalten ein reibungsloses Swiping-Erlebnis, ohne dass Daten von einem externen Server geladen werden, wenn Sie in dieser Registerkarte landen. Nachteile - Ihre Backstack-Implementierung in Registerkarten könnte problematisch werden. Wenn Sie eine Registerkarte klicken, ruft die Ansicht Pager tatsächlich glatten Reiter und Sie werden in einer großen Schwierigkeiten am Ende, wenn Ihre Methoden einrichten backarrow (home) oben links auf dem, was in der geklickten Registerkarte im Backstack ist.

setOffscreenPageLimit ist die Antwort darauf. Wenn Ihr benutzerdefiniertes Backstack-Framework funktionieren soll und tab3 nicht aufgerufen werden soll, wenn auf tab2 geklickt wird, müssen Sie lediglich den Wert auf die Anzahl der Registerkarten festlegen. Wenn Sie beispielsweise 4 Registerkarten haben, setzen Sie setOffScreePageLimit (4). Dies würde bedeuten, dass Android würde zunächst alle vier Fragmente aufzufrischen, was ein bisschen ein Performance-Overhead ist (die Sie richtig verwalten sollte.) Aber, Ihre Backstack und Reiter Schalt bleiben intakt. Hope this hilft.

Da die Aktivität ActionBar.TabListener implementiert, wird die Aktivität onCreate () immer wieder aufgerufen. Fügen Sie also den folgenden Code in die onResume () -Methode ein:

   // 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) {
        }
    });
1

In meinem Fall funktioniert der obige Vorschlag nicht.

Um die Wiederherstellung von Fragmenten einzuschränken, was ich getan habe:

In onCreateView können Sie die aufgeblasene Ansicht in einer globalen Variablen speichern und nur dann initialisieren, wenn es sich um null handelt, wie im folgenden 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
}

Nun, wenn Sie einige Daten analysieren und sie in RecyclerView oder eine andere View eintragen

  1. Machen Sie eine globale Variable wie im obigen Code apiDataReceived

  2. Setzen Sie es auf true, wenn Sie die Daten erfolgreich analysiert haben.

  3. Bevor apiCalls eine Bedingung wie diese setzt:

    if (! apiDataReceived) {apiCalls ()}

Also, wenn apiCalls () nur aufgerufen würde, wenn die Daten nicht analysiert werden.

Führen Sie Ihre http-Aufrufe und Parsing oder andere Methoden aus, die nach onCreateView aufgerufen wurden, wie onStart.

Der obige Code ist in Kotlin. Wenn Sie auf ein Problem stoßen, teilen Sie es mir in Kommentaren mit.

0
Suraj Vaishnav