it-swarm.com.de

Fragment aus ViewPager aktualisieren

Ich habe eine Activity mit einer ViewPager. Ich habe auch eine Dialog, die eine Liste mit einigen Elementen abruft, die der Benutzer auswählen wird. Wie kann ich nun Fragment aktualisieren, wo die Elemente als neue, diesem Fragment angehängte Ansichten angezeigt werden sollen? 

Hier ist der Adapter meines ViewPager:

public static class MyAdapter extends FragmentPagerAdapter {
    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return 1;
    }

    @Override
    public Android.support.v4.app.Fragment getItem(int position) {
        switch (position) {
        case 0:
            return new Fragment1();

        default:
            return null;
        }
    }
}

Hier ist das Fragment:

public class Fragment1 extends Fragment{

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onActivityCreated(savedInstanceState);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
}

@Override
public ViewGroup onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    ViewGroup view = (ViewGroup)inflater.inflate(R.layout.screen1, container, false);
    }
    return view;
}

}

Dies ist die Methode, die ich verwenden möchte, um Elemente zu meinem Fragment hinzuzufügen.

private void addItem() {

    // Instantiate a new "row" view.

    final ViewGroup[] newViews = new ViewGroup[selectedItems.length];


    for(int i = 0; i < selectedItems.length; i++){
        newViews[i] = (ViewGroup) LayoutInflater.from(this).inflate(
                    R.layout.animated_layout_item, mContainerView, false);

        // Set the text in each new row.
        ((TextView) newViews[i].findViewById(Android.R.id.text1)).setText(selectedItems[i]);

        // Because mContainerView has Android:animateLayoutChanges set to true,
        // adding this view is automatically animated.

            mContainerView.addView(newViews[i], 0);


        // Set a click listener for the "X" button in the row that will remove the row.
        OnClickListener listener = new MyAddItemListener(newViews[i], mContainerView, this);
        newViews[i].findViewById(R.id.delete_button).setOnClickListener(listener);

    }


}
46
Luis Lavieri

Fragment aus ViewPager aktualisieren

Sie müssen die getItemPosition(Object obj)-Methode implementieren.

Diese Methode wird beim Aufruf aufgerufen

notifyDataSetChanged()

auf Ihrer ViewPagerAdaper. Implizit gibt diese Methode einen POSITION_UNCHANGED-Wert zurück, der etwa Folgendes bedeutet: "Fragment ist dort, wo es sein sollte, also nichts ändern."

Wenn Sie also Fragment aktualisieren müssen, können Sie Folgendes tun:

  • Geben Sie POSITION_NONE immer von der getItemPosition()-Methode zurück. Was .__ bedeutet: "Fragment muss immer neu erstellt werden"
  • Sie können eine update () -Methode erstellen, mit der Ihr Fragment aktualisiert wird (Fragment behandelt Updates selbst).

Beispiel eines zweiten Ansatzes:

public interface Updateable {
   public void update();
}


public class MyFragment extends Fragment implements Updateable {

   ...

   public void update() {
     // do your stuff
   }
}

Und in FragmentPagerAdapter machen Sie so etwas:

@Override
public int getItemPosition(Object object) {
   MyFragment f = (MyFragment ) object;
   if (f != null) {
      f.update();
   }
  return super.getItemPosition(object);
}

Wenn Sie sich für den ersten Ansatz entscheiden, kann dies folgendermaßen aussehen:

@Override
public int getItemPosition(Object object) {
   return POSITION_NONE;
}

Hinweis: Es lohnt sich, darüber nachzudenken, welchen Ansatz Sie ergreifen werden.

109
Simon Dorociak

Ich hatte einige Probleme, so dass in diesem Fall immer FragmentPagerAdapter vermieden und FragmentStatePagerAdapter verwendet wird.  

Es funktioniert für mich. Ich hoffe es funktioniert auch für dich.

26
Yogendra

Ich implementiere eine App-Demo nach der Antwort von Sajmon. Nur für jeden, der diese Frage sucht.

Sie können auf den Quellcode unter GitHub zugreifen.

 enter image description here

13
li2

In Ihrem PagerAdapter überschreiben Sie getItemPosition

@Override
public int getItemPosition(Object object) {
// POSITION_NONE makes it possible to reload the PagerAdapter
return POSITION_NONE;
}

Fügen Sie anschließend viewPager.getAdapter (). NotifyDataSetChanged (); diesen Code wie folgt

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            viewPager.getAdapter().notifyDataSetChanged();
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

sollte arbeiten.

10
madhu sudhan

Sie können das Fragment auf zwei verschiedene Arten aktualisieren:

Erster Weg

wie @Sajmon

Sie müssen die getItemPosition(Object obj)-Methode implementieren.

Diese Methode wird beim Aufruf aufgerufen

notifyDataSetChanged()

Ein Beispiel finden Sie in Github und weitere Informationen in diesem post .

 enter image description here

Zweiter Weg

Mein Ansatz zum Aktualisieren von Fragmenten im Viewpager besteht darin, die setTag()-Methode für jede instantiierte Ansicht in der instantiateItem()-Methode zu verwenden. Wenn Sie also die Daten ändern oder die benötigte Ansicht für ungültig erklären möchten, können Sie die findViewWithTag()-Methode des ViewPagers aufrufen, um die zuvor instanziierte Ansicht abzurufen und sie nach Belieben zu ändern/zu verwenden, ohne jedes Mal eine neue Ansicht löschen oder erstellen zu müssen Sie möchten einen Wert aktualisieren.

@Override
public Object instantiateItem(ViewGroup container, int position) {
    Object object = super.instantiateItem(container, position);
    if (object instanceof Fragment) {
        Fragment fragment = (Fragment) object;
        String tag = fragment.getTag();
        mFragmentTags.put(position, tag);
    }
    return object;
}

public Fragment getFragment(int position) {
    Fragment fragment = null;
    String tag = mFragmentTags.get(position);
    if (tag != null) {
        fragment = mFragmentManager.findFragmentByTag(tag);
    }
    return fragment;
}

Ein Beispiel finden Sie in Github oder weitere Informationen in diesem post :

 enter image description here

4
Cabezas

Sehr einfach die Methode im Fragment zu überschreiben:

@Override

public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if(isVisibleToUser){
        actionView();
    }
    else{
        //no
    }      
}
3
Issac Balaji

Wenn Sie Kotlin verwenden, können Sie Folgendes tun:

1. Zuerst solltest du Interface erstellen und in deine Fragment implementieren

interface RefreshData {
    fun refresh()
}

class YourFragment : Fragment(), RefreshData {
    ...
    override fun refresh() {
        //do what you want
    }
}

2. Nächster Schritt füge OnPageChangeListener zu deiner ViewPager hinzu

viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
    override fun onPageScrollStateChanged(state: Int) { }

    override fun onPageSelected(position: Int) {
        viewPagerAdapter.notifyDataSetChanged()
        viewPager.currentItem = position
    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { }
})

3. Überschreiben Sie getItemPosition in Ihrer Adapter

override fun getItemPosition(obj: Any): Int {
    if (obj is RefreshData) {
        obj.refresh()
    }
    return super.getItemPosition(obj)
}
2
Danil

Eine sehr einfache und dennoch effektive Lösung zum Aktualisieren Ihrer Fragmentansichten . Verwenden Sie die setUserVisibleHint()-Methode. Sie wird aufgerufen, wenn das Fragment für den Benutzer sichtbar ist. Dort können Sie unsere Ansicht aktualisieren (setText() oder setVisibility() usw.). 

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if(isVisibleToUser){
       //Write your code to be executed when it is visible to user
    }
}

In meinem Fall hat es funktioniert. Ich hoffe es hilft! 

2
Tahmid Rahman

Akzeptierte Antwort ist nicht verständlich, deshalb einfache Lösung hinzugefügt. nach langem Kampf Arbeitslösung finden.

Einfach Benachrichtigen Sie Ihren Adapter , es funktioniert erstaunlich,

Referenzcode

 void setAdapter(int position) {
        PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(pagerAdapter);
        // when notify then set manually current position.
        viewPager.setCurrentItem(position);
        pagerAdapter.notifyDataSetChanged();
    }

rufen Sie diesen Code auf, wenn Sie den Adapter festlegen und wenn Sie die Benutzeroberfläche aktualisieren möchten.

In deinem Fragment füge diesen Code zum Aktualisieren hinzu

((YourActivityName) getContext()).setAdapter(selectedTabPosition);

Verwenden Sie instanceof für den Umwandlungskontext.

Dieser Code dient nur dazu, wer eine Lösung findet.

2
Yogesh Rathi

Vielleicht sollte Ihre Methode zum Hinzufügen von Elementen zu fragment public sein (in das gewünschte Fragment eingefügt werden) und Parameter denselben Typ haben wie selectedItems. 

Dadurch wird es aus der Aktivität sichtbar, die das Array und die Elemente von selectItems haben wird. 

p.s. Nennen Sie es besser addItemsFromArray(typeOfSelectedItems[] pSelectedItems), weil der Name addItem() ziemlich unbeschreiblich ist 

Edit: stackoverflow hat gerade ein ähnliches Thema vorgeschlagen :) Check here für detaillierte Ideenimplementierung .. :)

1
Ewoks

ich hatte 4 Fragmente im ViewPager, aber ich wollte nur ein Fragment "FavoriteFragment" an der Position 0 des ViewPagers aktualisieren, jedes Mal, wenn der Benutzer auf dieses Fragment klickt ein Fragment möchte ich. Ich habe es versucht und es funktioniert für mich:

in meinem FavoriteFragment habe ich onResume () überschrieben

@Override
    public void onResume() {
        super.onResume();
        updateUI(); // code to update the UI in the fragment
    }

in der Activity Hosting des viewPagers überschreiben Sie addOnPageChangeListener() und fügen Sie diesen Code hinzu

mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                super.onPageSelected(position);

                if(position == 0) { // 0 = the first fragment in the ViewPager, in this case, the fragment i want to refresh its UI
                    FavoritesFragment fragment = (FavoritesFragment) mViewPager.getAdapter().instantiateItem(mViewPager, position); 
                    fragment.onResume(); // here i call the onResume of the fragment, where i have the method updateUI() to update its UI
                    mViewPager.getAdapter().notifyDataSetChanged();
                }
            }
        });

und es funktioniert perfekt für mich, um nur das eine Fragment zu aktualisieren, das ich möchte.

0
korchix

1) Erstellen Sie einen Handler in dem Fragment, das Sie aktualisieren möchten.

public static Handler sUpdateHandler;

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ...

        sUpdateHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                // call you update method here.
            }
        };
    }

2) Rufen Sie im Activity/Fragment/-Dialogfeld, wo immer der Aktualisierungsaufruf ausgelöst werden soll, die Referenz zu diesem Handler ab und senden Sie eine Nachricht (Ihr Fragment wird aktualisiert)

// Check if the fragment is visible by checking if the handler is null or not.
Handler handler = TaskTabCompletedFragment.sUpdateHandler;
if (handler != null) {
    handler.obtainMessage().sendToTarget();
}
0
Astonvish32

Da keine der oben genannten Antworten den Trick für mich getan hat, ist hier meine Lösung:

Ich habe den POSITION_NONE Mit dem Laden von setUserVisibleHint(boolean isVisibleToUser) anstelle von onStart() kombiniert

Wie hier zu sehen: https://stackoverflow.com/a/25676323/497366

In der Fragment:

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // load data here
    }else{
       // fragment is no longer visible
    }
}

und in der FragmentStatePagerAdapter wie in der oberen Antwort hier von Simon Dorociak zu sehen https://stackoverflow.com/a/18088509/497366 :

@Override
public int getItemPosition(@NonNull Object object) {
    return POSITION_NONE;
}

Jetzt laden die Fragmente die Daten jedes Mal neu in ihre Ansichten, wenn sie dem Benutzer angezeigt werden.

0
Björn Kechel