Передача данных между фрагментом и его контейнерной активностью
Как передать данные между фрагментом и его активностью в контейнере? Есть ли что-то похожее на передачу данных между действиями через намерения?
Я читал это, но это не помогло:
http://developer.android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity
Ответы
Ответ 1
В фрагменте вы можете вызвать getActivity()
.
Это даст вам доступ к активности, создавшей фрагмент. Оттуда вы, очевидно, можете вызвать любые методы доступа, которые находятся в действии.
например. для метода, называемого getResult()
в вашей деятельности:
((MyActivity) getActivity()).getResult();
Ответ 2
Попробуйте использовать интерфейсы.
Любой фрагмент, который должен передать данные обратно в его содержащую активность, должен объявить интерфейс для обработки и передачи данных. Затем убедитесь, что ваша содержащая активность реализует эти интерфейсы. Например:
В вашем фрагменте объявите интерфейс...
public interface OnDataPass {
public void onDataPass(String data);
}
Затем подключите реализацию класса класса к фрагменту в методе onAttach, например:
OnDataPass dataPasser;
@Override
public void onAttach(Context context) {
super.onAttach(context);
dataPasser = (OnDataPass) context;
}
Внутри вашего фрагмента, когда вам нужно обрабатывать передачу данных, просто вызовите его в объекте dataPasser:
public void passData(String data) {
dataPasser.onDataPass(data);
}
Наконец, в вашей содержательной активности , которая реализует OnDataPass
...
@Override
public void onDataPass(String data) {
Log.d("LOG","hello " + data);
}
Ответ 3
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle b = getActivity().getIntent().getExtras();
wid = b.getString("wid");
rid = b.getString("rid");
View view = inflater.inflate(R.layout.categoryfragment, container, false);
return view;
}
Ответ 4
Самый простой подход, но не рекомендуется
Вы можете получить доступ к данным активности из фрагмента:
Активность:
public class MyActivity extends Activity {
private String myString = "hello";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
...
}
public String getMyData() {
return myString;
}
}
Фрагмент:
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MyActivity activity = (MyActivity) getActivity();
String myDataFromActivity = activity.getMyData();
return view;
}
}
Ответ 5
Передача данных между фрагментом и его активностью в контейнере
Активность:
Bundle bundle = new Bundle();
bundle.putString("message", "Alo Elena!");
FragmentClass fragInfo = new FragmentClass();
fragInfo.setArguments(bundle);
transaction.replace(R.id.fragment_single, fragInfo);
transaction.commit();
Фрагмент:
Чтение значения в фрагменте
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String myValue = this.getArguments().getString("message");
...
...
...
}
Ответ 6
Я не знаю, является ли это лучшим способом или нет
Я искал в google довольно долгое время, узнав, как я могу передать Bundle из фрагмента в его контейнерную активность, но все, что я нашел, это отсылать данные от активности к фрагменту (что было немного запутанным для меня, поскольку я новичок).
позже я попробовал что-то свое собственное, которое точно сработало для меня так, как я хотел. поэтому я отправлю его здесь, если кто-то вроде меня ищет то же самое.
//Передача данных из фрагмента.
Bundle gameData = new Bundle();
gameData.putStringArrayList(Constant.KEY_PLAYERS_ARR,players);
gameData.putString(Constant.KEY_TEAM_NAME,custom_team_name);
gameData.putInt(Constant.KEY_REQUESTED_OVER,requestedOver);
Intent intent = getActivity().getIntent();
intent.putExtras(gameData);
//Получение данных из пакета из его активности контейнера.
Bundle gameData = getIntent().getExtras();
if (gameData != null)
{
int over = gameData.getInt(Constant.KEY_REQUESTED_OVER);
ArrayList<String> players = gameData.getStringArrayList(Constant.KEY_PLAYERS_ARR);
String team = gameData.getString(Constant.KEY_TEAM_NAME);
}
else if (gameData == null)
{
Toast.makeText(this, "Bundle is null", Toast.LENGTH_SHORT).show();
}
Ответ 7
Интерфейс - одно из лучших решений:
Интерфейс клея:
public interface DataProviderFromActivity {
public String getName();
public String getId);
}
MyActivity:
public class MyActivity implements DataProviderFromActivity{
String name = "Makarov";
String id = "sys533";
... ... ... ... ... .... ....
... ... ... ... ... .... ....
public String getName(){
return name;
};
public String getId(){
return id;
};
}
MyFragment:
public class MyFragment extends Fragment{
String fragName = "";
String fragId = "";
... ... ... ... ... .... ....
... ... ... ... ... .... ....
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
DataProviderFromActivity myActivity= (DataProviderFromActivity) getActivity();
fragName = myActivity.getName();
fragId = myActivity.getId();
... ... ... ... ... .... ....
... ... ... ... ... .... ....
updateFragmentView();
}
}
Ответ 8
Я использовал AppCompatActivity, который реализует Listen Listers. Фрагменты возникли как необходимость, так как мне нужно было закодировать селектор диапазона дат. И мне также понадобился контейнер для получения выбранных дат, чтобы вернуть их родительской активности.
Для активности контейнера это объявление класса:
public class AppCompatDateRange extends AppCompatActivity implements
DateIniRangeFragment.OnDateIniSelectedListener, DateFimRangeFragment.OnDateFimSelectedListener
И интерфейсы для обратных вызовов:
@Override
public void onDateIniSelected(String dataIni) {
Log.i("data inicial:", dataIni);
}
@Override
public void onDateFimSelected(String dataFim) {
Log.i("data final:", dataFim);
}
Обратные вызовы являются строками, поскольку даты являются параметрами в выборе запроса.
Код для фрагментов (на основе исходного фрагмента даты):
public class DateIniRangeFragment extends Fragment {
OnDateIniSelectedListener callbackIni;
private DatePicker startDatePicker;
public DateIniRangeFragment() {
///required empty constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
///through this interface the fragment sends data to the container activity
public interface OnDateIniSelectedListener {
void onDateIniSelected(String dataIni);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
///layout for the fragment
View v = inflater.inflate(R.layout.date_ini_fragment, container, false);
///initial date for the picker, in this case, current date
startDatePicker = (DatePicker) v.findViewById(R.id.start_date_picker_appcompat);
Calendar c = Calendar.getInstance();
int ano = c.get(Calendar.YEAR);
int mes = c.get(Calendar.MONTH);
int dia = c.get(Calendar.DAY_OF_MONTH);
startDatePicker.setSpinnersShown(false);
startDatePicker.init(ano, mes, dia, dateSetListener);
return v;
}
///listener that receives the selected date
private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() {
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
if (view.isShown()) { ///if the datepicker is on the screen
String sDataIni = year + "-" + (monthOfYear + 1) + "-" + dayOfMonth;
callbackIni.onDateIniSelected(sDataIni); //apply date to callback, string format
}
}
};
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
/*
* this function guarantees that the container activity implemented the callback interface
* */
try {
callbackIni = (OnDateIniSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " deve implementar OnDateIniSelectedListener");
}
}
}
Чтобы составить контейнер + фрагменты, я использовал ViewPager (AppCompat) с пользовательским классом, который расширяет FragmentPagerAdapter. Нет диалогов.
Ответ 9
Просто вы можете использовать EventBus, это просто и отлично работает
EventBus за 3 шага
-
Определить события:
public static class MessageEvent {/* Additional fields if needed */}
-
Подготовьте подписчиков: объявите и аннотируйте свой метод подписки, опционально укажите режим потока:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
Зарегистрируйте и отмените регистрацию своего подписчика. Например, на Android, действия и фрагменты должны обычно регистрироваться в соответствии со своим жизненным циклом:
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
-
Почтовые события:
EventBus.getDefault().post(new MessageEvent());
Ответ 10
Это работает на меня..
в Activity добавьте этот метод
public void GetData(String data)
{
// do something with your data
}
и в Фрагменте добавьте эту строку
((YourActivity)getContext).GetData("your data here");
Ответ 11
public class Fragmentdemo extends Fragment {
public interface onDemoEventListener {
public void demoEvent(String s);
}
onDemoEventListener demoEventListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
demoEventListener = (onDemoEventListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onDemoEventListener");
}
}
final String LOG_TAG = "TAG";
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragmentdemo, null);
Button button = (Button) v.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
demoEventListener.someEvent("Test text to Fragment1");
}
});
enter code here
return v;
}
}
Ответ 12
Я знаю, что это может быть поздно. Но я также всегда терялся в этом вопросе. Я делюсь этой ссылкой... потому что это, возможно, лучшее объяснение, которое я когда-либо нашел в Интернете для этого. Это решает фрагмент к деятельности и фрагмент к фрагменту !
Решил и объяснил очень хорошо
Ответ 13
Еще один простой способ получить данные, переданные из другого действия, в фрагменте в активности контейнера:
например:
Activity_A = > Activity_B (фрагмент)
В вашей Activity_A вы создаете намерение, как будто вы отправляете данные (String здесь) в другое действие:
Intent intent = new Intent(getBaseContext(),Activity_B.class);
intent.putExtra("NAME", "Value");
startActivity(intent);
в вашем фрагменте, содержащемся в вашем Activity_B:
String data = getActivity().getIntent().getExtras();