I have managed to create a tabbed activity using recycle view and have made a list-view in each fragment, now I have the lists I need to make the cards in the fragment clickable and create an intent to start a new activity. I have tried on-click method and onListItemClick even though I knew that would not work.
Basically I need to create one more layer of lists for each fragment which will lead to a list of actions (webviews, Maps, and information).
Example Code is below
ublic class LOneFragment extends Fragment {
public LOneFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_blank, container, false);
RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.rv_recycler_view);
rv.setHasFixedSize(true);
MyAdapter adapter = new MyAdapter(new String[]{"League One News", "AFC Wimbledon", "Blackburn Rovers", "Blackpool", "Bradford City", "Bristol Rovers", "Bury", "Charlton Athletic", "Doncaster Rovers", "Fleetwood Town",
"Gillingham", "Milton Keynes Dons", "Northampton Town", "Oldham Athletic", "Oxford United", "Peterborough United", "Plymouth Argyle", "Portsmouth", "Rochdale", "Rotherham United",
"Scunthorpe United", "Shrewsbury Town", "Southend United", "Walsall", "Wigan Athletic"});
rv.setAdapter(adapter);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
return rootView;
}
public void onListItemClick(ListView l, View v, int position, long id) {
if (position == 3) {
Intent intent = new Intent(getContext(), Bradford.class);
startActivity(intent);
}
My adaptor class
public class MyAdapter extends RecyclerView.Adapter {
private String[] mDataset;
public static class MyViewHolder extends RecyclerView.ViewHolder{
public CardView mCardView;
public TextView mTextView;
public MyViewHolder(View v){
super(v);
mCardView = (CardView) v.findViewById(R.id.card_view);
mTextView = (TextView) v.findViewById(R.id.tv_text);
}
}
public MyAdapter(String[] myDataset){
mDataset = myDataset;
}
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_item, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position){
holder.mTextView.setText(mDataset[position]);
}
#Override
public int getItemCount() { return mDataset.length; }
}
This works perfect for me.
1) Create method in viewholder class which will take position, get array item from position and use the way you like.
2) Access it in onBindViewHolder method with itemView instance which is the full row at given position,
public class MyAdapter extends RecyclerView.Adapter {
private String[] mDataset;
public MyAdapter(String[] myDataset){
mDataset = myDataset;
}
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_item, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position){
holder.mTextView.setText(mDataset[position]);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.bindCliks(groupItem);
}
});
#Override
public int getItemCount() { return mDataset.length; }
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
public CardView mCardView;
public TextView mTextView;
public MyViewHolder(View v){
super(v);
mCardView = (CardView) v.findViewById(R.id.card_view);
mTextView = (TextView) v.findViewById(R.id.tv_text);
}
public void bindCliks(int position) {
Intent intent = new Intent(context,
OtherActivity.class);
//use number here to get your string item and use it to other activity.
context.startActivity(intent);
}
}
Related
I am a beginner at android development. I tried to display data on Recycle View using MVVM. When I opened the fragment the first time it is empty, the second time it showed data. Adapter not called the first time. How to fix this.
Fragment class
public class fragmentEmployee extends Fragment {
private FragmentEmployeeBinding binding;
private ViewGroup viewGroup;
private View view;
private RecyclerView mRecycleView;
private UserAdapter mAdapter;
private EmployeeRegisterViewModel viewModel;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_employee, viewGroup, false);
view = binding.getRoot();
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Toast.makeText(getContext(), "onViewCreated", Toast.LENGTH_SHORT).show();
mRecycleView = binding.recyleViewEmployee;
viewModel = new ViewModelProvider(this).get(EmployeeRegisterViewModel.class);
viewModel.init();
initRecycleView();
viewModel.getEmployee().observe(getViewLifecycleOwner(), new Observer<List<employeeModel>>() {
#Override
public void onChanged(List<employeeModel> employeeModels) {
mAdapter.notifyDataSetChanged();
}
});
}
private void initRecycleView() {
mAdapter = new UserAdapter(getContext(), viewModel.getEmployee().getValue());
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
mRecycleView.setLayoutManager(layoutManager);
mRecycleView.setAdapter(mAdapter);
}
}
UserAdapter class
public class UserAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
public List<employeeModel> employeeModelList= new ArrayList<>();
public Context context1;
public UserAdapter(Context context,List<employeeModel> employeeModels){
employeeModelList = employeeModels;
context1 = context;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_listitem,parent,false);
ViewHolder viewHolder=new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
(ViewHolder)holder).username.setText(employeeModelList.get(position).getName());
}
#Override
public int getItemCount() {
return employeeModelList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView username;
public ViewHolder(#NonNull View itemView) {
super(itemView);
username=itemView.findViewById(R.id.userText);
}
}
}
Try reordering like this.
Remove
mAdapter = new UserAdapter(getContext(), viewModel.getEmployee().getValue());
from initRecycleView
mAdapter = new UserAdapter(getContext(), viewModel.getEmployee().getValue());
viewModel.getEmployee().observe(getViewLifecycleOwner(), new Observer<List<employeeModel>>() {
#Override
public void onChanged(List<employeeModel> employeeModels) {
mAdapter.notifyDataSetChanged();
}
});
initRecycleView();
mAdapter.notifyDataSetChanged();
Above method will work if the list declared inside adapter has any change. So, calling above method without changing adapter's list is useless.
Add a method to UserAdapter class to update list data. Like:
public void updateData(List<employeeModel> updatedList){
employeeModelList.clear();
employeeModelList.addAll(updatedList);
notifyDataSetChanged();
}
And call this method inside observer. Like:
viewModel.getEmployee().observe(getViewLifecycleOwner(), new
Observer<List<employeeModel>>() {
#Override
public void onChanged(List<employeeModel> employeeModels) {
mAdapter.updateData(employeeModels);
}
});
where are you get your network data?
If your get in here -> viewModel.init();
I think it just timing problem.
Just change code sequence
initRecycleView();
viewModel.getEmployee().observe(getViewLifecycleOwner(), new Observer<List<employeeModel>>() {
#Override
public void onChanged(List<employeeModel> employeeModels) {
mAdapter.notifyDataSetChanged();
}
});
viewModel.init();
I'm trying to populate a RecyclerView using data stored in a ArrayList. When the RecyclerView loads each piece of data is repeted 4x in each row.
I've tried a whole variety of solutions I've found, but none seem to resolve the issue.
After some debugging the data in 'mData', appears to be correct, so that would lead me to believe that this issue is 'onBindViewHolder'?
Adapter
public class EventsRecyclerViewAdapter extends RecyclerView.Adapter<EventsRecyclerViewAdapter.ViewHolder> {
private List<String> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public EventsRecyclerViewAdapter(List<String> data) {
this.mInflater = LayoutInflater.from(MainActivity.mainActivity);
this.mData = data;
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.keyID.setText(mData.get(position));
holder.lockID.setText(mData.get(position));
holder.eventTime.setText(mData.get(position));
holder.eventType.setText(mData.get(position));
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView keyID;
TextView lockID;
TextView eventTime;
TextView eventType;
ViewHolder(View itemView) {
super(itemView);
keyID = itemView.findViewById(R.id.keyIDTV);
lockID = itemView.findViewById(R.id.lockIDTV);
eventTime = itemView.findViewById(R.id.eventDateTV);
eventType = itemView.findViewById(R.id.eventTypeTV);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
Fragment
public class KeyEvents extends Fragment {
public static KeyInfo newInstance() {
KeyInfo fragment = new KeyInfo();
return fragment;
}
EventsRecyclerViewAdapter adapter;
ArrayList<String> eventsList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventsOperationHandler ev = new EventsOperationHandler();
eventsList = new ArrayList<>();
for (int i=0; i<ev.getEvents().size(); i++) {
eventsList.add(ev.getEvents().get(i).get(0));
eventsList.add(ev.getEvents().get(i).get(1));
eventsList.add(ev.getEvents().get(i).get(2));
eventsList.add(ev.getEvents().get(i).get(3));
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_event_info, container, false);
RecyclerView recyclerView = view.findViewById(R.id.rvEvents);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.mainActivity));
adapter = new EventsRecyclerViewAdapter(eventsList);
recyclerView.setAdapter(adapter);
return view;
}
}
In your 'onBindViewHolder' you are setting same data in every textView of yours
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.keyID.setText(mData.get(position));
holder.lockID.setText(mData.get(position));
holder.eventTime.setText(mData.get(position));
holder.eventType.setText(mData.get(position));
}
Here you are setting mData.get(position) to every textView in the holder
A solution would be creating a Pojo class for your recyclerView
Create Pojo Event class
class Event{
public String keyID;
public String lockID;
public String eventTime;
public String eventType;
}
Create a list of 'Event' in your fragment
public class KeyEvents extends Fragment {
public static KeyInfo newInstance() {
KeyInfo fragment = new KeyInfo();
return fragment;
}
EventsRecyclerViewAdapter adapter;
ArrayList<Event> eventsList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventsOperationHandler ev = new EventsOperationHandler();
eventsList = new ArrayList<>();
for (int i=0; i<ev.getEvents().size(); i++) {
Event event = new Event();
event.keyID = ev.getEvents().get(i).get(0);
event.lockID = ev.getEvents().get(i).get(1);
event.eventTime = ev.getEvents().get(i).get(2);
event.eventType = ev.getEvents().get(i).get(3);
eventsList.add(event);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_event_info, container, false);
RecyclerView recyclerView = view.findViewById(R.id.rvEvents);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.mainActivity));
adapter = new EventsRecyclerViewAdapter(eventsList);
recyclerView.setAdapter(adapter);
return view;
}
}
Modify your recyclerView to handle to 'Event' class
public class EventsRecyclerViewAdapter extends RecyclerView.Adapter<EventsRecyclerViewAdapter.ViewHolder> {
private List<Event> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public EventsRecyclerViewAdapter(List<Event> data) {
this.mInflater = LayoutInflater.from(MainActivity.mainActivity);
this.mData = data;
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Event event = mData.get(position);
holder.keyID.setText(event.keyID);
holder.lockID.setText(event.lockId);
holder.eventTime.setText(event.eventTime);
holder.eventType.setText(event.eventType);
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView keyID;
TextView lockID;
TextView eventTime;
TextView eventType;
ViewHolder(View itemView) {
super(itemView);
keyID = itemView.findViewById(R.id.keyIDTV);
lockID = itemView.findViewById(R.id.lockIDTV);
eventTime = itemView.findViewById(R.id.eventDateTV);
eventType = itemView.findViewById(R.id.eventTypeTV);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
That's it, this should work perfectly.
I'm trying to add a recyclerview to a fragment, but somehow there happens to be an error in the adapter.
I think it is the way in which I bind it, and I can't figure out the solution to it. Can anybody help me solve the issue?
here's my adapter:
public class MyLeaguesListAdapter extends
RecyclerView.Adapter<MyLeaguesListAdapter.MyViewHolder>{
List<MyContest> listItems;
Context context;
public interface OnItemClickListener {
void onItemClick(View v,int pos);
}
public MyLeaguesListAdapter(List<MyContest> listItems,Context context){
this.listItems = listItems;
this.context = context;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v;
v = LayoutInflater.from(context).inflate(R.layout.my_contest_item,parent,false);
MyViewHolder myViewHolder = new MyViewHolder(v);
return myViewHolder;
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView leagueName,playerName,prizePool,playerRank,playerPoints,entryFee,spots;
OnItemClickListener onItemCheckListener;
public MyViewHolder(View itemView) {
super(itemView);
leagueName = (TextView) itemView.findViewById(R.id.mc_contest_name);
playerName = (TextView) itemView.findViewById(R.id.mc_player_name);
prizePool = (TextView) itemView.findViewById(R.id.mc_prize_pool);
playerRank = (TextView) itemView.findViewById(R.id.mc_player_rank);
playerPoints = (TextView) itemView.findViewById(R.id.mc_player_points);
entryFee = (TextView) itemView.findViewById(R.id.mc_entry_fee);
spots = (TextView) itemView.findViewById(R.id.mc_spots);
itemView.setOnClickListener(this);
}
public void setItemClickListener(OnItemClickListener ic){
this.onItemCheckListener = ic;
}
#Override
public void onClick(View view) {
this.onItemCheckListener.onItemClick(view,getAdapterPosition());
}
}
#Override
public int getItemCount() {
return listItems.size();
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
MyContest listItem = listItems.get(position);
holder.leagueName.setText(listItem.getLeaguename());
holder.prizePool.setText(listItem.getPrizepool());
holder.playerPoints.setText(listItem.getScore());
holder.playerRank.setText(listItem.getRank());
holder.playerName.setText(listItem.getUsername());
holder.spots.setText(listItem.getSpots());
holder.entryFee.setText(listItem.getFee());
holder.setItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(View v, int pos) {
}
});
}
}
this is my fragment:
public class MyLeagues extends Fragment {
SharedPreferences sharedPreferences,ui;
int score,userid,i=0;
String username,lname,inviteCode;
List<MyContest> list_item;
MyLeaguesListAdapter adapter;
ProgressBar progressBar;
Sprite fadingCircle;
RecyclerView recyclerView;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_leagues,null);
ui = this.getActivity().getSharedPreferences("User",Context.MODE_PRIVATE);
userid = ui.getInt("userid",-1);
progressBar = (ProgressBar) view.findViewById(R.id.mcspin_kit);
fadingCircle = new FadingCircle();
progressBar.setIndeterminateDrawable(fadingCircle);
Log.d("eede", "onCreateView: "+inviteCode);
recyclerView = (RecyclerView) view.findViewById(R.id.mc_recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL));
list_item = new ArrayList<>();
getMYContests();
return view;
}
public void getMYContests(){
Call<MyContestResponse> call = RetrofitClient
.getInstance()
.getApi()
.getMycontests(userid);
call.enqueue(new Callback<MyContestResponse>() {
#Override
public void onResponse(Call<MyContestResponse> call, Response<MyContestResponse> response) {
list_item=response.body().getData();
adapter = new MyLeaguesListAdapter(list_item,getContext());
progressBar.setVisibility(View.INVISIBLE);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<MyContestResponse> call, Throwable t) {
Log.d("bruv", "onFailure: "+t);
}
});
}
}
error:
07-03 09:36:20.980 30095-30095/? E/AndroidRuntime: FATAL EXCEPTION:
main
Process: com.example.android.khelo, PID: 30095
android.content.res.Resources$NotFoundException: String resource ID #0xffffffff
at android.content.res.Resources.getText(Resources.java:363)
at android.widget.TextView.setText(TextView.java:6485)
at com.example.android.khelo.MyLeaguesListAdapter.onBindViewHolder(MyLeaguesListAdapter.java:75)
at com.example.android.khelo.MyLeaguesListAdapter.onBindViewHolder(MyLeaguesListAdapter.java:20)
from what I've read, the issue is with the way I bind the recylerview but I've not got a clear idea about where the issue actually lies.
It is possible that one or many of your listItem attributes return an integer like getScore and getFee. So let's look at the implementation of TextView.setText(int)
public final void setText(int resid) {
...
}
As you can see, it only accepts the int as a resource id like R.string.something.
So what you can do here is to make your int become string when setText like
holder.playerPoints.setText(listItem.getScore().toString());
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
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;
}
}
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
}
Either creating a listener interface in the adapter or using regular old getters, if I understand your question correctly.
You need to pass the Bundle to the fragment through the setArguments(Bundle args) method. Since you have not set arguments, the bundle you try to extract in your Fragment resolves to null.
You have the right idea with using a Bundle. You just need to pass it to the Fragment by calling setArguments(). Then you retrieve the Bundle in your Fragment with getArguments().
Note that instead of mList.get(position).name, you can do current.name. Similarly for job.
Another part of the problem is that you create FragmentB on two different places. In one place you also call setArguments() but do not show the fragment. In the other you show the fragment but do not call setArguments(). If you really need to do this from multiple parts of your code you should write a method to avoid these inconsistencies.
Please I would like someone to help point me in the right direction with using the ParseRecyclerQueryAdapter. I'm trying to retrieve articles with my current adapter class that implements the standard RecyclerView. my implementation of pagination is not working properly soIi would like a demonstration from anyone that has used the ParseRecyclerQueryAdapter to achieve the following. By translating it from me so I get the implementation.
public class ArticleRVAdapter extends RecyclerView.Adapter {
List<Article> articleData = Collections.emptyList();
private LayoutInflater inflater;
private Context context;
public ArticleRVAdapter(Context context, List<Article> data){
inflater=LayoutInflater.from(context);
this.articleData= data;
this.context = context;
}
#Override
public ArticleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.article_item, parent, false);
ArticleViewHolder viewHolder = new ArticleViewHolder(view);
return viewHolder;
}
#Override
public int getItemCount() {
return articleData.size();
}
public class ArticleViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
CardView cardView;
TextView title;
TextView body;
Date dateCreated;
TextView author;
ImageView headImage;
String objectId;
public ArticleViewHolder(final View itemView) {
super(itemView);
itemView.setClickable(true);
itemView.setLongClickable(true);
itemView.setOnClickListener(this);
cardView = (CardView) itemView.findViewById(R.id.card_article);
title = (TextView) itemView.findViewById(R.id.text_title);
body = (TextView) itemView.findViewById(R.id.text_article_body);
//dateCreated = itemView.findViewById(R.id.text_article_body);
author = (TextView) itemView.findViewById(R.id.text_author);
headImage = (ImageView) itemView.findViewById(R.id.imageView_thumb);
}
#Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), ArticleInformationActivity.class);
intent.putExtra("article_id", articleData.get(getLayoutPosition()).getObjectId());
intent.putExtra("article_title", articleData.get(getLayoutPosition()).getArticleTitle());
intent.putExtra("article_body", articleData.get(getLayoutPosition()).getArticleBody());
intent.putExtra("article_author", articleData.get(getLayoutPosition()).getArticleAuthor());
intent.putExtra("article_date", articleData.get(getLayoutPosition()).getDateCreated());
v.getContext().startActivity(intent);
}
}
After a lot of testing, I got the solution in my project:
Fragment (or Activity):
private RecyclerView mRecyclerView;
private MyQueryAdapter myQueryAdapter;
private SwipeRefreshLayout swipeRefreshLayout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.list_fragment, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.rv);
myQueryAdapter = new MyQueryAdapter(true);
mRecyclerView.setAdapter(myQueryAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
myQueryAdapter.addOnQueryLoadListener(new ParseRecyclerQueryAdapter.OnQueryLoadListener<MY_MODEL>() {
#Override
public void onLoaded(List<MY_MODEL> objects, Exception e) {
if (swipeRefreshLayout.isRefreshing()) {
swipeRefreshLayout.setRefreshing(false);
}
}
#Override
public void onLoading() {
if (!swipeRefreshLayout.isRefreshing()) {
swipeRefreshLayout.setRefreshing(true);
}
}
});
swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
myQueryAdapter.loadObjects();
}
});
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
myQueryAdapter.loadObjects();
}
Adapter
public class MyQueryAdapter extends ParseRecyclerQueryAdapter<MY_MODEL, MyQueryAdapter.MyViewHolder>{
public MyQueryAdapter(boolean hasStableIds) {
super(MY_MODEL.class, hasStableIds);
}
public MarcacionesAdapter(ParseQueryAdapter.QueryFactory<Marcaciones> factory, boolean hasStableIds) {
super(factory, hasStableIds);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(v);
return myViewHolder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
MY_MODEL model = getItem(position);
holder.name.setText(model.getName());
holder.year.setText(model.getYear());
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView name;
TextView year;
MyViewHolder(View itemView) {
super(itemView);
cv = (CardView)itemView.findViewById(R.id.card_view);
name = (TextView)itemView.findViewById(R.id.name);
year = (TextView)itemView.findViewById(R.id.year);
}
}
}
If you want to configure a custom query, you can do it in this way:
factory =
new ParseQueryAdapter.QueryFactory<MY_MODEL>() {
public ParseQuery< MY_MODEL > create() {
ParseQuery<MY_MODEL> query = MY_MODEL.getQuery();
query.include("user");
//Filter by date
query.whereGreaterThan("createdAt", midnight);
query.whereLessThan("createdAt", now);
query.orderByDescending("createdAt");
return query;
}
};
adapter = new MyQueryAdapter(factory, true);