如何将数据从Recyclerview传递到Fragment

时间:2016-09-09 22:22:35

标签: java android android-fragments android-recyclerview

我有一个填充在Fragment中的recyclelerView,我想启动一个新的Fragment并从适配器传递数据,我尝试使用Bundles但它总是给我的适配器类

一个空值
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private LayoutInflater inflater;
private List<Information> mList;
private FragmentCommunication mCommunicator;

public RecyclerAdapter(Context context, List<Information> list,FragmentCommunication communication) {
    inflater = LayoutInflater.from(context);
    mList = list;
    mCommunicator=communication;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.single_row, parent, false);
    MyViewHolder holder = new MyViewHolder(view,mCommunicator);
    return holder;
}

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {

    final Information current = mList.get(position);
    holder.name.setText(current.name);
    holder.job.setText(current.job);

    FragmentB fragmentB=new FragmentB();
    Bundle bundle=new Bundle();
    bundle.putString("NAME",current.name);
    bundle.putString("JOB",current.job);
    fragmentB.setArguments(bundle);

}

@Override
public int getItemCount() {
    return mList.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView name;
    TextView job;
    FragmentCommunication mComminication;

    public MyViewHolder(View itemView, FragmentCommunication Communicator) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.tv_name);
        job = (TextView) itemView.findViewById(R.id.tv_gob);
        mComminication=Communicator;
        name.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        mComminication.respond(getAdapterPosition());
    }
}

这是我要发布的新片段

public class FragmentB extends Fragment {
TextView textview;
TextView textView2;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view= inflater.inflate(R.layout.fragment_b,container,false);

    textview= (TextView) view.findViewById(R.id.tv_name);
    textView2= (TextView) view.findViewById(R.id.tv_job);
    return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    Bundle arguments = getArguments();


        if (arguments!=null){
        String name= arguments.get("NAME").toString();
        String job= arguments.get("JOB").toString();
            textview.setText(name);
            textView2.setText(job);}

}

}

这是我连接Fragment和recyclerview Adapter的方式 带接口

public interface FragmentCommunication {
void respond(int position);

}

这是填充了recyclerview的片段

public class RecyclerViewFragment extends Fragment {
RecyclerView mRecyclerView;
RecyclerAdapter mRecyclerAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view= inflater.inflate(R.layout.recycler_fragment,container,false);

    mRecyclerView= (RecyclerView) view.findViewById(R.id.recycler);
    mRecyclerAdapter=new RecyclerAdapter(getActivity(),getData(),communication);
    mRecyclerView.setAdapter(mRecyclerAdapter);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    return view;
}

public static List<Information> getData() {
    List<Information>data=new ArrayList<>();
    String[] names={"ahmed","mohammed"};
    String[] jobs={"sacsd","csscs"};

    for (int i=0;i<names.length;i++){
        Information current=new Information();
        current.name=(names[i]);
        current.job=(jobs[i]);
        data.add(current);
    }
    return data;
}

FragmentCommunication communication=new FragmentCommunication() {
    @Override
    public void respond(int position) {
        FragmentB fragmentB=new FragmentB();
        FragmentManager manager=getFragmentManager();
        FragmentTransaction transaction=manager.beginTransaction();
        transaction.replace(R.id.dumper,fragmentB).commit();
    }

};

}

我的mainActivity类只是添加了RecyclerViewFragment

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RecyclerViewFragment fragment=new RecyclerViewFragment();
    FragmentManager manager=getSupportFragmentManager();
    FragmentTransaction transaction=manager.beginTransaction();
    transaction.add(R.id.dumper,fragment).commit();
}

}

那么启动fragmentB并将数据从recyclerview Adapter传递给fragmentB

的正确方法是什么

5 个答案:

答案 0 :(得分:6)

谢谢大家的答案,我使用带有String值的接口解决了问题,将适配器连接到包含recyclerview的片段,这里的另一个片段就是我所做的: 这是界面

public interface FragmentCommunication {
void respond(int position,String name,String job);

}

这是适配器

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
private LayoutInflater inflater;
private List<Information> mList;
private FragmentCommunication mCommunicator;

public RecyclerAdapter(Context context, List<Information> list,FragmentCommunication communication) {
    inflater = LayoutInflater.from(context);
    mList = list;
    mCommunicator=communication;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.single_row, parent, false);
    MyViewHolder holder = new MyViewHolder(view,mCommunicator);
    return holder;
}

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {

    final Information current = mList.get(position);
    holder.name.setText(current.name);
    holder.job.setText(current.job);

    FragmentB fragmentB=new FragmentB();
    Bundle bundle=new Bundle();
    bundle.putString("NAME",current.name);
    bundle.putString("JOB",current.job);
    fragmentB.setArguments(bundle);

}

@Override
public int getItemCount() {
    return mList.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView name;
    TextView job;
    FragmentCommunication mComminication;

    public MyViewHolder(View itemView, FragmentCommunication Communicator) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.tv_name);
        job = (TextView) itemView.findViewById(R.id.tv_gob);
        mComminication=Communicator;
        name.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        mComminication.respond(getAdapterPosition(),mList.get(getAdapterPosition()).name,mList.get(getAdapterPosition()).job);
    }
}

}

包含recyclerview的片段

public class RecyclerViewFragment extends Fragment {
RecyclerView mRecyclerView;
RecyclerAdapter mRecyclerAdapter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view= inflater.inflate(R.layout.recycler_fragment,container,false);

    mRecyclerView= (RecyclerView) view.findViewById(R.id.recycler);
    mRecyclerAdapter=new RecyclerAdapter(getActivity(),getData(),communication);
    mRecyclerView.setAdapter(mRecyclerAdapter);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    return view;
}

public static List<Information> getData() {
    List<Information>data=new ArrayList<>();
    String[] names={"ahmed","mohammed"};
    String[] jobs={"sacsd","csscs"};

    for (int i=0;i<names.length;i++){
        Information current=new Information();
        current.name=(names[i]);
        current.job=(jobs[i]);
        data.add(current);
    }
    return data;
}

FragmentCommunication communication=new FragmentCommunication() {
    @Override
    public void respond(int position,String name,String job) {
        FragmentB fragmentB=new FragmentB();
        Bundle bundle=new Bundle();
        bundle.putString("NAME",name);
        bundle.putString("JOB",job);
        fragmentB.setArguments(bundle);
        FragmentManager manager=getFragmentManager();
        FragmentTransaction transaction=manager.beginTransaction();
        transaction.replace(R.id.dumper,fragmentB).commit();
    }

};

}

这是片段B,我从适配器获取字符串

public class FragmentB extends Fragment {
TextView textview;
TextView textview2;
String name;
String job;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    name=getArguments().getString("NAME");
    job=getArguments().getString("JOB");

}

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

    textview= (TextView) view.findViewById(R.id.getName);
    textview2= (TextView) view.findViewById(R.id.getJob);
    textview.setText(name);
    textview2.setText(job);


    return view;

}

}

答案 1 :(得分:2)

如果您正在使用Kotlin,则解决方案要简单得多。 Original Answer here

将功能val itemClick: (Int) -> Unit传递给适配器。

class MyRecyclerViewAdapter(params , val itemClick: (Int) -> Unit): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
internal inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    ...
    itemView.setOnClickListener( {itemClick(layoutPosition)} )
  } 
}  

在片段中,使用返回值position

val myAdapter = MyRecyclerViewAdapter(params) { position ->
    // do something
}

答案 2 :(得分:1)

如果我正确理解你的问题,可以在适配器中创建一个监听器接口,也可以使用常规的旧getter。

答案 3 :(得分:0)

使用Bundle时你有正确的想法。您只需通过调用setArguments()将其传递给Fragment即可。然后,使用getArguments()检索Bundle中的Fragment

请注意,您可以mList.get(position).name代替current.name。同样适用于job

问题的另一部分是你在两个不同的地方创建FragmentB。在一个地方你也调用setArguments()但不显示片段。在另一个中,您显示片段但不调用setArguments()。如果您确实需要从代码的多个部分执行此操作,则应编写一种方法来避免这些不一致。

答案 4 :(得分:0)

您需要通过setArguments(Bundle args)方法将Bundle传递给片段。由于您尚未设置参数,因此您尝试在Fragment中提取的包将解析为null。