Я пытаюсь передать данные между двумя фрагментами в моей программе. Его простая строка, которая хранится в списке. Список публикуется в фрагментах A, и когда пользователь нажимает на элемент списка, мне нужно, чтобы он отображался в фрагменте B. Поставщик содержимого, похоже, поддерживает идентификаторы, так что это не сработает. Любые предложения?
Как передавать данные между фрагментами
Ответ 1
Я думаю, что связь между фрагментами должна осуществляться через активность. И связь между фрагментом и деятельностью может быть выполнена следующим образом: https://developer.android.com/training/basics/fragments/communicating.html https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
Ответ 2
Если вы используете Roboguice, вы можете использовать EventManager в Roboguice для передачи данных без использования Activity в качестве интерфейса. Это довольно чистый ИМО.
Если вы не используете Roboguice, вы можете использовать Otto также как шину событий: http://square.github.com/otto/
Обновление 20150909: Вы также можете использовать Green Bus Robot Event Bus или даже RxJava. Зависит от вашего варианта использования.
Ответ 3
Из Fragment документации:
Часто вам нужно, чтобы один фрагмент связывался с другим, например, чтобы изменить контент на основе пользовательского события. Вся связь между фрагментами и фрагментами осуществляется через связанную с ней активность. Два фрагмента никогда не должны связываться напрямую.
Поэтому я предлагаю вам ознакомиться с документами по документированию основных фрагментов в документации. Они довольно полны с примером и прохождением руководства.
Ответ 4
Почему бы вам не использовать 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
Ответ 5
Итак, скажем, у вас есть 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 - это ТВ-пульт (интерфейс), который позволяет Фрагменту A использовать Activity AB. Возможно, я ошибаюсь в деталях, потому что я нооб, но я действительно добился, чтобы моя программа отлично работала на всех размерах экрана, и это то, что я использовал.
Итак, внутри фрагмента A мы имеем: (Я взял это из андроидских примеров программ)
@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.
Ответ 6
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);
}
Подробнее о о деталях, примерах использования и примере проекта о шаблоне шины событий.
Ответ 7
Это зависит от того, как структурирован фрагмент. Если вы можете использовать некоторые из методов статического элемента класса 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.
Недавно я сделал процедуру в своем проекте, и это сработало. Надеюсь, что это помогло.
Ответ 8
вы можете прочитать этот документ. Эта концепция хорошо объясняется здесь http://developer.android.com/training/basics/fragments/communicating.html
Ответ 9
Я работаю над подобным проектом, и я думаю, мой код может помочь в вышеуказанной ситуации
Вот обзор того, что я делаю
Мой проект Имеет два фрагмента, названных " FragmentA" и "FragmentB"
- FragmentA Содержит один список Просмотр, когда вы нажимаете элемент в FragmentA. УКАЗАТЕЛЬ передается FragmentB с помощью интерфейса Communicator
- Шаблон проектирования полностью основан на концепции интерфейсов Java, которая гласит: " ссылочные переменные интерфейса могут ссылаться на объект подкласса
- Пусть MainActivity реализует интерфейс, предоставляемый fragmentA (в противном случае мы не можем сделать ссылку ссылочной переменной для указания на MainActivity)
- В приведенном ниже коде коммуникационный объект создан для ссылки на объект MainActivity с помощью метода setCommunicator (Communicatot c) ", присутствующего в фрагменте.
-  Я запускаю метод reply() интерфейса от 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);
}
}
Ответ 10
В основном реализовать интерфейс для взаимодействия между 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/
Ответ 11
В моем случае я должен был отправить данные назад из FragmentB- > FragmentA, следовательно, Intents не был вариантом, поскольку фрагмент уже был инициализирован. Все, если все выше ответы звучит хорошо, требуется много кодовой таблички кодов для реализации, поэтому я пошел с более простым использованием 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);
    }
 }
И в сообщении, которое будет получен фрагмент (FRAGMENT 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");
      }
    };
}
Надеюсь, что это поможет кому-то
Ответ 12
Класс фрагмента 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 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   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 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 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/]. Есть полный пример.
Ответ 13
В основном здесь мы имеем дело с сообщением между Фрагментами. Связь между фрагментами никогда не может быть напрямую возможной. Он включает в себя активность, в контексте которой создаются оба фрагмента.
Вам нужно создать интерфейс в отправляющем фрагменте и реализовать интерфейс в активности, который отсрочит сообщение и передаст его получающему фрагменту.
