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();
Related
This is the code in which I'm getting errors in startListening() and stopListening():
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_app_cart,container,false);
recyclerView = view.findViewById(R.id.recylervieww);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
cartmodelList = new ArrayList<>();
cartadapt = new cartAdapter(getActivity(),cartmodelList);
recyclerView.setAdapter(cartadapt);
FirebaseRecyclerOptions<Cartmodel> options =
new FirebaseRecyclerOptions.Builder<Cartmodel>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("Cart List"), Cartmodel.class)
.build();
cartadapt = new cartAdapter(options);
recyclerView.setAdapter(cartadapt);
return view;
}
#Override
public void onStart() {
super.onStart();
cartadapt.startListening();
}
#Override
public void onStop() {
super.onStop();
cartadapt.stopListening();
}
}
This is the code for cartAdapter:
public class cartAdapter extends RecyclerView.Adapter<cartAdapter.ViewHolder> {
Context context;
List<Cartmodel> cartmodelList;
public cartAdapter(Context context, List<Cartmodel> cartmodelList) {
this.context = context;
this.cartmodelList = cartmodelList;
}
public cartAdapter(FirebaseRecyclerOptions<Cartmodel> options) {
}
#NonNull
#Override
public cartAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_singlero,parent,false));
}
#Override
public void onBindViewHolder(#NonNull cartAdapter.ViewHolder holder, int position) {
holder.productName.setText(cartmodelList.get(position).getProductName());
holder.quantity.setText(cartmodelList.get(position).getQuantity());
holder.totalPrice.setText(cartmodelList.get(position).getTotalPrice());
Glide.with(holder.itemView.getContext()).load(Cartmodel.productImage()).into(holder.productImage);
}
#Override
public int getItemCount() {
return cartmodelList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView date,productName,productPrice,quantity,totalPrice;
ImageView productImage;
public ViewHolder(#NonNull View itemView) {
super(itemView);
productName = itemView.findViewById(R.id.pnametext);
quantity = itemView.findViewById(R.id.quantity);
totalPrice = itemView.findViewById(R.id.totalprice);
productImage = itemView.findViewById(R.id.img2);
}
}
}
I'm getting these errors:
Cannot resolve method 'startListening' in 'cartAdapter'
Cannot resolve method 'stopListening' in 'cartAdapter'
I'm using both classes in another activity but in those, I'm not getting any errors.
I'm getting error in startListening() and stopListening()
Because those methods are not present inside RecyclerView.Adapter class. Your adapter class should extend FirebaseRecyclerAdapter class instead in order to be able to call startListening() and stopListening().
For more info, please check the official documentation:
https://firebaseopensource.com/projects/firebase/firebaseui-android/database/readme/
I have 2 fragments. When I click like in one fragment, in the second fragment must appear news, which I liked.
Here is my favourite fragment I have a method Add()
RecyclerView recyclerView;
private FavouriteListAdapter adapter;
private List<News> newsList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_favourite, container,
false);
recyclerView = rootView.findViewById(R.id.recycler_favourite);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
newsList= new ArrayList<>();
adapter = new FavouriteListAdapter(newsList);
recyclerView.setAdapter(adapter);
return rootView;
}
public void addNews(News news) {
newsList.add(news);
recyclerView.getAdapter().notifyItemInserted(newsList.size() - 1);
}
In Home Fragment I use interface listener and add
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_home, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_home);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
listener = new NewsListAdapter.ItemClickListener() {
#Override
public void likeClick(int position, News item) {
add.respond(item);
newsListAdapter.notifyItemChanged(position);
}
};
add = new NewsListAdapter.Add() {
#Override
public void respond(News news) {
((MainActivity) getActivity()).respond(news);
}
};
newsListAdapter = new NewsListAdapter(newsGenerator(), listener, add);
recyclerView.setAdapter(newsListAdapter);
return rootView;
}
Adapter for Home
#Override
public void onBindViewHolder(#NonNull NewsListAdapter.NewsViewHolder holder, final int position)
{
final News news = mainList.get(position);
holder.theme.setText(news.getTheme());
holder.like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener!=null){
listener.likeClick(position,news);
}
}
});
#Override
public int getItemCount() {
return mainList.size();
}
public class NewsViewHolder extends RecyclerView.ViewHolder {
private TextView theme;
private ImageButton like;
public NewsViewHolder(#NonNull View itemView) {
super(itemView);
theme = itemView.findViewById(R.id.theme);
like = itemView.findViewById(R.id.like);
}
}
interface ItemClickListener {
void likeClick(int position, News item);
}
public interface Add{
void respond(News news);
}
Adaper for favourites. Adapter favourites contains News and we call method add here in MainActivity
#NonNull
#Override
public FavouriteListAdapter.FavouriteNewsHolder onCreateViewHolder(#NonNull ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news, null,false);
RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
view.setLayoutParams(params);
return new FavouriteNewsHolder(view);
}
#Override
public void onBindViewHolder(#NonNull FavouriteListAdapter.FavouriteNewsHolder holder, int
position) {
final News news = newsList.get(position);
holder.theme.setText(news.getTheme());
}
#Override
public int getItemCount() {
return newsList.size();
}
public class FavouriteNewsHolder extends RecyclerView.ViewHolder {
TextView theme;
ImageButton like;
public FavouriteNewsHolder(#NonNull View itemView) {
super(itemView);
theme = itemView.findViewById(R.id.theme);
like = itemView.findViewById(R.id.like);
}
}
in Activity I overwrite my method. When I execute my programm and click button click the program stopping
#Override
public void respond(News news) {
FavouriteFragment f = (FavouriteFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
f.addNews(news);
}
In logcat:
2020-03-24 21:55:12.367 13933-13933/com.example.newsfragment E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.newsfragment, PID: 13933
java.lang.ClassCastException: com.example.newsfragment.HomeFragment cannot be cast to com.example.newsfragment.FavouriteFragment
at com.example.newsfragment.MainActivity.respond(MainActivity.java:50)
at com.example.newsfragment.HomeFragment$2.respond(HomeFragment.java:51)
at com.example.newsfragment.HomeFragment$1.likeClick(HomeFragment.java:43)
at com.example.newsfragment.NewsListAdapter$1.onClick(NewsListAdapter.java:61)
at android.view.View.performClick(View.java:7125)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3500(View.java:801)
at android.view.View$PerformClick.run(View.java:27336)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
The 50 line in MainActivity
public void respond(News news) {
FavouriteFragment f = (FavouriteFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
f.addNews(news);
}
Use the eventBus for this type of communication with a fragment. Using https://github.com/greenrobot/EventBus this lib I have implemented the same things(When like a post in homeFragment at that time I want to like that post in multiple fragments)
Register and unregister EventBus
#Override public void onStart() {
super.onStart();
EventBus.getDefault().register(this); }
#Override public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this); }
Post events:
EventBus.getDefault().post(new MessageEvent());
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. Values are lost when recycler is scrolled down.I would like to have values greater than 7. Values come up when first opened but When I go down the scroll bar, it returns to its original state.
FragmentB.java
public class FragmentB extends Fragment{
View view ;
TextView textView;
RecyclerView recyclerView ;
ArrayList<OnemliDepremler> onemliDepremler;
BuyukRecyclerAdapter buyukRecyclerAdapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_sabit,container,false);
// textView=view.findViewById(R.id.textView3);
recyclerView = view.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager=new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.scrollToPosition(0);
recyclerView.setLayoutManager(layoutManager);
onemliDepremler=new ArrayList<OnemliDepremler>();
Factory.getInstance().buyukDepremModel().enqueue(new Callback<OnemliDepremModel>() {
#Override
public void onResponse(Call<OnemliDepremModel> call, Response<OnemliDepremModel> response) {
buyukRecyclerAdapter=new BuyukRecyclerAdapter(response.body().data.subList(0, 10));
recyclerView.setAdapter(buyukRecyclerAdapter);
}
#Override
public void onFailure(Call<OnemliDepremModel> call, Throwable t) {
}
});
return view;
}
}
BuyukRecyclerAdapter.java
public class BuyukRecyclerAdapter extends RecyclerView.Adapter<BuyukRecyclerAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView buyukluk;
public TextView yer;
public TextView tarih;
public CardView cardView ;
FrameLayout frameLayout;
public ViewHolder(View itemView) {
super(itemView);
cardView = itemView.findViewById(R.id.card_view);
buyukluk=itemView.findViewById(R.id.text_buyukluk);
yer=itemView.findViewById(R.id.text_yer);
tarih=itemView.findViewById(R.id.text_tarih);
frameLayout=itemView.findViewById(R.id.frame_layout);
}
}
List<Datum> onemliDepremler;
public BuyukRecyclerAdapter(List<Datum> onemliDepremler) {
this.onemliDepremler = onemliDepremler;
}
#Override
public BuyukRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.onemli_custom,parent,false);
final ViewHolder view_holder=new ViewHolder(v);
return view_holder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.buyukluk.setText(onemliDepremler.get(position).siddeti);
holder.tarih.setText("Tarih :"+onemliDepremler.get(position).tarih);
holder.yer.setText(onemliDepremler.get(position).lokasyon);
if(Float.parseFloat(onemliDepremler.get(position).siddeti)>7){
holder.frameLayout.setBackgroundColor(Color.RED);
}
}
#Override
public int getItemCount() {
return onemliDepremler.size();
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
}
Your advice important for me
Thank you very much !
if(Float.parseFloat(onemliDepremler.get(position).siddeti)>7){
holder.frameLayout.setBackgroundColor(Color.RED);
}else{
holder.frameLayout.setBackgroundColor(Color.YELLOW);
}
Try this.
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.