2013-03-16 19 views
5

Jestem na poziomie początkującym w programowaniu Androida, więc potrzebuję twojej szczerej pomocy w tym zakresie. Niech ktoś mi pomoże.Komunikacja fragmentów i fragmentów w Androidzie

Próbuję zbudować przesuwne UI stosując fragmenty

więc moja wątpliwość jest rzeczywista ... Mam Fragment (słownie Fragment A) ma TextView i Button w nim i inną Fragment (słownie Fragment B). Ma w sobie TextView. Muszę pokazać zawartość Fragment A w Fragment B TextView, kiedy nacisnąłem Button w FRAGMENT A. Próbowałem na wiele sposobów, niestety nie miałem prawidłowego wyjścia. Jestem pewien, że ludzie o tym wiedzą. Proszę pomóż mi.

Dziękuję

+0

Powinieneś przechowywać tekst w nadrzędnej aktywności i przekazać go do FRAGMENTU B podczas ładowania. – dmaxi

+0

@dmaxi Ale nie wiem, jak przechowywać tekst w rodzica Aktywność – sam

+0

Utwórz zmienną składową typu String i nie zapomnij zapisać jej w pakiecie w wywołaniu zwrotnym onSaveInstanceState(). Powinieneś także przeczytać JavaDoc działania i fragmentu. – dmaxi

Odpowiedz

14

Należy zrobić przemyślane słuchacza, tak Fragmenty wciąż nie zależą od siebie i mogą być używane w trybie jednego lub dwóch tafli. Aktywność powinna obsługiwać słuchaczy obu fragmentów.

Oto przykład działania z dwóch fragmentów:

package com.example; 

import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 

import com.example.fragment.FragmentA; 
import com.example.fragment.FragmentA.TextChangeListener; 
import com.example.fragment.FragmentB; 

public class ActivityAB extends FragmentActivity { 

    FragmentA fragmentA; 
    FragmentB fragmentB; 

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

     FragmentManager manager = getSupportFragmentManager(); 
     fragmentA = (FragmentA) manager.findFragmentById(R.id.fragmentA); 
     fragmentB = (FragmentB) manager.findFragmentById(R.id.fragmentB); 

     fragmentA.setTextChangeListener(new TextChangeListener() { 

      @Override 
      public void onTextChange(CharSequence newText) { 
       fragmentB.updateTextValue(newText); 
      } 
     }); 
    } 

} 

Oto fragment A, który posiada własny detektor zmian tekst zdarzenia.

package com.example.fragment; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.TextView; 

import com.example.R; 

public class FragmentA extends Fragment { 

    TextChangeListener listener; 

    public interface TextChangeListener { 
     public void onTextChange(CharSequence newText); 
    } 

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

     Button btn = (Button) view.findViewById(R.id.button1); 
     final TextView textView = (TextView) view.findViewById(R.id.textView1); 

     btn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       if (null != listener) { 
        listener.onTextChange(textView.getText()); 
       } 

      } 
     }); 
     return view; 
    } 

    public void setTextChangeListener(TextChangeListener listener) { 
     this.listener = listener; 
    } 
} 

Oto fragment B, który ma metodę publiczną do aktualizowania pola tekstowego:

package com.example.fragment; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

import com.example.R; 

public class FragmentB extends Fragment { 

    TextView textView; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_b, container, false); 
     textView = (TextView) view.findViewById(R.id.textView1); 
     return view; 
    } 

    public void updateTextValue(CharSequence newText) { 
     textView.setText(newText); 
    } 
} 

Układ ActivityAB xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:baselineAligned="false" 
    android:orientation="horizontal" > 

    <fragment 
     android:id="@+id/fragmentA" 
     android:name="com.example.fragment.FragmentA" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:layout_weight="1" /> 

    <fragment 
     android:id="@+id/fragmentB" 
     android:name="com.example.fragment.FragmentB" 
     android:layout_width="0dp" 
     android:layout_height="match_parent" 
     android:layout_weight="1" /> 

</LinearLayout> 

Fragment A xml układ:

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

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="This is text" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

    <Button 
     android:id="@+id/button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Show" /> 

</LinearLayout> 

Układ fragmentu xml:

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

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="(here will be text)" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

</LinearLayout> 
+0

cześć, dziękuję za odpowiedź .. ale to nie działa dla mnie .. I jeszcze jedno nie mam dwóch oddzielnych fragmentów layout in activity ab (ofcourse mam dwie klasy fragmentów i odpowiadający im plik xml układu) ... zamiast tego mam tylko jeden układ fragmentów i dynamicznie zmieniam zawartość ... możesz spróbować jeszcze raz dla mnie .. – sam

+0

Metoda 'onTextChange' zostanie wywołana podczas kliknięcia przycisku. Tak więc użyj tego wywołania zwrotnego, aby zastąpić fragment A fragmentem B, a także ustaw tekst, który otrzymujesz, np. 'fragmentB.updateTextValue (newText); this.showFragmentB(); ' – andrew

+0

Ta opinia nie ma zastosowania w przypadku ogólnym. A co jeśli używasz pod-fragmentów? Fragment nadrzędny i fragment potomny mogą również potrzebować komunikować się ze sobą, bez konieczności przechodzenia aż do działania zawierającego, aby to zrobić. W niektórych przypadkach Aktywność roota może zawierać całą aplikację (tj. Aplikację opartą na tabulatorach). Nie ma mowy, aby każda pojedyncza komunikacja między każdym pojedynczym pod-komponentem była prowadzona w jednym miejscu (poważne naruszenie antypróbowania odpowiedzialności indywidualnej) – Marchy

0

Komunikacja między dwoma fragmentami powinna zawsze odbywać się poprzez ich aktywność fragmentu w celu utrzymania luźne sprzężenie pomiędzy fragmentami, więc jeśli chcesz wysłać jakieś dane z jednego fragmentu A do innego fragmentu B można tworzyć słuchacza i zaimplementuj go w swojej aktywności fragmentu i od wewnątrz fragmentA możesz wystrzelić zdarzenie za pomocą tego słuchacza i wysłać dane do aktywności fragmentu, więc teraz aktywność fragmentu będzie również posiadała obiekt fragmentu B, więc aktywność fragmentu może bezpośrednio wywoływać metodę fragmentu B i wyślij dane do fragmentu B ...

2

To brzmi tak, jakby twoje ustawienia może być coś podobnego - główną działalność w/Fragmenta [dodane] i FragmentB [dodane]. W tym przypadku delegowałbym wiadomości/akcje pomiędzy tymi dwoma fragmentami za pośrednictwem MainActivity. Umożliwienie obsługi wiadomości/akcji MainActivity ułatwia także "specjalne" orkiestracje, które mogą być potrzebne w bardziej złożonej sytuacji pomiędzy Fragmentami.Na przykład:

public interface FragmentCommunicator 
{ 
    public void sendMessage (String broadcastMessage); 
    public void takeAction (String name, int action, Fragment frag); 
} 

public class MainActivity extends Activity implements FragmentCommunicator 
{ 
    Fragment fragA; 
    Fragment fragB; 
    ... 
    @Override 
    public void sendMessage (String msg) 
    { 
     if (msg.Contains("Send To fragA")) 
      fragA.receiveMsg(msg); 
     ... 
    } 
    @Override 
    public void takeAction (String name, int action, Fragment frag) 
    { 
    if (action == CLOSE) 
      removeFragment(name, frag); 
     ... 
    } 
} 

public class FragmentA extends Fragment 
{ 
    ... 
@Override 
public void onClick(View v) 
{ 
    FragmentCommunicator inter = (FragmentCommunicator) getActivity(); 
    inter.sendMessage("the txt/information/etc you want to send to fragB");  
} 
} 

public class FragmentB extends Fragment 
{ 
    ... 
    public void receiveMsg (String msg) 
    { 
     textView.setText(msg); 
    } 
} 

Zapomniałem napisać część wysyłkową FragmentA. Mam nadzieję, że to pomoże.

0

developer.android.com

Aby umożliwić Fragment aby komunikować się ze swoją działalnością, można zdefiniować interfejs w klasie Fragment i wdrożyć go w ramach działalności . Fragment przechwytuje implementację interfejsu w trakcie jego metody onAttach() i może następnie wywoływać metody interfejsu w celu komunikowania się z działaniem.

Przykład: - http://wiki.workassis.com/android-fragment-communication/

ref: - https://developer.android.com/training/basics/fragments/communicating.html

-1

jego faktycznie dość proste, wystarczy wykonać następujące kroki:

  1. Więc stworzył dwa fragmenty A i B, teraz tworzą swoje mózgi, tj. pliki klasy Java. Nazwijmy je JClass A (dla fragmentu A) i JClass B (dla Fragment B)

2.You przycisk dostał w ciebie Frag A więc idź do JClass A, i tym, że uzyskać tekst string typy użytkowników i naciśnięcie przycisku takiego zdarzenia: // wystarczy przesłonić metodę onCreate.

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.<name of your fragment A.xml file>,container,false); 

    userInput = (EditText)view.findViewById(R.id.<Id that you gave to EditText field in which user enters text>); 

    Button myButton = (Button)view.findViewById(R.id.<id of your Button>); 
    myButton.setOnClickListener(
      new Button.OnClickListener(){ 
       public void onClick(View v){ 
        JClassB.setText(userInput.getText().toString());/*Replace JClassB with the java class of Fragment B*/ 

       } 
      } 
    ); 

    return view; 
} 
  1. I wreszcie w swój JClass B (plik Java do fragmentu B):

    public class BottomSectionFrag rozciąga Fragment {

    private static TextView userText; 
    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        View view = inflater.inflate(R.layout.fragmentB, container, false); 
        userText = (TextView)view.findViewById(R.id.userText); 
        return view; 
    } 
    public static void setText(String text){ 
        userText .setText(text); 
    
    } 
    

    }

Voila !!

P.S. To jest mój pierwszy w historii post na pileOverFlow: D

Spokój.

0

Podoba mi się aktywność pośrednika między komunikacją fragmentów i fragmentów. ale inną rzeczą, którą lubię, jest użycie architektury event bus, która oferuje również oddzielenie.

Powiązane problemy