Cette question vise principalement à solliciter des opinions sur la meilleure façon de gérer mon application. J'ai trois fragments traités par une activité. Le fragment A a un élément cliquable sur la photo et le fragment B a 4 éléments cliquables les boutons. L'autre fragment affiche uniquement les détails lorsque l'utilisateur clique sur la photo. J'utilise ActionBarSherlock.
Les boutons avant et arrière doivent modifier la photo pour la pose suivante ou précédente, respectivement. Je pouvais conserver la photo et les boutons dans le même fragment, mais je voulais les garder séparés au cas où je voudrais les réorganiser dans une tablette.
J'ai besoin de conseils - devrais-je combiner les fragments A et B? Sinon, je devrai comprendre comment implémenter une interface pour 3 éléments cliquables.
J'ai envisagé d'utiliser Roboguice, mais je suis déjà en train d'utiliser SherlockFragmentActivity, c'est donc un non-droit. J'ai vu la mention d'Otto, mais je n'ai pas vu de bons tutoriels sur la façon d'inclure dans un projet. Selon vous, quelle devrait être la meilleure pratique de conception?
J'ai aussi besoin d'aide pour savoir comment communiquer entre un fragment et une activité. J'aimerais garder certaines données "globales" dans l'application, comme l'identifiant de pose. Existe-t-il un exemple de code que je peux voir en plus des informations de base du développeur Android? Ce n'est pas si utile.
BTW, je stocke déjà toutes les informations sur chaque pose dans une base de données SQLite. C'est la partie facile.
Le moyen le plus simple de communiquer entre votre activité et vos fragments consiste à utiliser des interfaces. L'idée est essentiellement de définir une interface à l'intérieur d'un fragment A donné et de laisser l'activité implémenter cette interface.
Une fois cette interface implémentée, vous pouvez faire ce que vous voulez dans la méthode qu’elle remplace.
L’autre partie importante de l’interface est que vous devez appeler la méthode abstraite à partir de votre fragment et vous rappeler de l’intégrer à votre activité. Il devrait attraper un ClassCastException s'il n'est pas fait correctement.
Il y a un bon tutoriel sur Simple Developer Blog sur comment faire exactement ce genre de chose.
J'espère que cela vous a été utile!
La méthode suggérée pour la communication entre fragments consiste à utiliser des callbacks\écouteurs gérés par votre activité principale.
Je pense que le code sur cette page est assez clair: http://developer.Android.com/training/basics/fragments/communicating.html
Vous pouvez également faire référence à l'application IO 2012 Schedule, conçue pour être une application de référence de facto. Vous pouvez le trouver ici: http://code.google.com/p/iosched/
En outre, voici une question SO avec une bonne information: Comment passer des données entre fragments
Il est implémenté par une interface de rappel: Tout d’abord, nous devons créer une interface:
public interface UpdateFrag {
public void updatefrag();
}
En activité faites le code suivant:
UpdateFrag updatfrag ;
public void updateApi(UpdateFrag listener) {
updatfrag = listener;
}
de l'événement à partir duquel le rappel doit être déclenché en activité:
updatfrag.updatefrag();
Dans Fragment, implémentez l'interface dans CreateView en utilisant le code suivant:
((Home)getActivity()).updateApi(new UpdateFrag() {
@Override
public void updatefrag() {
.....your stuff......
}
});
J'ai créé une bibliothèque d'annotations pouvant effectuer le casting à votre place. vérifier cela . https://github.com/zeroarst/callbackfragment/
@CallbackFragment
public class MyFragment extends Fragment {
@Callback
interface FragmentCallback {
void onClickButton(MyFragment fragment);
}
private FragmentCallback mCallback;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt1
mCallback.onClickButton(this);
break;
case R.id.bt2
// Because we give mandatory = false so this might be null if not implemented by the Host.
if (mCallbackNotForce != null)
mCallbackNotForce.onClickButton(this);
break;
}
}
}
Il génère ensuite une sous-classe de votre fragment. Et ajoutez-le simplement à FragmentManager.
public class MainActivity extends AppCompatActivity implements MyFragment.FragmentCallback {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction()
.add(R.id.lo_fragm_container, MyFragmentCallbackable.create(), "MY_FRAGM")
.commit();
}
Toast mToast;
@Override
public void onClickButton(MyFragment fragment) {
if (mToast != null)
mToast.cancel();
mToast = Toast.makeText(this, "Callback from " + fragment.getTag(), Toast.LENGTH_SHORT);
mToast.show();
}
}
Il existe plusieurs façons de communiquer entre activités, fragments, services, etc. L’essentiel est de communiquer en utilisant des interfaces. Cependant, ce n'est pas un moyen productif de communiquer. Vous devez implémenter les auditeurs, etc.
Ma suggestion est d'utiliser un bus d'événement. Le bus d'événements est une implémentation de modèle de publication/abonnement.
Vous pouvez vous abonner à des événements de votre activité, puis publier ces événements dans vos fragments, etc.
Ici sur mon article de blog vous pouvez trouver plus de détails sur ce modèle et aussi un exemple de projet pour montrer l'utilisation.
Je ne suis pas sûr d'avoir bien compris ce que vous voulez faire, mais la méthode suggérée pour communiquer entre fragments est d'utiliser des rappels avec l'activité, jamais directement entre fragments. Voir ici http://developer.Android.com/training/basics/fragments/communicating.html
Pour communiquer entre Activity
et Fragment
s, il existe plusieurs options, mais après de nombreuses lectures et de nombreuses expériences, j'ai découvert que cela pouvait être repris de la manière suivante:
Activity
veut communiquer avec l'enfant Fragment
=> Écrivez simplement des méthodes publiques dans votre classe Fragment
et laissez le Activity
les appelerFragment
veut communiquer avec le parent Activity
=> Cela nécessite un peu plus de travail, comme le lien officiel Android https://developer.Android.com/training/basics/fragments/communicating suggère, ce serait un excellente idée de définir une interface
qui sera implémentée par la Activity
et qui établira un contrat pour toute Activity
qui souhaite communiquer avec cette Fragment
. Par exemple, si vous avez FragmentA
, qui veut communiquer avec tout activity
qui l’inclut, définissez ensuite FragmentAInterface
qui définira la méthode que la FragmentA
peut appeler pour le activities
qui décide de l’utiliser.Fragment
veut communiquer avec une autre Fragment
=> C'est le cas où vous obtenez la situation la plus «compliquée». Puisque vous pourriez potentiellement avoir besoin de transmettre des données de FragmentA à FragmentB et vice versa, cela pourrait nous amener à définir 2 interfaces, FragmentAInterface
qui sera implémentée par FragmentB
et FragmentAInterface
qui sera implémentée par FragmentA
. Cela va commencer à rendre les choses en désordre. Et imaginez si vous avez un peu plus de Fragment
s sur place, et même le parent activity
souhaite communiquer avec eux. Eh bien, cette affaire est le moment idéal pour établir une ViewModel
partagée pour la activity
et c'est fragment
s. Plus d'infos ici https://developer.Android.com/topic/libraries/architecture/viewmodel . En gros, vous devez définir une classe SharedViewModel
, qui contient toutes les données que vous voulez partager entre activity
et fragments
et qui auront besoin de communiquer des données entre elles.Le cas ViewModel
rend les choses plus simples à la fin, car vous n'avez pas à ajouter de logique supplémentaire qui rend les choses sales dans le code et désordonnées. De plus, cela vous permettra de séparer la collecte (via des appels vers une base de données SQLite ou une API) des données de la variable Controller
(activities
et fragments
).
Vous pouvez créer déclarer une interface publique avec une déclaration de fonction dans le fragment et implémenter l'interface dans l'activité. Ensuite, vous pouvez appeler la fonction à partir du fragment.
J'utilise Intents pour communiquer des actions à l'activité principale. L’activité principale consiste à les écouter en remplaçant NewIntent (Intention Intention). L'activité principale traduit ces actions en fragments correspondants, par exemple.
Donc, vous pouvez faire quelque chose comme ça:
public class MainActivity extends Activity {
public static final String INTENT_ACTION_SHOW_FOO = "show_foo";
public static final String INTENT_ACTION_SHOW_BAR = "show_bar";
@Override
protected void onNewIntent(Intent intent) {
routeIntent(intent);
}
private void routeIntent(Intent intent) {
String action = intent.getAction();
if (action != null) {
switch (action) {
case INTENT_ACTION_SHOW_FOO:
// for example show the corresponding fragment
loadFragment(FooFragment);
break;
case INTENT_ACTION_SHOW_BAR:
loadFragment(BarFragment);
break;
}
}
}
Puis à l'intérieur de n'importe quel fragment pour montrer le fragment foo:
Intent intent = new Intent(context, MainActivity.class);
intent.setAction(INTENT_ACTION_SHOW_FOO);
// Prevent activity to be re-instantiated if it is already running.
// Instead, the onNewEvent() is triggered
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
getContext().startActivity(intent);