Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass data from Recyclerview to Fragment

I have a recyclerView populated in a Fragment and I want to Launch a new Fragment and pass data from the adapter ,I try to use Bundles but it always give a null value this my Adapter Class

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());
    }
}

and this is my new Fragment that I want to launch

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);}

}

}

this is how I connect Fragment and recyclerview Adapter with interface

public interface FragmentCommunication {
void respond(int position);

}

and this the Fragment where the recyclerview is populated

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();
    }

};

}

and my mainActivity class is just add the 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();
}

}

so what is the right way to launch fragmentB and pass the data from recyclerview Adapter to fragmentB

like image 315
Ahmed Ezzat Avatar asked Sep 09 '16 22:09

Ahmed Ezzat


3 Answers

If you are working with kotlin, the solution is much simpler. Original Answer here

pass the function val itemClick: (Int) -> Unit to your adapter.

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

In your fragment use the returned value position

val myAdapter = MyRecyclerViewAdapter(params) { position ->
    // do something
}
like image 96
pz64_ Avatar answered Oct 19 '22 02:10

pz64_


thank you guys for the answer,I solved the problem using an interface with String values to connect the adapter with the fragment that contains the recyclerview and the other fragment here is what I did exactly : this is the interface

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

and this is the adapter

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);
        }
    }
}

the fragment that contains the 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();
        }

    };

}

this is the fragmentB where I get the Strings from the Adapter

    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;

    }


}
like image 22
Ahmed Ezzat Avatar answered Oct 19 '22 03:10

Ahmed Ezzat


Either creating a listener interface in the adapter or using regular old getters, if I understand your question correctly.

like image 22
itayrabin Avatar answered Oct 19 '22 04:10

itayrabin