Intereting Posts
Консоль Eclipse показывает: «Не удалось нажать выделение: файловая система только для чтения», когда я пытаюсь нажать файл Можете ли вы объяснить (математический расчет) пример жестов (Левенштейн)? Проблема ориентации изображения на Android с пользовательской активностью камеры Разрешения INTERNET в Android M Что делает FrameLayout? Начать работу с Button Android Как использовать инструменты: overrideLibrary в файле build.gradle? Поиск в XML-файле с помощью XPath в Android Некоторые андроиды, загружающие скремблированные изображения Могу ли я каким-либо образом включить и использовать несколько версий данной библиотеки .jar? Повторение уведомлений на Android 4 Стиль TabLayout не может решить @ dimen / tab_max_width после перехода на Android Design Support v23 Android. Отладка на реальном устройстве (Nexus 7) Есть ли способ сделать столбцы таблицы равными доле общей ширины? Пользовательский вид Android должен расширять AppCompatTextView

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

Я пытаюсь передать данные между двумя 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/