Comunicación entre un fragmento y una actividad-mejores prácticas
Esta pregunta es principalmente para solicitar opiniones sobre la mejor manera de manejar mi aplicación. Tengo tres fragmentos manejados por una actividad. El fragmento A tiene un elemento clickable la foto y el fragmento B tiene 4 elementos clickables los botones. El otro fragmento solo muestra detalles cuando se hace clic en la foto. Estoy usando ActionBarSherlock.
Los botones adelante y atrás deben cambiar la foto a las poses siguiente o anterior, respectivamente. Podría seguir con la foto y los botones en el mismo fragmento, pero quería mantenerlos separados en caso de que quisiera reorganizarlos en una tableta.
Necesito un consejo - ¿debo combinar Fragmentos A y B? Si no, tendré que averiguar cómo implementar una interfaz para 3 elementos seleccionables.
Consideré usar Roboguice, pero ya estoy extendiendo el uso de SherlockFragmentActivity por lo que es un no ir. Vi mención de Otto, pero no vi buenos tutoriales sobre cómo incluirlo en un proyecto. ¿Qué haces ¿crees que las mejores prácticas de diseño deberían serlo?
También necesito ayuda para averiguar cómo comunicarse entre un fragmento y una actividad. Me gustaría mantener algunos datos "globales" en la aplicación, como el pose id. ¿Hay algún código de ejemplo que pueda ver además de la información del desarrollador de Android? Eso no es tan útil.
Por cierto, ya estoy almacenando toda la información sobre cada pose en una base de datos SQLite. Esa es la parte fácil.
9 answers
La forma más fácil de comunicarse entre su actividad y los fragmentos es utilizando interfaces. La idea es básicamente definir una interfaz dentro de un fragmento A dado y dejar que la actividad implemente esa interfaz.
Una vez que haya implementado esa interfaz, puede hacer lo que quiera en el método que anula.
La otra parte importante de la interfaz es que tienes que llamar al método abstracto desde tu fragmento y recordar enviarlo a tu actividad. Debería coger una ClassCastException si no se hace correctamente.
Hay un buen tutorial en Simple Developer Blog sobre cómo hacer exactamente este tipo de cosas.
Espero que esto haya sido útil para usted!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-30 21:59:58
El método sugerido para la comunicación entre fragmentos es usar callbacks\listeners que son administrados por su actividad principal.
Creo que el código de esta página es bastante claro: http://developer.android.com/training/basics/fragments/communicating.html
También puede hacer referencia a la aplicación IO 2012 Schedule, que está diseñada para ser una aplicación de referencia de facto. Se puede encontrar aquí: http://code.google.com/p/iosched /
También, aquí hay una pregunta con buena info: Cómo pasar datos entre fragmentos
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:20
Se implementa mediante la interfaz de devolución de llamada: En primer lugar tenemos que hacer una interfaz:
public interface UpdateFrag {
public void updatefrag();
}
En la actividad haga el siguiente código:
UpdateFrag updatfrag ;
public void updateApi(UpdateFrag listener) {
updatfrag = listener;
}
Desde el evento desde donde la devolución de llamada tiene que disparar en la actividad:
updatfrag.updatefrag();
En Fragment implementar la interfaz en CreateView hacer el siguiente código:
((Home)getActivity()).updateApi(new UpdateFrag() {
@Override
public void updatefrag() {
.....your stuff......
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-03 17:48:14
Hice una biblioteca de anotaciones que puede hacer el reparto por ti. mira esto. 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;
}
}
}
Luego genera una subclase de tu fragmento. Y solo agrégalo a 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();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-22 08:14:13
Hay varias maneras de comunicarse entre actividades, fragmentos, servicios, etc. La obvia es comunicarse usando interfaces. Sin embargo, no es una forma productiva de comunicarse. Tienes que implementar los oyentes, etc.
Mi sugerencia es usar un bus de eventos. Event bus es una implementación de patrón de publicación / suscripción.
Puede suscribirse a eventos en su actividad y luego puede publicar esos eventos en sus fragmentos, etc.
Aquí en mi entrada de blog puede encontrar más detalles sobre este patrón y también un proyecto de ejemplo para mostrar el uso.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-08 13:45:57
No estoy seguro de entender realmente lo que quieres hacer, pero la forma sugerida de comunicarse entre fragmentos es usar callbacks con la Actividad, nunca directamente entre fragmentos. Ver aquí http://developer.android.com/training/basics/fragments/communicating.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-09 23:08:20
Para comunicarse entre un Activity
y Fragment
s, hay varias opciones, pero después de mucha lectura y muchas experiencias, descubrí que se podría resumir de esta manera:{[36]]}
-
Activity
quiere comunicarse con childFragment
= > Simplemente escriba métodos públicos en su claseFragment
, y deje queActivity
los llame -
Fragment
quiere comunicarse con el padreActivity
= > Esto requiere un poco más de trabajo, ya que el enlace oficial de Android https://developer.android.com/training/basics/fragments/communicating sugiere, sería una gran idea para definir uninterface
que será implementado por elActivity
, y que establecerá un contrato para cualquierActivity
que quiere comunicar con queFragment
. Por ejemplo, si tieneFragmentA
, que quiere comunicarse con cualquieractivity
que lo incluya, entonces defina elFragmentAInterface
que definirá qué método puede llamar elFragmentA
para elactivities
que decida usarlo. - A
Fragment
quiere para comunicarse con otrosFragment
= > Este es el caso donde se obtiene la situación más 'complicada'. Dado que potencialmente podría necesitar pasar datos de FragmentA a FragmentB y viceversa, eso podría llevarnos a definir 2 interfaces,FragmentAInterface
que serán implementadas porFragmentB
yFragmentAInterface
que serán implementadas porFragmentA
. Eso empezará a complicar las cosas. E imaginen si tienen unos cuantosFragment
más en el lugar, e incluso el padreactivity
quiere comunicarse con ellos. Bueno, este caso es un momento perfecto para establecer unViewModel
compartido para elactivity
y esfragment
s. Más información aquí https://developer.android.com/topic/libraries/architecture/viewmodel . Básicamente, necesita definir una claseSharedViewModel
, que tenga todos los datos que desea compartir entreactivity
yfragments
que necesitarán comunicar datos entre ellos.
El caso ViewModel
, hace las cosas bastante más simples al final, ya que no tiene que agregar lógica adicional que ensucie las cosas en el código y desordenado. Además, le permitirá separar la recopilación (a través de llamadas a una base de datos SQLite o una API) de los datos Controller
(activities
y fragments
).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-10 15:33:29
Puede crear declarar una interfaz pública con una declaración de función en el fragmento e implementar la interfaz en la actividad. Luego puede llamar a la función desde el fragmento.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-31 12:06:22
Estoy usando Intents para comunicar acciones a la actividad principal. La actividad principal es escucharlos anulando onNewIntent (Intent intent). La actividad principal traduce estas acciones a los fragmentos correspondientes, por ejemplo.
Así que puedes hacer algo como esto:
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;
}
}
}
Luego dentro de cualquier fragmento para mostrar el fragmento 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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-16 11:17:58