2017-10-15 7 views
0

Je fais des tests avec des fragments à étudier à ce sujet. Et j'ai un doute.Comment envoyer des données d'un fragment à un autre sans un clic sur un événement?

J'ai une activité principale avec une barre d'outils avec un seul élément et lorsque cet élément est cliqué, j'ajoute un fragment A qui a une vue en liste.

Puis je clique dans un élément de la vue liste, le fragment A est retiré et son fragment B est à remplacer fragment A. Le fragment B a un textview pour afficher le texte de l'élément cliqué sur le fragment A.

Pour transmettre les données de l'élément cliqué dans la vue liste du fragment A à la vue texte du fragment BI, vous devez également ajouter un bouton sur le fragment B xml et cliquer sur ce bouton pour envoyer les données de l'élément cliqué au fragment B et la vue de texte est mise à jour avec le texte correct de l'élément cliqué.

Mais ce n'est pas possible de le faire automatiquement? Si cette méthode "sendDataToFragmentB (View View)" est appelée sur la méthode addText (String), elle apparaît comme NullPointerException in FragmentB.addText(java.lang.String). Mais si j'ai le bouton dans le fragment xml avec le onClick = "sendDataTofragmentB" lorsque le bouton est cliqué cela fonctionne.

Interface:

public interface Listener { 
    public void addText(String text); 
} 

activité principale

public class MainActivity extends AppCompatActivity implements Listener { 

    Toolbar toolbar; 
    FragmentManager manager; 
    private String text; 

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

     manager = getFragmentManager(); 

     toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     getSupportActionBar().setTitle("Pets"); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     String msg = ""; 

     if (item.getItemId() == R.id.search) { 
       msg = "search"; 
       AddFragmentA(); 
     } 
     Toast.makeText(this, msg + "clicked !", Toast.LENGTH_SHORT).show(); 
     return super.onOptionsItemSelected(item); 
    } 
    @Override 
    public void addText(String text) { 
     this.text = text; 

     Toast.makeText(this, "Text Received in Activity" + text, Toast.LENGTH_SHORT).show(); 
     sendDataToFragmentB(); 
    } 
    public void sendDataToFragmentB(View view) { 

      FragmentB fragmentB = (FragmentB) manager.findFragmentByTag("fragB"); 
      fragmentB.addText(text); 

    } 
} 

fragment A:

public class FragmentA extends Fragment { 
    private static final String TAG = FragmentA.class.getSimpleName(); 
    private ListView listItems; 

    private String[] items = { 
      "item1", 
      "item2", 
    }; 

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

     ArrayAdapter<String> adapter = 
       new ArrayAdapter<String>(getActivity().getApplicationContext(), 
         android.R.layout.simple_list_item_1, android.R.id.text1, items); 
     listItems.setAdapter(adapter); 

     listItems.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
       int positionCode = i; 
       String clickedValue = (String) adapterView.getItemAtPosition(i); 

       Listener listener = (Listener) getActivity(); 
       listener.addText(clickedValue); 

       Toast.makeText(getActivity().getApplicationContext(), clickedValue, Toast.LENGTH_SHORT).show(); 
       removeFragmentA(); 
       AddFragmentB(); 
      } 

     }); 

     return view; 
    } 

    public void removeFragmentA(){ 
     FragmentA fragmentA = (FragmentA) getFragmentManager().findFragmentByTag("fragA"); 
     FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
     if(fragmentA !=null){ 
      transaction.remove(fragmentA); 
      transaction.commit(); 
     } 
     else{ 
      Toast.makeText(this.getActivity(), "Fragment A not found", Toast.LENGTH_SHORT).show(); 
     } 
    } 
    public void AddFragmentB(){ 

     FragmentB fragmentB = new FragmentB(); 
     FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
     transaction.add(R.id.container, fragmentB, "fragB"); 
     transaction.commit(); 
    } 
} 

fragment B:

public class FragmentB extends Fragment { 
    private TextView txvResult; 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_b, container, false); 
     txvResult = (TextView) view.findViewById(R.id.txvResult); 
     return view; 
    } 
    public void addText(String text){ 
     String result = text; 
     txvResult.setText(result); 
    } 
} 
+0

Bien qu'il y ait un autre problème qui affectera ceci, vous devriez au moins essayer de raisonner à travers votre code comme vous l'avez maintenant. Dans 'onItemClick()', regardez l'ordre des choses. Voulez-vous vraiment appeler 'listener.addText()' avant même d'avoir échangé le 'Fragment's? Avant que l'instance de 'FragmentB' est même créée? –

+0

Au lieu d'un écouteur, qui n'envoie pas les données dans un paquet et n'y accède directement –

+0

Merci. Aussi le même problème avec bundle. Mais le problème est sur la méthode onCreateView dans String text = getArguments(). GetString ("clickedValue"); – JonD

Répondre

1

Réponse courte: Vous voulez utiliser Bundles. Vous pouvez essayer quelque chose comme ça

public void AddFragmentB(String clickedText){ 


    FragmentB fragmentB = new FragmentB(); 

    Bundle bundle = new Bundle(); 
    bundle.putString(R.string.clicked_text_key, clickedText); 
    fragmentB.setArguments(bundle); 

    FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
    transaction.add(R.id.container, fragmentB, "fragB"); 
    transaction.commit(); 
} 

FragmentB

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

    addText(); 

    return view; 
} 
public void addText(){ 
    String result = getArguments().getString(R.string.clicked_text_key); 
    txvResult.setText(result); 
} 

Voir: How to transfer some data to another Fragment?

+0

Merci, mais aussi ne fonctionne pas. Il apparaît référence null obect sur widget.TetView.setTex(). – JonD

+0

addText() doit être appelé après fragmentB.onCreateView(), ou éventuellement dedans (après avoir connecté txvResult) – Mars

+0

J'ai édité la réponse pour que vous puissiez voir l'utilisation - je devine que vous appeliez addText avant que la vue ait été gonflé, ce qui signifie que txvResult serait nul. – Mars

0

Vous pouvez essayer avec StickyEvent dans EventBus Sticky Event. Lorsque vous cliquez sur l'article, juste poster un événement collant comme

EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!")); 

Puis après avoir ajouté FragmentB, vous pouvez recevoir l'événement dans la méthode subscribe.