3

Ich habe eine Aktivität und zwei Fragmente für eine tablayout enthält eine viewpager. Nun kann ich von dem Fragment zu der Aktivität kommunizieren, indem ich die Google Callback-Schnittstelle von Google implementiere. Aber wie kann ich den anderen Weg von Aktivität zu Fragment kommunizieren? Wenn etwas in der Aktivität (externe Ereignisse) passiert, möchte ich das Fragment aktualisieren. Ich schaffte es das Frag1 Fragment mitKommunikation von Aktivität zu Fragment mit ViewPager

MyFragmentPagerAdapter a = (MyFragmentPagerAdapter) viewPager.getAdapter(); 
Frag1 frag = (Frag1) a.getItem(0); 

zu bekommen, aber wenn ich öffentliche Methoden auf frag nennen erhalte ich eine Illegal: Fragment nicht wahrscheinlich Aktivität gebunden, weil getItem (0) eine neue Instanz von Frag1 zurückkehrt und dies ist nicht angebracht Aber ... gibt es jemanden, der eine saubere Lösung für diesen ganzen Viewpager -> Activity to Fragment-Kommunikation bereitstellen kann?

Einige Code für Sie:

in Aktivität:

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager); 
     if (viewPager != null) { 
      viewPager.setAdapter(new MyFragmentPagerAdapter(getSupportFragmentManager())); 
     } 

     TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs); 
     if (tabLayout != null) { 
      tabLayout.setupWithViewPager(viewPager); 
     } 
} 

Aktivität Layout:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:orientation="vertical" 
    tools:context="com.MainActivity"> 

    <android.support.design.widget.TabLayout 
     android:id="@+id/sliding_tabs" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <android.support.v4.view.ViewPager 
     android:id="@+id/viewpager" 
     android:layout_width="match_parent" 
     android:layout_height="0px" 
     android:layout_weight="1"/> 
</LinearLayout> 

MyFragmentPagerAdapter:

public class MyFragmentPagerAdapter extends FragmentPagerAdapter { 

    final int PAGE_COUNT = 2; 
    private String tabTitles[] = new String[] { "tab1", "tab2" }; 

    public MyFragmentPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     switch (position) { 
      case 0: 
       return Frag1.newInstance(position + 1); 
      case 1: 
       return Frag2.newInstance(position + 1); 
      default: 
       return null; 
     } 
    } 

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

    @Override 
    public CharSequence getPageTitle(int position) { 
     return tabTitles[position]; 
    } 
} 

Frag1:

public class Frag1 extends Fragment { 
    public static final String ARG_PAGE = "ARG_PAGE"; 

    private int mPage; 

    private onFrag1InteractionListener mListener; 

    public Frag1() { 
     // Required empty public constructor 
    } 

    /** 
    * Use this factory method to create a new instance of 
    * this fragment using the provided parameters. 
    * 
    * @return A new instance of fragment Frag1. 
    */ 
    public static Frag1 newInstance(int page) { 
     Frag1 fragment = new Frag1(); 
     Bundle args = new Bundle(); 
     args.putInt(ARG_PAGE, page); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if (getArguments() != null) { 
      mPage = getArguments().getInt(ARG_PAGE); 
     } 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_1, container, false); 
     return view; 
    } 


    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     if (context instanceof onFrag1InteractionListener) { 
      mListener = (onFrag1InteractionListener) context; 
     } else { 
      throw new RuntimeException(context.toString() 
        + " must implement onFrag1InteractionListener"); 
     } 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mListener = null; 
    } 

    public interface onFrag1InteractionListener { 
     // TODO: Update argument type and name 
     void onFrag1Interaction(Action action); 
    } 
+0

AppCompatActivity anstelle von Activity erweitern, dann prüfen, was gerade passiert? – Nitesh

+0

Aktivität erweitert AppCompatActivity – Zuop

+0

Was meinen Sie mit externen Ereignissen? Angenommen, Sie möchten das Fragment aktualisieren, wenn die Registerkarten kopiert werden. So, – Nitesh

Antwort

1

Sie müssen einig Ereignis-Listener-Logik, wo das Fragment-Register mit der Aktivität für den Fall einzurichten es will. Das Fragment sollte bei der Erstellung registriert und bei der Vernichtung aufgehoben werden.

Wenn dann das Ereignis eintritt, durchläuft die Aktivität die Liste der registrierten Listener und benachrichtigt sie über das Ereignis.

Ich gebe ein ausführliches Beispiel in this answer.

Sie können eine Event-Bus-Bibliothek verwenden, um einen Teil der Verkabelung zwischen der Aktivität und den Fragmenten zu vereinfachen.

+0

Ich befolgte die Anweisungen im Link Ihrer Antwort und das löste es. Ich finde es komisch, eine Schnittstelle zu implementieren, um von Fragment -> Activity zu kommunizieren und dann zusätzlich eine andere Schnittstelle, um von Activity zu kommunizieren -> Fragment – Zuop

+0

Mein Beispiel hat keine Schnittstelle für die Aktivität implementiert, aber das ist immer noch eine gute Übung für Unit Testing und Wiederverwendung. Viele Beispiele von Google für Dinge wie Navigations-Schublade tun dies. –

+0

Oh okay .. Ich muss Ihre Antwort falsch interpretiert haben, aber nvm es funktioniert jetzt. Obwohl Sie gesagt haben: "Definieren Sie eine Listener-Schnittstelle. Normalerweise mache ich dies als eine innere Schnittstelle innerhalb der Aktivität" in der Verknüpfung :) – Zuop

Verwandte Themen