根据从片段A收集的数据,使用较少的样板代码从Activity中启动片段B.

Red*_*d M 6 java android interface android-fragments android-activity

我有以下设置:

  1. 我有一个Activity推出了FragmentA.
    FragmentA包含一个recyclerView和一个adapter.

  2. interfaceA在适配器中有一个实现,FragmentA以便通知我点击了哪个位置.

  3. interfaceB创建了第二个FragmentA,它是在第1步Activity中启动的FragmentA.
  4. 最后,我是基于我得到的数据启动FragmentB的.ActivityinterfaceB

一切都工作正常,但流程繁琐,并需要很多样板代码.

目标activity启动fragmentB包含来自recyclelerView内的单个项目的数据FragmentA.

问题:它能以不同的方式实现吗?

代码如下:

Activity 推出FragmentA:

Fragment fragment = fragmentManager.findFragmentByTag(FragmentA.class.getName());
    if (fragment == null) {

        fragment = Fragment.instantiate(this, FragmentA.class.getName());
    }
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction
            .replace(R.id.fragmentLayout, fragment, FragmentA.class.getName())
            .addToBackStack(FragmentA.class.getName())
            .commit();
Run Code Online (Sandbox Code Playgroud)

FragmentA我们内部recyclerView,并interfaceA实施adapter:

适配器类:

        public class AdapterA extends RecyclerView.Adapter< AdapterA.ViewHolderA> {

        //instances
        private Context context;
        private List<Data> dataList;
        private OnItemClickListener onItemListClickListener;

        //Constructor
        public AdapterA (Context context, List<Data> dataList, OnItemClickListener onItemListClickListener {
        this.context = context;
        this.dataList = dataList;
        this.onItemListClickListener = onItemListClickListener;
    }

onCreateViewHolder....
onBindViewHolder....
getItemCount...

class ViewHolderA RecyclerView.ViewHolder {
//instances..
//Constructor...

}
        }
Run Code Online (Sandbox Code Playgroud)

interface class interfaceA:

public interface OnItemClickListener {
    void onItemClick(View view, int position);
}
Run Code Online (Sandbox Code Playgroud)

interface class interfaceB:

public interface SingleItemEventListener {
    void onSingleItemClicked(int position);
}
Run Code Online (Sandbox Code Playgroud)

FragmentA 类:

//Instances
private AdapterA adapter;
private RecyclerView recyclerView;
private onSingleItemClicked singleItemEventListener;

onAttach...
onCreateView...

@Override
public void onStart() {
    super.onStart();

    //Setting adapter
    onSetAdapter();
}

private void onSetAdapter() {
    List<Data> dataList;

    dataList = getData();

    adapter = new AdapterA(context, dataList, new OnItemClickListener() {
        @Override
        public void onItemClick(View view, int position) {
            singleItemEventListener.onSingleItemClicked(position);
        }
    });
Run Code Online (Sandbox Code Playgroud)

Activity,我们正在实现onSingleItemClicked回调以接收事件并FragmentB使用从接口回调接收的数据启动:

ActivityA implements SingleItemEventListener {
@Override
    public void onSingleItemClicked(int position) {
Data data = getData(position);

if (data != null) {
Bundle bundle = new Bundle();
bundle.putParcelable("single_data_key", data);
Fragment fragmentB = fragmentManager.findFragmentByTag(FragmentB.class.getName());

        if (fragmentB == null && bundle != null) {
            fragmentB = Fragment.instantiate(this, FragmentB.class.getName(), bundle);
        }

        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction
                .replace(R.id.FragmentLayout, fragmentB, FragmentB.class.getName())
                .addToBackStack(FragmentB.class.getName())
                .commit();
}
}
}
Run Code Online (Sandbox Code Playgroud)

Tpo*_*6oH 3

将ViewModel添加到您的活动中,并使用它在所有组件、活动和两个片段之间进行通信。

您可以从片段访问活动的 ViewModel

MyViewModel model = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
Run Code Online (Sandbox Code Playgroud)

使用LiveData进行通信,从您的片段向其发布一个操作,并在您的活动中监听它以启动另一个片段。