在FragmentA和FragmentB之间传递数据

时间:2018-12-16 22:17:55

标签: android android-fragments

如何在Fragments之间传递数据。

我已经创建了InstructionActivityInstructionsFragmentStepsFragmentSharedViewModel。我正在尝试将String从InstructionsFragment传递到StepsFragment

这是我的logCat中的结果:

  

D / StepsFragment:THIS com.shawn.nichol.bakingapp.Fragments.SharedViewModel@23e39c0 ​​

我还将整个代码放在GitHub上。

SharedViewModel:

public class SharedViewModel extends ViewModel {
private final MutableLiveData<String> stepPosition = new MutableLiveData<>();

public void setStepPosition(String position) {
    stepPosition.setValue(position);
}

public MutableLiveData getStepPosition() {
    return stepPosition;
}
}

说明片段:

public class InstructionsFragment extends Fragment {
private static final String LOGTAG = "InstructionsFragment";

private RecyclerView mRecyclerView;
private InstructionsAdapter mAdapter;

private String mAllIngredients;

private SharedViewModel model;

// Empty constructor
public InstructionsFragment() {
}



public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle onSavedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_instructions, container, false);

    model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

    mRecyclerView = (RecyclerView) view.findViewById(R.id.ingredients_instructions_rv_fragments);

    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    mRecyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity().getApplicationContext(),
            mRecyclerView, new RecyclerTouchListener.ClickListener() {

        @Override
        public void onClick(View view, int position) {
            Log.d(LOGTAG, "Step " + (position + 1) + " " +
                    InstructionsExtractSteps.stepsShortDescriptionList.get(position));

            model.setStepPosition("HELP");




            FragmentManager mFragmentManager = getFragmentManager();

            StepsFragment mStepsFragment = new StepsFragment();

            FragmentTransaction mFragmentTransaction = mFragmentManager.beginTransaction();
            mFragmentTransaction
                    .replace(R.id.instructions_place_holder, mStepsFragment)
                    // Puts InstructionsFragment on back stack, when back button is press it will
                    // reload that fragment instead of going back to the RecipeActivity.
                    .addToBackStack(null)
                    .commit();
        }

        @Override
        public void onLongClick(View view, int position) {

        }
    }));

    mAdapter = new InstructionsAdapter();
    mRecyclerView.setAdapter(mAdapter);

    return view;
}

/**
 * onViewCreated: I found this to be the only way to update the TextView in fragment_instructions.xml
 *
 * @param view
 * @param savedInstanceState
 */
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState){
    TextView mLoadIngredients = (TextView)getView().findViewById(R.id.ingredients_tv_fragment);

    // Set ingredients to screen
    for(int i = 0; i < InstructionsExtractIngredients.ingredientList.size(); i++) {
        if(i == 0) {
            mAllIngredients = "- " + InstructionsExtractIngredients.ingredientList.get(i);
        } else {
            mAllIngredients = mAllIngredients + "\n - " + InstructionsExtractIngredients.ingredientList.get(i);
        }
    }
    Log.d(LOGTAG, mAllIngredients);
    mLoadIngredients.setText(mAllIngredients);
}
}

步骤片段:

public class StepsFragment extends Fragment {
private static final String LOGTAG = "StepsFragment";

// Requires an empty constructor
public StepsFragment() {
}


public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_step, container, false);

    final SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

    model.getStepPosition();

    Log.d(LOGTAG, "THIS " + model);

    return view;
}
}

2 个答案:

答案 0 :(得分:2)

您可以使用接口来允许两个片段及其未弃用之间的通信

但是更好的替代选择是使用架构组件

只需将以下库添加到您的应用gradle文件

implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation 'android.arch.lifecycle:runtime:1.1.1'

,然后创建如下所示的类

import android.arch.lifecycle.ViewModel;
import android.support.annotation.NonNull;

public class TestViewModel extends ViewModel {

private MutableLiveData<String> fragmentAClicked;

public LiveData<String> getFragmentAClicked() {
       if (fragmentAClicked == null) {
              fragmentAClicked = new MutableLiveData<String>(); 
       }
                return fragmentAClicked;
}

public void fragmentAIsClicked(){
           fragmentAClicked.setValue("I am clicked")
}

}

在活动类中添加以下代码

public class MyActivity extends AppCompatActivity {
     TestViewModel model;
     public void onCreate(Bundle savedInstanceState) {

        model = ViewModelProviders.of(this).get(TestViewModel.class);

     }
    }

假设您有两个片段A和B

public class FragmentB extends Fragment {
    private TestViewModel model;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        model =ViewModelProviders.of(getActivity()).get(TestViewModel.class);

        //communicating with fragment  
        model.fragmentAIsClicked();
    }
}

public class FragmentA extends Fragment {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TestViewModel model = ViewModelProviders.of(getActivity()).get(TestViewModel.class);
        model.getFragmentAClicked().observe(this, { msg ->
           Log.d("test","message from fragmentA is " + msg)
        });
    }
}

所以基本上,您的想法是基于mvvm设计模式的viewmodel类,该类可处理活动,片段之间使用事件进行的所有通信

有关更多信息,请检查此here

答案 1 :(得分:0)

我不知道您的目的是什么,但是您可以使用POJO类在片段之间传递。

public class Test {
    public static class FragmentScanIDGInfo {
        public String getLastName() { return lastName; }
        public void setLastName(String lastName) { this.lastName = lastName; }

        public String getFirstName() { return firstName; }
        public void setFirstName(String firstName) { this.firstName = firstName; }

        String lastName = "";
        String firstName = "";

        public static FragmentScanIDGInfo shared;
        public static FragmentScanIDGInfo sharedSingleton() {
            if (shared == null) {
                shared = new FragmentScanIDGInfo();
            }
            return shared;
        }

        FragmentScanIDGInfo() {
            this.setLastName("");
            this.setFirstName("");
        }
    }
}

您可以设置并达到自己的目的,例如:

Test.FragmentScanIDGInfo scanDataFragment = Test.FragmentScanIDGInfo.sharedSingleton();
scanDataFragment.setFirstName(""); /* set data first name */
scanDataFragment.getFirstName();   /* get data first name */