Intereting Posts
Android: с помощью registerContentObserver (), чтобы быть уведомленным по мере изменения контактов Правильный способ обработки навигации «Вверх» в соответствии с рекомендациями Добавить булавки в Google Map в TWebBrowser и обрабатывать клики Поддерживает ли Android поддержку структуры MVC (Model View Controller)? Значение сообщений хореографа в Logcat Установка высоты элемента ListView Как преобразовать double в 2 числа после точки? ActivityLifecycleCallbacks не запускаются, когда активность убивается с помощью «Не продолжать действия», Как предоставить свой собственный LocationProvider на Android? Перенос изображения через Bluetooth в Android URLConnection.getContentLength () возвращает -1 Устройства Gingerbread, не использующие стиль Holo от Theme.AppCompat (библиотека поддержки) Android jack toolchain не распознает java.util.function.Predicate in stream Разница между воссозданием Activity с методом recreate () и startActivity (getIntent ()) Улучшение гладкости прокрутки в Android ListView

Как передавать данные между фрагментами

Я пытаюсь передать данные между двумя fragmens в моей программе. Его простая строка, которая хранится в списке. Список публикуется в фрагментах A, и когда пользователь нажимает на элемент списка, мне нужно, чтобы он отображался в фрагменте B. Поставщик содержимого, похоже, поддерживает идентификаторы, поэтому это не сработает. Какие-либо предложения?

Solutions Collecting From Web of "Как передавать данные между фрагментами"

Я думаю, что связь между фрагментами должна осуществляться через активность. И связь между фрагментом и активностью может быть выполнена следующим образом: https://developer.android.com/training/basics/fragments/communicating.html https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity

Если вы используете Roboguice, вы можете использовать EventManager в Roboguice для передачи данных без использования Activity в качестве интерфейса. Это довольно чистая ИМО.

Если вы не используете Roboguice, вы можете использовать Otto также как автобус событий: http://square.github.com/otto/

Обновление 20150909: вы также можете использовать Green Bus Robot Event Bus или даже RxJava. Зависит от вашего прецедента.

Из документации Fragment :

Часто вы хотите, чтобы один фрагмент связывался с другим, например, чтобы изменить контент на основе пользовательского события. Связь между фрагментами и фрагментами осуществляется через связанную с ней активность. Два фрагмента никогда не должны связываться напрямую.

Поэтому я предлагаю вам ознакомиться с базовыми документами по обработке фрагментов в документации. Они довольно обширны с примером и прогулочным руководством.

Почему бы вам не использовать Bundle. Из вашего первого фрагмента, вот как его настроить:

 Fragment fragment = new Fragment(); Bundle bundle = new Bundle(); bundle.putInt(key, value); fragment.setArguments(bundle); 

Затем во втором фрагменте извлеките данные, используя:

 Bundle bundle = this.getArguments(); int myInt = bundle.getInt(key, defaultValue); 

Bundle использует методы для множества типов данных. См. http://developer.android.com/reference/android/os/Bundle.html.

Итак, скажем, у вас есть Activity AB, который контролирует Frag A и Fragment B. Внутри фрагмента A вам нужен интерфейс, который может реализовать Activity AB. В образце кода Android они:

private Callbacks mCallbacks = sDummyCallbacks;

/ * Интерфейс обратного вызова, который должен реализовывать все действия, содержащие этот фрагмент. Этот механизм позволяет уведомлять действия о выборе элементов. * /

 public interface Callbacks { /*Callback for when an item has been selected. */ public void onItemSelected(String id); } /*A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity. */ private static Callbacks sDummyCallbacks = new Callbacks() { @Override public void onItemSelected(String id) { } }; 

Интерфейс обратного вызова помещается в один из ваших фрагментов (скажем, фрагмент A). Я думаю, что цель этого интерфейса Callbacks – как вложенный класс внутри Frag A, который может реализовать любое действие. Так, если Fragment A был телевизором, CallBacks – это ТВ-пульт (интерфейс), который позволяет Fragment A использоваться Activity AB. Возможно, я ошибаюсь в деталях, потому что я нооб, но я действительно добился, чтобы моя программа отлично работала на всех размерах экрана, и это то, что я использовал.

Итак, внутри Fragment A у нас есть: (я взял это из пробных программ Android)

 @Override public void onListItemClick(ListView listView, View view, int position, long id) { super.onListItemClick(listView, view, position, id); // Notify the active callbacks interface (the activity, if the // fragment is attached to one) that an item has been selected. mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id); //mCallbacks.onItemSelected( PUT YOUR SHIT HERE. int, String, etc.); //mCallbacks.onItemSelected (Object); } 

И внутри Activity AB мы переопределяем метод onItemSelected:

 public class AB extends FragmentActivity implements ItemListFragment.Callbacks { //... @Override //public void onItemSelected (CATCH YOUR SHIT HERE) { //public void onItemSelected (Object obj) { public void onItemSelected(String id) { //Pass Data to Fragment B. For example: Bundle arguments = new Bundle(); arguments.putString(“FragmentB_package”, id); FragmentB fragment = new FragmentB(); fragment.setArguments(arguments); getSupportFragmentManager().beginTransaction().replace(R.id.item_detail_container, fragment).commit(); } 

Поэтому внутри Activity AB вы в основном бросаете все в Bundle и передаете его B. Если u не уверены, как использовать Bundle, посмотрите класс вверх.

Я в основном придерживаюсь образца кода, который предоставил Android. Тот, у кого есть материал DummyContent. Когда вы создаете новый пакет приложений для Android, он называется MasterDetailFlow.

1- Первый способ – определить интерфейс

 public interface OnMessage{ void sendMessage(int fragmentId, String message); } public interface OnReceive{ void onReceive(String message); } 

2- В вашей деятельности реализован интерфейс OnMessage

 public class MyActivity implements OnMessage { ... @Override public void sendMessage(int fragmentId, String message){ Fragment fragment = getSupportFragmentManager().findFragmentById(fragmentId); ((OnReceive) fragment).sendMessage(); } } 

3- В вашем фрагменте реализован интерфейс OnReceive

 public class MyFragment implements OnReceive{ ... @Override public void onReceive(String message){ myTextView.setText("Received message:" + message); } } 

Это стандартная версия обработки сообщения, проходящего между фрагментами.

Другим способом передачи данных между фрагментами является использование шины событий.

1- Регистрация / отмена регистрации на автобусе событий

 @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } 

2- Определить класс события

 public class Message{ public final String message; public Message(String message){ this.message = message; } } 

3- Опубликовать это событие в любом месте приложения

 EventBus.getDefault().post(new Message("hello world")); 

4- Подпишитесь на это событие, чтобы получить его в своем фрагменте

 @Subscribe(threadMode = ThreadMode.MAIN) public void onMessage(Message event){ mytextview.setText(event.message); } 

Для получения дополнительной информации используйте примеры использования и пример проекта о шаблоне шины событий.

Это зависит от того, как структурирован фрагмент. Если вы можете использовать некоторые методы в статике класса B фрагмента, а также целевой объект TextView static, вы можете вызвать метод непосредственно в классе фрагментов A. Это лучше, чем слушатель, когда метод выполняется мгновенно, Необходимо иметь дополнительную задачу, которая выполняет прослушивание во время всего действия. См. Пример ниже:

 Fragment_class_B.setmyText(String yourstring); 

На фрагменте B вы можете иметь метод, определенный как:

 public static void setmyText(final String string) { myTextView.setText(string); } 

Просто не забудьте указать myTextView как статический на фрагменте B и правильно импортировать класс Fragment B на фрагмент A.

Просто недавно была выполнена процедура моего проекта, и это сработало. Надеюсь, что это помогло.

Вы можете прочитать этот документ. Эта концепция хорошо объясняется здесь. http://developer.android.com/training/basics/fragments/communicating.html

Я работаю над подобным проектом, и я думаю, мой код может помочь в вышеуказанной ситуации

Вот обзор того, что я делаю

Мой проект имеет два фрагмента, названных « FragmentA » и «FragmentB »

FragmentA Содержит один список Просмотр, когда вы нажимаете элемент в FragmentA . INDEX передается в FragmentB с использованием интерфейса Communicator

  • Шаблон проектирования полностью основан на концепции интерфейсов Java, в которой говорится, что « ссылочные переменные интерфейса могут ссылаться на объект подкласса»,
  • Пусть MainActivity реализует интерфейс, предоставляемый фрагментом (в противном случае мы не можем заставить ссылочную переменную интерфейса указывать на MainActivity)
  • В приведенном ниже коде сообщается, что объект коммуникатора ссылается на объект MainActivity, используя метод setCommunicator (Communicatot c), присутствующий в фрагменте A.
  • Я запускаю метод ответа () интерфейса от FrgamentA, используя ссылку MainActivity.

    Интерфейс Communcator определяется внутри фрагмента A, это обеспечивает наименьшее превалирование доступа к интерфейсу коммуникатора .

Ниже мой полный рабочий код

FragmentA.java

 public class FragmentA extends Fragment implements OnItemClickListener { ListView list; Communicator communicater; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.fragmenta, container,false); } public void setCommunicator(Communicator c){ communicater=c; } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); communicater=(Communicator) getActivity(); list = (ListView) getActivity().findViewById(R.id.lvModularListView); ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(getActivity(), R.array.items, android.R.layout.simple_list_item_1); list.setAdapter(adapter); list.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) { communicater.respond(index); } public interface Communicator{ public void respond(int index); } 

}

fragmentB.java

 public class FragmentA extends Fragment implements OnItemClickListener { ListView list; Communicator communicater; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.fragmenta, container,false); } public void setCommunicator(Communicator c){ communicater=c; } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); communicater=(Communicator) getActivity(); list = (ListView) getActivity().findViewById(R.id.lvModularListView); ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(getActivity(), R.array.items, android.R.layout.simple_list_item_1); list.setAdapter(adapter); list.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> arg0, View arg1, int index, long arg3) { communicater.respond(index); } public interface Communicator{ public void respond(int index); } } 

MainActivity.java

 public class MainActivity extends Activity implements FragmentA.Communicator { FragmentManager manager=getFragmentManager(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentA fragA=(FragmentA) manager.findFragmentById(R.id.fragmenta); fragA.setCommunicator(this); } @Override public void respond(int i) { // TODO Auto-generated method stub FragmentB FragB=(FragmentB) manager.findFragmentById(R.id.fragmentb); FragB.changetext(i); } } 

В моем случае я должен был отправить данные назад из FragmentB-> FragmentA, поэтому Intents не был вариантом, поскольку фрагмент уже был инициализирован. Все, если все вышеприведенные ответы звучат хорошо, для реализации требуется много кода котельной плиты , поэтому i Пошел с гораздо более простым подходом к использованию LocalBroadcastManager , он точно делает это, но без allly неприятный шаблонный код. Ниже приведен пример.

В Отправляющем фрагменте (фрагмент B)

 public class FragmentB { private void sendMessage() { Intent intent = new Intent("custom-event-name"); intent.putExtra("message", "your message"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); } } 

И в сообщении, которое будет получен фрагмент (Фрагмент A)

  public class FragmentA { @Override public void onCreate(Bundle savedInstanceState) { ... // Register receiver LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter("custom-event-name")); } // This will be called whenever an Intent with an action named "custom-event-name" is broadcasted. private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String message = intent.getStringExtra("message"); } }; } 

Надеюсь, это поможет кому-то

Класс фрагмента A

 public class CountryListFragment extends ListFragment{ /** List of countries to be displayed in the ListFragment */ ListFragmentItemClickListener ifaceItemClickListener; /** An interface for defining the callback method */ public interface ListFragmentItemClickListener { /** This method will be invoked when an item in the ListFragment is clicked */ void onListFragmentItemClick(int position); } /** A callback function, executed when this fragment is attached to an activity */ @Override public void onAttach(Activity activity) { super.onAttach(activity); try{ /** This statement ensures that the hosting activity implements ListFragmentItemClickListener */ ifaceItemClickListener = (ListFragmentItemClickListener) activity; }catch(Exception e){ Toast.makeText(activity.getBaseContext(), "Exception",Toast.LENGTH_SHORT).show(); } } 

Фрагмент класса B

 public class CountryDetailsFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { /** Inflating the layout country_details_fragment_layout to the view object v */ View v = inflater.inflate(R.layout.country_details_fragment_layout, null); /** Getting the textview object of the layout to set the details */ TextView tv = (TextView) v.findViewById(R.id.country_details); /** Getting the bundle object passed from MainActivity ( in Landscape mode ) or from * CountryDetailsActivity ( in Portrait Mode ) * */ Bundle b = getArguments(); /** Getting the clicked item's position and setting corresponding details in the textview of the detailed fragment */ tv.setText("Details of " + Country.name[b.getInt("position")]); return v; } } 

Основной класс активности для передачи данных между фрагментами

 public class MainActivity extends Activity implements ListFragmentItemClickListener { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } /** This method will be executed when the user clicks on an item in the listview */ @Override public void onListFragmentItemClick(int position) { /** Getting the orientation ( Landscape or Portrait ) of the screen */ int orientation = getResources().getConfiguration().orientation; /** Landscape Mode */ if(orientation == Configuration.ORIENTATION_LANDSCAPE ){ /** Getting the fragment manager for fragment related operations */ FragmentManager fragmentManager = getFragmentManager(); /** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); /** Getting the existing detailed fragment object, if it already exists. * The fragment object is retrieved by its tag name * */ Fragment prevFrag = fragmentManager.findFragmentByTag("in.wptrafficanalyzer.country.details"); /** Remove the existing detailed fragment object if it exists */ if(prevFrag!=null) fragmentTransaction.remove(prevFrag); /** Instantiating the fragment CountryDetailsFragment */ CountryDetailsFragment fragment = new CountryDetailsFragment(); /** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */ Bundle b = new Bundle(); /** Setting the data to the bundle object */ b.putInt("position", position); /** Setting the bundle object to the fragment */ fragment.setArguments(b); /** Adding the fragment to the fragment transaction */ fragmentTransaction.add(R.id.detail_fragment_container, fragment,"in.wptrafficanalyzer.country.details"); /** Adding this transaction to backstack */ fragmentTransaction.addToBackStack(null); /** Making this transaction in effect */ fragmentTransaction.commit(); }else{ /** Portrait Mode or Square mode */ /** Creating an intent object to start the CountryDetailsActivity */ Intent intent = new Intent("in.wptrafficanalyzer.CountryDetailsActivity"); /** Setting data ( the clicked item's position ) to this intent */ intent.putExtra("position", position); /** Starting the activity by passing the implicit intent */ startActivity(intent); } } } 

Класс чувствительности Detailde

 public class CountryDetailsActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** Setting the layout for this activity */ setContentView(R.layout.country_details_activity_layout); /** Getting the fragment manager for fragment related operations */ FragmentManager fragmentManager = getFragmentManager(); /** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */ FragmentTransaction fragmentTransacton = fragmentManager.beginTransaction(); /** Instantiating the fragment CountryDetailsFragment */ CountryDetailsFragment detailsFragment = new CountryDetailsFragment(); /** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */ Bundle b = new Bundle(); /** Setting the data to the bundle object from the Intent*/ b.putInt("position", getIntent().getIntExtra("position", 0)); /** Setting the bundle object to the fragment */ detailsFragment.setArguments(b); /** Adding the fragment to the fragment transaction */ fragmentTransacton.add(R.id.country_details_fragment_container, detailsFragment); /** Making this transaction in effect */ fragmentTransacton.commit(); } } 

Array Of Contries

 public class Country { /** Array of countries used to display in CountryListFragment */ static String name[] = new String[] { "India", "Pakistan", "Sri Lanka", "China", "Bangladesh", "Nepal", "Afghanistan", "North Korea", "South Korea", "Japan", "Bhutan" }; } 

Для получения дополнительной информации посетите эту ссылку [ http://wptrafficanalyzer.in/blog/itemclick-handler-for-listfragment-in-android/%5D . Есть полный пример.

В основном здесь мы имеем дело с сообщением между Фрагментами. Связь между фрагментами никогда не может быть напрямую возможной. Он включает в себя деятельность, в контексте которой создаются оба фрагмента.

Вам необходимо создать интерфейс в отправляющем фрагменте и реализовать интерфейс в активности, который отсрочит сообщение и передаст его получающему фрагменту.

В основном выполните интерфейс для взаимодействия между Activity и фрагментом.

1) Основная деятельность

 public class MainActivity extends Activity implements SendFragment.StartCommunication { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void setComm(String msg) { // TODO Auto-generated method stub DisplayFragment mDisplayFragment = (DisplayFragment)getFragmentManager().findFragmentById(R.id.fragment2); if(mDisplayFragment != null && mDisplayFragment.isInLayout()) { mDisplayFragment.setText(msg); } else { Toast.makeText(this, "Error Sending Message", Toast.LENGTH_SHORT).show(); } } } 

2) фрагмент отправителя (фрагмент к активности)

 public class SendFragment extends Fragment { StartCommunication mStartCommunicationListner; String msg = "hi"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View mView = (View) inflater.inflate(R.layout.send_fragment, container); final EditText mEditText = (EditText)mView.findViewById(R.id.editText1); Button mButton = (Button) mView.findViewById(R.id.button1); mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub msg = mEditText.getText().toString(); sendMessage(); } }); return mView; } interface StartCommunication { public void setComm(String msg); } @Override public void onAttach(Activity activity) { // TODO Auto-generated method stub super.onAttach(activity); if(activity instanceof StartCommunication) { mStartCommunicationListner = (StartCommunication)activity; } else throw new ClassCastException(); } public void sendMessage() { mStartCommunicationListner.setComm(msg); } } 

3) фрагмент приемника (операция-фрагмент)

  public class DisplayFragment extends Fragment { View mView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub mView = (View) inflater.inflate(R.layout.display_frgmt_layout, container); return mView; } void setText(String msg) { TextView mTextView = (TextView) mView.findViewById(R.id.textView1); mTextView.setText(msg); } } 

Я использовал эту ссылку для того же решения, надеюсь, кто-то найдет ее полезной. Очень простой и простой пример.

http://infobloggall.com/2014/06/22/communication-between-activity-and-fragments/