如何在 Viewpager 片段之间同步数据
How to Synchronize Data Between Viewpager Fragments
使用以下代码,我可以单击一个按钮,将来自一个片段(片段 A)的字符串发送到 MainActivity。我如何从 MainActivity 中检索字符串并将其一次性显示在片段 B 上?我希望片段同步;单击片段 A 中的按钮后,片段 B 会立即更新。我似乎无法在 SO 中找到任何关于此的内容。
接口:
public interface OnDataListener {
public void onDataReceived(String data);
}
片段A数据侦听器:
OnDataListener mOnDataListener;
@Override
public void onAttach(Context context) {
try{
mOnDataListener = (OnDataListener) context;
Log.d(TAG, "onAttach was called" + context);
}catch (ClassCastException e){
Log.e(TAG, "onAttach: ClassCastException: " + e.getMessage() );
}
super.onAttach(context);
}
Fragment A 的 onCreateView 中的按钮逻辑:
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String newTextString = editTextView.getText().toString();
mOnDataListener.onDataReceived(newTextString);
}
});
MainActivity 数据接收者
public class MainActivity extends AppCompatActivity implements OnDataListener {
@Override
public void onDataReceived(String data) {
Log.e(TAG, "MainActivity received this string " + data );
}
}
解决方案 1
在您的 MainActivity 中
@Override
public void onDataReceived(String data) {
Log.e(TAG, "MainActivity received this string " + data );
Bundle bundle = new Bundle();
bundle.putString("edttext", data);
FragmentB fragment = new FragmentB();
fragment.setArguments(bundle);
// Fragment Transaction method goes here
}
在你的 FragmentB 中检索数据
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
解决方案 2
您可以将回调数据放入您的全局变量,并在onClickListerner 时在片段事务中使用它。
解决方案 3
A) 在 FragmentB 中创建方法
public void changeText (String data) {
textview.setText(data)
}
B) 并从 MainActivity 传递值
@Override
public void onDataReceived (String data) {
myInterface.CallBack("Callbacked when onCreate method Created" + data);
Log.d("Tiggered", "respond: ");
FragmentManager manager = getFragmentManager();
FragmentB fragmentB = (FragmentB) manager.findFragmentById(R.id.id_fragmentB);
fragmentB.changeText(data);
}
解决方案 1:使用回调
//如果您的片段实例处于活动状态,这将起作用,因此请检查 viewpager offscreenpage 限制
(您也可以使用 Farid Haq 提到的解决方案 3,它通过 activity 本身的工作来实现相同的效果)
这里,Activity实现回调OnDataUpdateListener
interface OnDataUpdateListener{
void passDataToFragmentB(String data)
}
Activity代码:
Fragment instanceFragmentB;
// intialise it somewhere in your activity
// or get from viewpager adapter
@Override
void passDataToFragmentB(String data){
instanceFragmentB.onDataChange(data)
}
片段A代码:
OnDataUpdateListener mOnDataUpdateListener;
onAttach(Activity activity){
mOnDataUpdateListener= (OnDataUpdateListener) activity
}
onViewCreated(){
somebutton.onClick{
mOnDataUpdateListener.passDataToFragmentB("someString")
}
}
片段B代码:
onDataChange(String data){
//do your work with update data passed from fragment A
}
方案二:使用EventBus或RxBus
//如果您的片段实例处于活动状态,这将起作用,因此请检查 viewpager offscreenpage 限制
使用事件或 rxbus,post 总线上的新更新值并使目标片段观察到相同的值类型。
片段 A:
onViewCreated(){
somebutton.onClick{
EventBus.post("your data")
}
}
片段 B:
@Subsribe
void onDataChange(String data){
//do your work with update data passed from fragment A
}
解决方案 3:使用 ViewModel。
在所有片段中获取上下文为 activity 的视图模型,并使用 LiveData 包装字符串。
每当更改字符串数据时,只需 post String Livedata 对象上的新数据。
所有观察实时数据的片段都将获得更新值。
使用以下代码,我可以单击一个按钮,将来自一个片段(片段 A)的字符串发送到 MainActivity。我如何从 MainActivity 中检索字符串并将其一次性显示在片段 B 上?我希望片段同步;单击片段 A 中的按钮后,片段 B 会立即更新。我似乎无法在 SO 中找到任何关于此的内容。
接口:
public interface OnDataListener {
public void onDataReceived(String data);
}
片段A数据侦听器:
OnDataListener mOnDataListener;
@Override
public void onAttach(Context context) {
try{
mOnDataListener = (OnDataListener) context;
Log.d(TAG, "onAttach was called" + context);
}catch (ClassCastException e){
Log.e(TAG, "onAttach: ClassCastException: " + e.getMessage() );
}
super.onAttach(context);
}
Fragment A 的 onCreateView 中的按钮逻辑:
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String newTextString = editTextView.getText().toString();
mOnDataListener.onDataReceived(newTextString);
}
});
MainActivity 数据接收者
public class MainActivity extends AppCompatActivity implements OnDataListener {
@Override
public void onDataReceived(String data) {
Log.e(TAG, "MainActivity received this string " + data );
}
}
解决方案 1
在您的 MainActivity 中
@Override
public void onDataReceived(String data) {
Log.e(TAG, "MainActivity received this string " + data );
Bundle bundle = new Bundle();
bundle.putString("edttext", data);
FragmentB fragment = new FragmentB();
fragment.setArguments(bundle);
// Fragment Transaction method goes here
}
在你的 FragmentB 中检索数据
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
解决方案 2
您可以将回调数据放入您的全局变量,并在onClickListerner 时在片段事务中使用它。
解决方案 3
A) 在 FragmentB 中创建方法
public void changeText (String data) {
textview.setText(data)
}
B) 并从 MainActivity 传递值
@Override
public void onDataReceived (String data) {
myInterface.CallBack("Callbacked when onCreate method Created" + data);
Log.d("Tiggered", "respond: ");
FragmentManager manager = getFragmentManager();
FragmentB fragmentB = (FragmentB) manager.findFragmentById(R.id.id_fragmentB);
fragmentB.changeText(data);
}
解决方案 1:使用回调
//如果您的片段实例处于活动状态,这将起作用,因此请检查 viewpager offscreenpage 限制
(您也可以使用 Farid Haq 提到的解决方案 3,它通过 activity 本身的工作来实现相同的效果)
这里,Activity实现回调OnDataUpdateListener
interface OnDataUpdateListener{
void passDataToFragmentB(String data)
}
Activity代码:
Fragment instanceFragmentB;
// intialise it somewhere in your activity
// or get from viewpager adapter
@Override
void passDataToFragmentB(String data){
instanceFragmentB.onDataChange(data)
}
片段A代码:
OnDataUpdateListener mOnDataUpdateListener;
onAttach(Activity activity){
mOnDataUpdateListener= (OnDataUpdateListener) activity
}
onViewCreated(){
somebutton.onClick{
mOnDataUpdateListener.passDataToFragmentB("someString")
}
}
片段B代码:
onDataChange(String data){
//do your work with update data passed from fragment A
}
方案二:使用EventBus或RxBus
//如果您的片段实例处于活动状态,这将起作用,因此请检查 viewpager offscreenpage 限制
使用事件或 rxbus,post 总线上的新更新值并使目标片段观察到相同的值类型。
片段 A:
onViewCreated(){
somebutton.onClick{
EventBus.post("your data")
}
}
片段 B:
@Subsribe
void onDataChange(String data){
//do your work with update data passed from fragment A
}
解决方案 3:使用 ViewModel。
在所有片段中获取上下文为 activity 的视图模型,并使用 LiveData 包装字符串。
每当更改字符串数据时,只需 post String Livedata 对象上的新数据。 所有观察实时数据的片段都将获得更新值。