studio pasar otro navegar llamar fragments fragmento entre dinamicos desde cambiar abrir android android-activity fragment onkeydown

pasar - navegar entre fragments android studio



La actividad de fragmentos captura onKeyDown y se utiliza en fragmentos (4)

Tengo actividad Fragmento con buscapersonas:

List<Fragment> fragments = new Vector<Fragment>(); fragments.add(Fragment.instantiate(this, PastEventListFragment.class.getName(),bundle)); fragments.add(Fragment.instantiate(this, EventListFragment.class.getName(),bundle)); this.mPagerAdapter = new EventPagerAdapter(super.getSupportFragmentManager(), fragments); // ViewPager pager = (ViewPager)super.findViewById(R.id.viewpager1); pager.setAdapter(this.mPagerAdapter); pager.setCurrentItem(1);

Capto el evento onDownDown:

@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU) { } return super.onKeyDown(keyCode, event); }

La pregunta es: cómo usar el evento en todos los fragmentos que he creado en esta actividad. Gracias


Como lo mencionaron otros, la respuesta aceptada resulta en un estrecho acoplamiento entre la actividad y sus fragmentos.

Yo sugeriría usar algún tipo de implementación basada en eventos en su lugar. Esto es mucho más reutilizable y da como resultado una mejor arquitectura de software. En proyectos anteriores he usado una de las siguientes soluciones (Kotlin):

Transmisiones

Usando LocalBroadcastManager de Android: Documentation

Crear un BroadcastReceiver:

class SomeBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val keyCode = intent?.getIntExtra("KEY_CODE", 0) // Do something with the event }

}

En tu actividad:

class SomeActivity : AppCompatActivity() { override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { val intent = Intent("SOME_TAG").apply { putExtra("KEY_CODE", keyCode) } LocalBroadcastManager.getInstance(this).sendBroadcast(intent) return super.onKeyDown(keyCode, event) } }

Luego, en cualquiera de los fragmentos (o servicios, etc.):

class SomeFragment : Fragment() { val receiver = SomeBroadcastReceiver() override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val filter = IntentFilter().apply { addAction("SOME_TAG") } LocalBroadcastManager.getInstance(context!!).registerReceiver(receiver, filter) return super.onCreateView(inflater, container, savedInstanceState) } }

EventBus

Utilizando EventBus

Crear una clase de evento:

data class Event(val keyCode: Int)

En tu actividad:

class SomeActivity : AppCompatActivity() { override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { EventBus.getDefault().post(Event(keyCode)) return super.onKeyDown(keyCode, event) } }

Luego, en tu fragmento:

class SomeFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { // Register for events EventBus.getDefault().register(this) return super.onCreateView(inflater, container, savedInstanceState) } @Subscribe public fun onKeyEvent(event : Event) { // Called by eventBus when an event occurs } override fun onDestroyView() { super.onDestroyView() EventBus.getDefault().unregister(this) } }


He subclasificado las clases de Actividad y Fragmento para realizar el paso de KeyEvents. Para mí, parece más claro que enviar transmisiones locales. Pero esta solución puede no ser tan flexible. Elige la forma preferida por ti mismo.

Aquí está la actividad:

public abstract class KeyEventPassingActivity extends Activity { public interface KeyEventListener extends View.OnKeyListener { boolean isVisible(); View getView(); } private final List<KeyEventListener> keyEventHandlerList = new ArrayList<>(); @Override public boolean dispatchKeyEvent(KeyEvent event) { for (KeyEventListener handler : keyEventHandlerList) { if (handleKeyEvent(handler, event)) { return true; } } return super.dispatchKeyEvent(event); } void addKeyEventHandler(@NonNull KeyEventListener handler) { keyEventHandlerList.add(handler); } void removeKeyEventHandler(@NonNull KeyEventListener handler) { keyEventHandlerList.remove(handler); } /** * @return <tt>true</tt> if the event was handled, <tt>false</tt> otherwise */ private boolean handleKeyEvent(@Nullable KeyEventListener listener, KeyEvent event) { return listener != null && listener.isVisible() && listener.onKey(listener.getView(), event.getKeyCode(), event); } }

Y el fragmento:

public abstract class KeyEventHandlingFragment extends Fragment implements KeyEventPassingActivity.KeyEventListener { @SuppressWarnings("deprecation") @Override public void onAttach(Activity activity) { super.onAttach(activity); if (activity instanceof KeyEventPassingActivity) { ((KeyEventPassingActivity) activity).addKeyEventHandler(this); } } @Override public void onDetach() { Activity activity = getActivity(); if (activity instanceof KeyEventPassingActivity) { ((KeyEventPassingActivity) activity).removeKeyEventHandler(this); } super.onDetach(); } }

Gist: https://gist.github.com/0neel/7d1ed5d26f2148b4168b6616337159ed


Lo que puede hacer es definir un método personalizado en su (s) clase (s) de fragmentos. Por ejemplo:

public void myOnKeyDown(int key_code){ //do whatever you want here }

y llame a este método siempre que se genere un evento de reducción de teclas en su clase de actividad. Por ejemplo:

@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU) { ((PastEventListFragment)fragments.get(0)).myOnKeyDown(keyCode); ((EventListFragment)fragments.get(1)).myOnKeyDown(keyCode); //and so on... } return super.onKeyDown(keyCode, event); }


Si a alguien le intereso cómo hacerlo con Boradcast:

En tu fragmento en onViewCreated

@Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // Register to receive messages. // We are registering an observer (mMessageReceiver) to receive Intents // with actions named "custom-event-name". LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("activity-says-hi")); ...} // Our handler for received Intents. This will be called whenever an Intent // with an action named "custom-event-name" is broadcasted. private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Get extra data included in the Intent doSomethingCauseVolumeKeyPressed(); } };

su evento clave - código para poner en actividad

@Override public boolean dispatchKeyEvent(KeyEvent event) { int action = event.getAction(); int keyCode = event.getKeyCode(); switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: if (action == KeyEvent.ACTION_DOWN) { sendBroadcast(); } return true; case KeyEvent.KEYCODE_VOLUME_DOWN: if (action == KeyEvent.ACTION_DOWN) { sendBroadcast(); } return true; default: return super.dispatchKeyEvent(event); } }

su transmisor de transmisión:

private void sendVolumeBroadcast(){ Intent intent = new Intent("activity-says-hi"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); }