Reference recyclerView elements from fragment - android

Good afternoon!
I have a fragment containing a recyclerView which holds bookmarked elements. The element layout has a star icon to delete the chosen item from SQLite database. When the icon is clicked, i need to set its tint to white then the position of that item needs to be saved in a list declared in my fragment. I am wondering how to do that.
Since we use adapters to bind elements I couldn't reference the icon from fragment to change the tint. Note that, It shouldn't refresh the page. After user presses back, It will save changes in db
Fragment
public class BookMarksFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener, View.OnClickListener {
private BookMarksAdapter listAdapter;
private List<BookmarksModel> bookmarks = new ArrayList<>();
private FragmentBookmarksBinding binding;
private DBHelper dbHelper;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Functions.setLanguages(App.getCurrentActivity());
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_bookmarks, container, false);
binding.refresher.setColorSchemeResources(R.color.drawer_background);
binding.refresher.setOnRefreshListener(this);
binding.refresher
.post(new Runnable() {
#Override
public void run() {
binding.refresher.setRefreshing(true);
setRefreshingState(true);
}
}
);
listAdapter = new BookMarksAdapter(getActivity(), bookmarks, this);
binding.bookmarkList.setLayoutManager(new LinearLayoutManager(getActivity()));
binding.bookmarkList.setAdapter(listAdapter);
listAdapter.notifyDataSetChanged();
return binding.getRoot();
}
private void setRefreshingState(final boolean b) {
binding.refresher.post(new Runnable() {
#Override
public void run() {
binding.refresher.setRefreshing(b);
getNews();
}
});
}
private void getNews() {
dbHelper = new DBHelper(getActivity(), "kunuz", null, 1);
bookmarks.clear();
bookmarks.addAll(dbHelper.getBookmarks());
if(bookmarks.size()==0){
binding.bookmarkList.setVisibility(View.GONE);
binding.emptyView.setVisibility(View.VISIBLE);
}else{
binding.emptyView.setVisibility(View.GONE);
binding.bookmarkList.setVisibility(View.VISIBLE);
}
binding.refresher.setRefreshing(false);
listAdapter.notifyDataSetChanged();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case Constants.BOOKMARK_REQUEST_CODE:
if (resultCode == Constants.BOOKMARK_RESULT_CODE) {
binding.refresher
.post(new Runnable() {
#Override
public void run() {
binding.refresher.setRefreshing(true);
setRefreshingState(true);
}
}
);
}
break;
}
}
#Override
public void onRefresh() {
getNews();
}
#Override
public void onClick(View v) {
if (v.getId()==R.id.star){
dbHelper.deleteFavorites(v.getTag().toString());
onRefresh();
}else if(v.getId()==R.id.bookmark_card_view){
Intent intent = new Intent(App.getInstance(), NewsViewActivity.class);
intent.putExtra(Constants.NEWS_CODE, v.getTag().toString());
getActivity().startActivity(intent);
}
}
}
Adapter
public class BookMarksAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<BookmarksModel> data;
private LayoutInflater inflater;
private View.OnClickListener listener;
public BookMarksAdapter(Context context, List<BookmarksModel> data, View.OnClickListener listener) {
this.context = context;
this.data = data;
this.listener = listener;
this.inflater = LayoutInflater.from(context);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
BookmarksItemBinding binding
= DataBindingUtil.inflate(inflater, R.layout.bookmarks_item, parent, false);
return new BookmarksHolder(binding.getRoot());
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final BookmarksModel item = data.get(position);
((BookmarksHolder)holder).binding.setNewsItem(item);
((BookmarksHolder)holder).binding.categoryIcon.setImageResource(Utils.getCategoryColorByName(item.getCategory()));
if (item.getImage_url() != null && !item.getImage_url().isEmpty()) { // TODO get image from cache
ImageLoader.getInstance()
.displayImage(item.getImage_url(), ((BookmarksHolder)holder).binding.newsImageView);
} else {
((BookmarksHolder)holder).binding.
newsImageView.setImageResource(R.drawable.kun_uz_logo_no_image);
}
((BookmarksHolder)holder).binding.star.setTag(item.getCode());
((BookmarksHolder)holder).binding.star.setOnClickListener(listener);
((BookmarksHolder)holder).binding.bookmarkCardView.setTag(item.getCode());
((BookmarksHolder)holder).binding.bookmarkCardView.setOnClickListener(listener);
}
#Override
public int getItemCount() {
return data.size();
}
public class BookmarksHolder extends RecyclerView.ViewHolder {
BookmarksItemBinding binding;
BookmarksHolder(View root) {
super(root);
binding = DataBindingUtil.bind(root);
}
}
}

OnClick listener on star icon sends clicked adapterPosition back to Fragment.
Fragment stores the change in database, updates list in the adapter.
Fragment calls adapters notifyItemChanged(position).
Adapters onBindViewHolder re-reads item on this position and sets star color appropriately.

You need to have some flag in BookmarksModel class to know whether the bookmarks is active(in db)/inactive(not in db) as in your case.
public BookmarksModel{
....
....
public isSaved;
}
Now in you onBindViewHolder method.
final BookmarksModel item = data.get(position);
((BookmarksHolder)holder).binding.setNewsItem(item);
.....
.....
if(item.isSaved){
((BookmarksHolder)holder).star.setAlpha(1f); //set your tint value
}else{
((BookmarksHolder)holder).star.setAlpha(0.5ff); //set your tint value
}
((BookmarksHolder)holder).binding.star.setTag(position); // just set the position
((BookmarksHolder)holder).binding.star.setOnClickListener(listener);
((BookmarksHolder)holder).binding.bookmarkCardView.setTag(position);
((BookmarksHolder)holder).binding.bookmarkCardView.setOnClickListener(listener);
In your fragment onClick()
public void onClick(View v) {
if (v.getId()==R.id.star){
int pos = (Integer)v.getTag();
BookmarksModel model = listAdapter.getList(pos); //create a getter in your
if(!model.isSaved) //toggled to saved bookmark
///////////////// your code to save bookmark
else
dbHelper.deleteFavorites(v.getTag().toString()); ///// your code for deleting bookmark
model.isSaved = !model.isSaved;
listAdapter.notifyItemChanged(pos); // refreshes your recyclerView item
}
}
Hope this helps.

Related

Recyclerview not refreshing after removing an item

My Recycler view is not updating after an item is removed.
This recyclerView is inside a fragment.
I have tried every method and nothing works.
Adapter declaration in fragment class
notificationsTabAdapter = new NotificationsTabAdapter(getContext(), R.id.notificationsRecyclerView,
notificationItemsList, cListner);
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(notificationsTabAdapter);
RecyclerViewAdapter:
public class NotificationsTabAdapter extends RecyclerView.Adapter<NotificationsTabAdapter.NotificationItemHolder> {
Boolean debug = false;
public static final String NOTIFICATION_ADAPTER = "NotificationAdapter";
private ArrayList<NotificationItemm> notificationItems;
private int layoutResID;
private int notificationposition;
private Context myContext;
public onNotificationItemClickListner mListner;
public interface onNotificationItemClickListner {
void onNotificationItemDelete(int position);
}
public NotificationsTabAdapter(Context context, int resource, ArrayList<NotificationItemm> notificationList,
onNotificationItemClickListner listner) {
myContext = context;
layoutResID = resource;
notificationItems = notificationList;
notificationposition = 0;
this.mListner = listner;
}
#NonNull
#Override
public NotificationItemHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.notifications_tab_item, viewGroup, false);
NotificationsTabAdapter.NotificationItemHolder evh = new NotificationsTabAdapter.NotificationItemHolder(view, mListner);
return evh;
}
#Override
public void onBindViewHolder(#NonNull final NotificationItemHolder notificationItemHolder, final int position) {
final NotificationItemm currentItem = notificationItems.get(position);
notificationItemHolder.mNotificationTextView.setText(currentItem.getNotification_name());
notificationItemHolder.mNotificationURL = currentItem.getNotification_link();
notificationItemHolder.mNotificationDate = currentItem.getNotification_date();
notificationItemHolder.mNotificationRT = currentItem.getNotification_rT();
notificationItemHolder.mNotificaionHolderLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
//to delete the notification
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deleteNotification(currentItem);
mListner.onNotificationItemDelete(position);
}
});
}
#Override
public int getItemCount() {
return notificationItems.size();
}
//Delete from View
public void deleteNotification(NotificationItemm todelete) {
int notificationPosition = notificationItems.indexOf(todelete);
notificationItems.remove(notificationPosition);
notifyItemRemoved(notificationPosition);
notifyItemChanged(notificationPosition);
notifyDataSetChanged();
notifyItemRemoved(notificationPosition);
notifyItemChanged(notificationPosition);
if (notificationItems.isEmpty()) {
}
}
/**
* VIEW HOLDER =================================================================================
**/
public class NotificationItemHolder extends RecyclerView.ViewHolder {
RelativeLayout mNotificaionHolderLayout;
RelativeLayout notificationParentRelative;
ImageView imageDelete;
TextView mNotificationTextView;
String mNotificationURL;
String mNotificationDate;
String mNotificationRT;
public NotificationItemHolder(#NonNull View itemView, onNotificationItemClickListner listner) {
super(itemView);
mNotificationTextView = itemView.findViewById(R.id.NotificationTextView);
mNotificaionHolderLayout = itemView.findViewById(R.id.notification__item_container);
imageDelete = itemView.findViewById(R.id.notification_delete_image);
notificationParentRelative = itemView.findViewById(R.id.rlNotificLayout);
mNotificationRT = null;
mNotificationURL = null;
mNotificationDate = null;
}
}
}
When I debug the project, I can see that the item is actually removing from the ArrayList.But not updating in recycled view.
After deletion, if the recyclerview is scrolled, the deleted item is removed from the recyclerview.But not without scrolling.
Try this.Hope will work for you.
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
notificationItems.remove(position);
notifyDataSetChanged();
}
In your NotificationsTabAdapter make the following changes
NotificationsTabAdapterListener notificationsTabAdapterListener;
public interface NotificationsTabAdapterListener { // create an interface
void onItemsDeleted(int position); // create callback function
}
public NotificationsTabAdapter(Context context, int resource, ArrayList<NotificationItemm> notificationList,
NotificationsTabAdapterListener notificationsTabAdapterListener) {
myContext = context;
layoutResID = resource;
notificationItems = notificationList;
notificationposition = 0;
this.notificationsTabAdapterListener = notificationsTabAdapterListener;
}
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//perform normal remove operation here
notificationItems.remove(position);
notificationsTabAdapterListener.onItemsDeleted(position);
}
});
And Implement NotificationsTabAdapterListener in you fragment and in override method use the following code
#Override
public void onItemsDeleted(final int position) {
notificationsTabAdapter.notifyDataSetChanged();
recyclerView.post(new Runnable() {
#Override
public void run() {
recyclerView.smoothScrollToPosition(position);
}
});
}
Try this to your delete functionality
public void deleteNotification(NotificationItemm todelete) {
notificationItems.remove(todelete);
notifyDataSetChanged();
}
As workaround you can call a method in the FragmentClass, which loads the new list (with item removed) in your adapter. Call this method from your Adapter
public void MethodInFragmentClass(NotificationItemm todelete)
{
/*
... delete item
*/
notificationsTabAdapter = new NotificationsTabAdapter(getContext(), R.id.notificationsRecyclerView,
notificationDeletedItemsList, cListner);
recyclerView.setAdapter(notificationsTabAdapter);
}
Use a callback like this in your adapter :
private ICallback mICallback;
public interface ICallback {
void deleteItem(int position);
}
public SettingRecyclerViewAdapter(SettingMediator settingMediator, ICallback ICallback) {
mICallback = ICallback;
mSettingMediator = settingMediator;
}
And in your faragment notifydatasetchange and update recyclerview like this :
public class YourFragment implements SettingContract.View, SettingRecyclerViewAdapter.ICallback {
.
.
.
#Override
public void deleteItem(int position) {
//delete item from your list here
mSettingRecyclerViewAdapter = new SettingRecyclerViewAdapter(yourList, this);
mRecyclerView.setAdapter(mSettingRecyclerViewAdapter);
mSettingRecyclerViewAdapter.notifyDataSetChanged();
}
}
Try this:
notificationItemHolder.imageDelete.setTag(holder);
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
NotificationItemHolder viewholder = (NotificationItemHolder) v.getTag();
notificationItems.remove(viewholder.getAdapterPosition());
notifyDataSetChanged();
}
});
You have to parse the position which is getting from onclick listener in Adapter class to Interface method(onitemClicked())
Then, Implement the interface class to Fragment class and will remove the position which we have on Interface method using [ listname.remove(position)) ]
Eventually, update recyclerview UI using adaptername.notifyDataSetChanged();
Step 1 :create interface class
public interface RecyclerviewItemClickListener {
void onitemClicked(View v, int position);
}
Step 2: pass position to the interface method in adapter class
notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deleteNotification(currentItem);
//use interface method & pass the position of the list to fragment for update UI .
recyclerviewItemClickListener.onitemClicked(v,position);
}
});
step 3 : implement the interface class & method in fragment
#Override
public void onitemClicked(View v, int position) {
Listname.remove(Listname.get(position));
RecyclerviewAdaptername.notifyDataSetChanged();
}

How to get RecyclerView's Clicked data Position to View Pager Swipe?

I'm using Viewpager for slider and initially Recyclerview... When I load image from Server to recycler it's done... Now what i want to do that when ever someone click on particular item, it should be opened in second activity in which ViewPager I use.. example: When I click first Image, it should open that image in viewPager(slider).... And Also when someone swipe on ViewPager's activity it should load more images....
Code is Below and don't know what to do next. Please Help me.
RecyclerView
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.myViewHolder> {
ArrayList<model> mdata;
Context context;
public RecyclerViewAdapter(){ }
public RecyclerViewAdapter(ArrayList<model> mdata, Context context) {
this.mdata = mdata;
this.context = context;
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
View view = inflater.inflate(R.layout.item,viewGroup,false);
return new myViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final myViewHolder holder, int i) {
Picasso.get().load(mdata.get(holder.getAdapterPosition()).getWallpaper()).into(holder.wallpaper);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context,SecondActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("wallpaperUrl",mdata.get(holder.getAdapterPosition()).getWallpaper());
context.startActivity(i);
}
});
}
#Override
public int getItemCount() {
return mdata.size();
}
public class myViewHolder extends RecyclerView.ViewHolder{
ImageView wallpaper;
Button set;
public myViewHolder(#NonNull View itemView) {
super(itemView);
wallpaper = itemView.findViewById(R.id.wallpaper);
set = itemView.findViewById(R.id.set);
}
}
Second Activity which have ViewPager:
public class SecondActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
btn = findViewById(R.id.setWallpaper);
mdata = new ArrayList<model>();
viewPager = findViewById(R.id.viewPager);
Intent intent = getIntent();
Integer[] colors_temp ={getResources().getColor(R.color.color1),
getResources().getColor(R.color.color2),
getResources().getColor(R.color.color3),
getResources().getColor(R.color.color4),
} ;
colors = colors_temp;
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffSet, int pixels) {
if (position < adapter.getCount() -1 && position <(colors.length) -1){
viewPager.setBackgroundColor(
(Integer) argbEvaluator.evaluate
(positionOffSet,
colors[position],
colors[position + 1]));
}else{
viewPager.setBackgroundColor(colors[colors.length - 1]);
}
}
#Override
public void onPageSelected(final int i) {
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DownloadImage downloadImage = new DownloadImage();
Bitmap bitmap = null;
try{
bitmap =
downloadImage.execute(mdata.get(i).getWallpaper()).get();
}catch (Exception e){
e.printStackTrace();
Toast.makeText(SecondActivity.this, "Something went
Wrong! ", Toast.LENGTH_SHORT).show();
}
}
});
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
mDatabase = FirebaseDatabase.getInstance();
mReference = mDatabase.getReference().child("wallpapers");
mReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1:dataSnapshot.getChildren()){
model data = dataSnapshot1.getValue(model.class);
mdata.add(data);
}
adapter = new Adapter(mdata,getApplicationContext());
viewPager.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(SecondActivity.this, "Failed! "+databaseError,
Toast.LENGTH_SHORT).show();
}
});
}
MyAdapter:
public class Adapter extends PagerAdapter {
ArrayList<model> mdata;
Context context;
LayoutInflater inflater;
public Adapter(){
}
public Adapter(ArrayList<model> mdata, Context context) {
this.mdata = mdata;
this.context = context;
}
#Override
public int getCount() {
return mdata.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object o) {
return view.equals(o);
}
#NonNull
#Override
public Object instantiateItem(#NonNull final ViewGroup container, final int position) {
inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.pager_item,container,false);
ImageView wallpaper;
Button btn;
wallpaper = view.findViewById(R.id.wallpaperImage);
Picasso.get().load(mdata.get(position).getWallpaper()).into(wallpaper);
container.addView(view,0);
return view;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((View)object);
}
If you are loading the images from the server, and each image has an id, pass the id into then intent. When you open up the view that needs the image that was clicked, make a service call to retrieve the image from the server using it's id.
In your enter code here, add setOnclickListener to holser.iytemView, then create an intent for navigating to the second activity, and add this code in onBindViewHolder:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: LoadingProfileActivity");
Intent intent = new Intent(getContext(), SecondActivity.class);
/*
Extras
*/
mainActivityContext.startActivity(intent);
}
});
If you want to send the image or id that contained in this row add intent.putExtra() after the intent is created.
Like if I want to display the image in second activity ill put in
Intent intent = new Intent(getContext(), SecondActivity.class);
intent.putExtra("image_url", imageResource);
In SecondActivity firsts get the imageresource from the intent
String imageResouce = getIntent.getStringExtra("image_url");
Then display the image in image view

Adding item to a recyclerview from dialog within a fragment class.?

I have a fragment which must contains two recycler views. The view looks like follows. i need to add an item to the bottom recyclerview from a dialog. L'll post my code for the adapter class and xml. Please guide me to achieve this, a sample or a code is more than welcome.
I've tried to pass the data from the dialog to the second recyclerview but it does not show the added item. Tell me anything i'm doing wrong here. Nothing i tried worked out to update my second recyclerview... :/
My Fragment Class
public class ReceiptFragment extends Fragment { //implements ContReceiptsAdapter.ItemOnClickListener
RecyclerView rv_rceipts, rv_addpayments;
RecyclerView.Adapter mContReceiptsAdapter,mAddPaymentsAdapter;
RecyclerView.LayoutManager mLayoutManager1,mLayoutManager2;
View receipts_view;
private Context mContext;
ContReceiptsAdapter contReceiptsAdapter;
AddPaymentsAdapter addPaymentsAdapter;
//-- items in detailed dialog here
private ArrayList<Contract> contracts;
private ArrayList<AddPayments> payments;
private View linearLayout;
public View mRootView;
public ReceiptFragment() {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
receipts_view = inflater.inflate(R.layout.fragment_receipt, container, false);
BuildReceiptsRV();
BuildAddedPaymentsRV();
// for setting the first item as default in the list
// onItemClicked(0);
return receipts_view;
}
private void BuildReceiptsRV() {
rv_rceipts = receipts_view.findViewById(R.id.rv_tobe_added);
rv_rceipts.setHasFixedSize(true);
rv_rceipts.setItemAnimator(new DefaultItemAnimator());
mLayoutManager1 = new LinearLayoutManager(getActivity());
rv_rceipts.setLayoutManager(mLayoutManager1);
mContReceiptsAdapter = new ContReceiptsAdapter(getActivity(), ApplicationClass.contractList);
rv_rceipts.setAdapter(mContReceiptsAdapter);
}
private void BuildAddedPaymentsRV() {
rv_addpayments = receipts_view.findViewById(R.id.rv_added);
rv_addpayments.setHasFixedSize(true);
rv_addpayments.setItemAnimator(new DefaultItemAnimator());
mLayoutManager2 = new LinearLayoutManager(getActivity());
rv_addpayments.setLayoutManager(mLayoutManager2);
mAddPaymentsAdapter = new AddPaymentsAdapter(getActivity(),ApplicationClass.paymentList);
rv_addpayments.setAdapter(mAddPaymentsAdapter);
}
//change when click on change on item added to second rv
private void changeLayoutRV() {
linearLayout = mRootView.findViewById(R.id.rv_tobe_added);
if (linearLayout.getVisibility() == View.GONE) {
linearLayout.setVisibility(View.VISIBLE);
} else {
linearLayout.setVisibility(View.GONE);
}
}
}
My Adapter for the First Recyclerview
public class ContReceiptsAdapter extends RecyclerView.Adapter<ContReceiptsAdapter.ReceiptsViewHolder> {
// private static Dialog AddItemDialog;
private ArrayList<Contract> contracts;
private ArrayList<AddPayments> payments = new ArrayList<>();
Context mContext;
String inPending;
//for the details dialog
EditText et_number, contract_id_val, product_type_val, mobile_number_ADialog, et_amount_add;
// ImageView btn_add_item;
//--to set to add item dialog
public TextView contract_number, vehicle_number, contract_number_ADialog, vehicle_number_ADialog;
CheckBox checkbox_pending;
public ContReceiptsAdapter(Context context, ArrayList<Contract> contractList) {
contracts = contractList;
mContext = context;
}
public class ReceiptsViewHolder extends RecyclerView.ViewHolder {
TextView tv_contract, tvVehicleN, tvContractType;
ImageView btn_add_item;
LinearLayout detailsLayout;
public ReceiptsViewHolder(#NonNull final View itemView) {
super(itemView);
detailsLayout = itemView.findViewById(R.id.add_details_item_id);
tv_contract = itemView.findViewById(R.id.tv_contract);
tvVehicleN = itemView.findViewById(R.id.tvVehicleN);
tvContractType = itemView.findViewById(R.id.tvContractType);
btn_add_item = itemView.findViewById(R.id.btn_add_item);
}
}
#NonNull
#Override
public ContReceiptsAdapter.ReceiptsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.receipt_tobe_added_rv_item, viewGroup, false);
final ReceiptsViewHolder receiptsViewHolder = new ReceiptsViewHolder(view);
//dialog ini
// ShowDetails();
final Dialog detailedDialog = new Dialog(this.mContext);
detailedDialog.setContentView(R.layout.fragment_details);
receiptsViewHolder.detailsLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//click view dto show the detaileds view of the list item
contract_number = detailedDialog.findViewById(R.id.contract_id_val);
vehicle_number = detailedDialog.findViewById(R.id.vehicle_num_val);
contract_number.setText(contracts.get(receiptsViewHolder.getAdapterPosition()).getContractNumber());
vehicle_number.setText(contracts.get(receiptsViewHolder.getAdapterPosition()).getVehicleNumber());
detailedDialog.show();
detailedDialog.setCancelable(true);
// mListener.onItemClicked(contracts.indexOf(v.getTag()));
}
});
return receiptsViewHolder;
}
#Override
public void onBindViewHolder(#NonNull final ContReceiptsAdapter.ReceiptsViewHolder viewHolder, int i) {
viewHolder.itemView.setTag(contracts.get(i));
// Contract currentItem = contracts.get(i);
viewHolder.tv_contract.setText(contracts.get(i).getContractNumber());
viewHolder.tvVehicleN.setText(contracts.get(i).getVehicleNumber());
viewHolder.tvContractType.setText(contracts.get(i).getContractType());
final Dialog AddItemDialog = new Dialog(mContext);
AddItemDialog.setContentView(R.layout.fragment_add_receipt);
viewHolder.btn_add_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// ShowDetails();7
contract_number_ADialog = AddItemDialog.findViewById(R.id.contract_id_val_add);
contract_number_ADialog.setText(contracts.get(viewHolder.getAdapterPosition()).getContractNumber());
vehicle_number_ADialog = AddItemDialog.findViewById(R.id.product_type_val_add);
vehicle_number_ADialog.setText(contracts.get(viewHolder.getAdapterPosition()).getVehicleNumber());
mobile_number_ADialog = AddItemDialog.findViewById(R.id.et_number_add);
mobile_number_ADialog.setText(contracts.get(viewHolder.getAdapterPosition()).getMobileNumber());
checkbox_pending = AddItemDialog.findViewById(R.id.checkbox_pending_add);
checkbox_pending.setChecked(Boolean.parseBoolean(contracts.get(viewHolder.getAdapterPosition()).getPendingState()));
Button btn_cancel_receipt = AddItemDialog.findViewById(R.id.btn_cancel_receipt);
Button btn_add_receipt = AddItemDialog.findViewById(R.id.btn_add_receipt);
et_amount_add = AddItemDialog.findViewById(R.id.et_amount_add);
AddItemDialog.show();
AddItemDialog.setCancelable(true);
btn_cancel_receipt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AddItemDialog.dismiss();
}
});
btn_add_receipt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AddData();
//add item to rv2
AddItemDialog.dismiss();
}
});
}
});
}
#Override
public int getItemCount() {
return contracts.size();
}
private void addAnItem(AddPayments payment) {
payments = ApplicationClass.paymentList;
payments.add(payment);
this.notifyDataSetChanged();
}
private void AddData() {
String c_code = contract_number_ADialog.getText().toString();
String c_mobile = mobile_number_ADialog.getText().toString();
String c_amount = et_amount_add.getText().toString();
AddPayments added_payment = new AddPayments(c_amount, c_code, c_mobile, "true");
payments.add(added_payment);
notifyDataSetChanged();
}
}
My Adapter class for the Second Recyclerview
public class AddPaymentsAdapter extends RecyclerView.Adapter<AddPaymentsAdapter.AddPayViewHolder> {
private ArrayList<AddPayments> payments;
Context mContext;
public AddPaymentsAdapter(Context context, ArrayList<AddPayments> addPayments) {
mContext = context ;
payments = addPayments;
}
public class AddPayViewHolder extends RecyclerView.ViewHolder{
TextView tv_contract_d, tv_amount_d, tv_isPending_d, tv_mobile_num_d;
ImageView btn_delete_item;
ConstraintLayout addedPaymentLayout;
public AddPayViewHolder(#NonNull View itemView) {
super(itemView);
addedPaymentLayout = itemView.findViewById(R.id.added_payment_item_id);
tv_contract_d = itemView.findViewById(R.id.tv_contract_d);
tv_amount_d = itemView.findViewById(R.id.tv_amount_d);
tv_isPending_d = itemView.findViewById(R.id.tv_isPending_d);
tv_mobile_num_d = itemView.findViewById(R.id.tv_mobile_num_d);
btn_delete_item = itemView.findViewById(R.id.btn_delete_item);
}
}
#NonNull
#Override
public AddPaymentsAdapter.AddPayViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.receipt_added_rv_item, viewGroup, false);
final AddPayViewHolder addPayViewHolder= new AddPayViewHolder(view);
return addPayViewHolder;
}
#Override
public void onBindViewHolder(#NonNull AddPaymentsAdapter.AddPayViewHolder addPayViewHolder, final int i) {
AddPayments currentItem = payments.get(i);
addPayViewHolder.itemView.setTag(payments.get(i));
addPayViewHolder.tv_contract_d.setText(payments.get(i).getAddContractCode());
addPayViewHolder.tv_isPending_d.setText(payments.get(i).getAddIsPending());
addPayViewHolder.tv_amount_d.setText(payments.get(i).getAddAmount());
addPayViewHolder.tv_mobile_num_d.setText(payments.get(i).getAddMobile());
addPayViewHolder.btn_delete_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//delete function
// Toast.makeText(mContext, "clicked delete icon inHoldernAdapter", Toast.LENGTH_SHORT).show();
removeItem(i);
}
});
}
#Override
public int getItemCount() {
return payments.size();
}
private void removeItem(int i) {
payments.remove(i);
this.notifyItemRemoved(i);
}
}
From your code in the adapter for the first recycler view you are using this method AddData(); to add data. But this method adds data to payments which is the list where you hold the data which you want to show in the second recycler view but have no connection to it(it's just a field of the adapter class).
The this.notifyDataSetChanged() notifies the current adapter for a change in data(first recycler view). You will need to add this data to the second recycler view adapter thou. You aren't doing that right now.
So a way would be to create a method inside of the fragment which takes a list of AddPayments as argument and add this data to the second recycler view adapater. It would be something like this:
Fragment method:
public void addSecondRVData(AddPayments itemToAdd) {
mAddPaymentsAdapter.addNewPayment(itemToAdd);
}
Second recycler view method:
public void addData(AddPayments itemToAdd) {
payments.add(itemToAdd);
this.notifyDataSetChanged():
}
Dont forget to initialize the payment list in the second recycler view.
Then in the first adapter do smth like this:
private ReceiptFragment receiptFragment;
//Constructor
public ContReceiptsAdapter(Context context, ArrayList<Contract> contractList, ReceiptFragment receiptFragment) {
contracts = contractList;
mContext = context;
this.receiptFragment = receiptFragment;
}
//Use this to add elements to second rv
receiptFragment.addSecondRVData(newItem);
Hope this helps although is not the cleanest solution. Check the example I wrote here because can't test it at the moment.

how to call startActivity in RecyclerView Adapter (DataBinding)

My RecyclerView(rvPredictionIndex) item includes ImageView, EditText and Button, when Button is clicked the Text inside EditText will be uploaded on server and when ImageView is clicked, the New Activity will be called and the position of that Item will be passed to new activity using Intent().
I am using DataBinding so View() is not used here (or any other way of using View() than i don't know).
Here is RecyclerView Adapter code....
public class PredictionItemAdapter extends RecyclerView.Adapter<PredictionItemAdapter.MyViewHolder> {
private List<PredictionItems> mPredictionItemsList;
private Context mContext;
private int predictionId;
private String etAnswer;
public class MyViewHolder extends RecyclerView.ViewHolder {
// ImageView ivPredictionImage;
// CustomTextView txtPredictionQuestion;
PredictionItemBinding predictionItemBinding;
public MyViewHolder(PredictionItemBinding predictionItemBinding) {
super(predictionItemBinding.getRoot());
this.predictionItemBinding = predictionItemBinding;
// ivPredictionImage = (ImageView) itemView.findViewById(R.id.ivPredictionImage);
// txtPredictionQuestion = (CustomTextView) itemView.findViewById(R.id.txtPredictionQuestion);
}
}
public PredictionItemAdapter(Context context, List<PredictionItems> mPredictionItemsList) {
this.mPredictionItemsList = mPredictionItemsList;
this.mContext = context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.prediction_item, parent, false);
// return new MyViewHolder(view);
PredictionItemBinding predictionItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()),
R.layout.prediction_item, parent, false);
return new MyViewHolder(predictionItemBinding);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
// PredictionItems predictionItems = mPredictionItemsList.get(position);
// Picasso.with(mContext).load(predictionItems.getImage()).into(holder.ivPredictionImage);
// holder.txtPredictionQuestion.setText(predictionItems.getQuestion());
final PredictionItems predictionItems = mPredictionItemsList.get(position);
PredictionViewModel predictionViewModel = new PredictionViewModel(predictionItems);
predictionViewModel.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
#Override
public void onPropertyChanged(Observable sender, int propertyId) {
if (propertyId == 1) {
etAnswer = holder.predictionItemBinding.editText.getText().toString();
predictionId = mPredictionItemsList.get(position).getId();
if (etAnswer.equals("")) {
Utility.showToastShort(mContext, "Please input answer");
} else {
callUpdatePredictionAnswerApi(predictionId, etAnswer);
// Toast.makeText(mContext, "submjit of " + holder.getAdapterPosition), Toast.LENGTH_SHORT).show();
}
}
else if (propertyId == 2){
//Here i want to start activity and pass data with intent
}
}
});
holder.predictionItemBinding.setPredictionVM(predictionViewModel);
}
#Override
public int getItemCount() {
return mPredictionItemsList.size();
}
}
I have already opened new activity on ItemClick of recyclerView but when i tried to click the EditText for input something, it will redirect me to the new activity, so that's why i want to start new activity on ImageView click..
here is my RecyclerViewItem Click...
private void rvPredictionIndexClick() {
rvPredictionIndex.addOnItemTouchListener(new RecyclerTouchListener(mContext, rvPredictionIndex, new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, int position) {
String preId = mPredictionItemsList.get(position).getId().toString();
Intent i = new Intent(mContext, PredictionInfoActivity.class);
String posi = ((String.valueOf(position)));
i.putExtra("predictionId", posi);
startActivity(i);
}
#Override
public void onLongClick(View view, int position) {
}
}));
}
Create Class DataBindingAdapter
and paste
#BindingAdapter("android:onClick")
public static void setOnClickListener(View view, final Runnable runnable) {
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
runnable.run();
}
});
}
than go to your ViewModel class
and paste
public void onSubmitClicked() {
Log.e("onButtonSubmit", "onButtonSubmit");
notifyPropertyChanged(1);
}
public void onImageClicked() {
Log.e("onImageClicked", "onImageClicked");
notifyPropertyChanged(2);
}
than go to your item.xml file and call
android:onClick="#{predictionVM::onSubmitClicked}"
in your Button,
and
android:onClick="#{predictionVM.onImageClicked}
in your imaggView,
than go to your ItemAdapterClass
and inside onCreateViewHolder
predictionViewModel.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
#Override
public void onPropertyChanged(Observable sender, int propertyId) {
if (propertyId == 1) {
//do your stuff
}
else if (propertyId == 2) {
// do your stuff
}
The most elegant and frankly adequate solution would be not to do anything inside adapter!
I wrote an article about adapters, have a look RecyclerView Adapters
Straightforward: add a callback to your adapter and perform everything inside calling sight (fragment etc)

how to make the header of Recycle view invisible

I have a Recyclerview with header view as slider images and remaining view as normal recycler items.I am wondering if there is any way around to make the header view invisible depending upon some sort of condition.The recycler view consists of two separate layout files for this purpose: layout1 for header items and layout2 for normal recycler items and adapter will pick a layout and binds corresponding data at runtime.
This is my RecyclerView adapter RestaurantAdapter.java
public class RestaurantAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String TAG = RestaurantAdapter.class.getName();
private List<Restaurant> mList;
private Context mContext;
private RestaurantType mRestaurantType;
private static final int RECYCLER_HEADER=0,RECYCLER_ITEMS=1;
private LayoutInflater inflater;
private SlideItemViewHolder slideItemViewHolder;
private List<ImageSliderPOJO> mData;
public RestaurantAdapter(Context context, List<Restaurant> list, RestaurantType restaurantType) {
this.mContext = context;
this.mList = list;
this.mRestaurantType = restaurantType;
inflater=LayoutInflater.from(context);
}
public void updateAdapter(List<ImageSliderPOJO> data){
this.mData = data;
this.notifyDataSetChanged();
}
#Override
public int getItemCount() {
return mList.size();
}
#Override
public int getItemViewType(int position) {
return position == 0 ? RECYCLER_HEADER : RECYCLER_ITEMS;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int i) {
int viewType=viewHolder.getItemViewType();
switch (viewType){
case RECYCLER_HEADER:
slideItemViewHolder = (SlideItemViewHolder) viewHolder;
slideItemViewHolder.updateHeader();
break;
case RECYCLER_ITEMS:
final RecyclerItemViewHolder holder = (RecyclerItemViewHolder) viewHolder;
final Restaurant restaurant = mList.get(i);
Picasso.with(mContext)
.load(restaurant.getVendorLogo())
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.into(holder.restaurentImageView);
holder.restaurentNameTextView.setText(restaurant.getName());
//Remaining code here
break;
default:
throw new RuntimeException(TAG+":Unable to bind the viewType"+viewType);
}
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
switch (viewType){
case RECYCLER_HEADER:
return new SlideItemViewHolder(inflater.inflate(R.layout.slide_show_restaurant_fragment_list,viewGroup,false));
case RECYCLER_ITEMS:
return new RecyclerItemViewHolder(inflater.inflate(R.layout.new_restautant_list_items, viewGroup, false));
default:
throw new RuntimeException(TAG+":Invalid ViewType "+viewType);
}
}
public static class RecyclerItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private ClickListener clickListener;
//Initialization here.
public RecyclerItemViewHolder(View v) {
super(v);
ButterKnife.inject(this, v);
v.setOnClickListener(this);
}
#Override
public void onClick(View v) {
clickListener.onClick(v, getPosition(), false);
}
public interface ClickListener {
/**
* Called when the view is clicked.
*
* #param v view that is clicked
* #param position of the clicked item
* #param isLongClick true if long click, false otherwise
*/
public void onClick(View v, int position, boolean isLongClick);
}
/* Setter for listener. */
public void setClickListener(ClickListener clickListener) {
this.clickListener = clickListener;
}
}
// id = 87,170
private class SlideItemViewHolder extends RecyclerView.ViewHolder {
SliderLayout sliderLayout;
LinearLayout rootLinearLayout;
public SlideItemViewHolder(View recyclerHeader) {
super(recyclerHeader);
sliderLayout = (SliderLayout) recyclerHeader.findViewById(R.id.home_slider);
rootLinearLayout = (LinearLayout) recyclerHeader.findViewById(R.id.rootLinearLayout);
}
private void updateHeader() {
if(Util.isNetworkAvailable(mContext)){
for (int i = 0; i < mData.size(); i++) {
DefaultSliderView defaultSliderView = new DefaultSliderView(mContext);
final int finalI = i;
defaultSliderView.image(mData.get(finalI).getImageUrl())
.setOnSliderClickListener(new BaseSliderView.OnSliderClickListener() {
#Override
public void onSliderClick(BaseSliderView slider) {
Restaurant restaurantById = Restaurant.searchByRestaurantId(mData.get(finalI).getTargetVendorId());
if(restaurantById != null)
openDetailFragment(restaurantById);
}
});
sliderLayout.addSlider(defaultSliderView);
}
}
}
}
public void openDetailFragment(Restaurant restaurant) {
Intent intent = new Intent(mContext, DetailTabActivity.class);
intent.putExtra(DetailTabActivity.INTENT_RESTAURANT_DATA, restaurant);
mContext.startActivity(intent);
}
public SliderLayout getSliderLayout(){
return slideItemViewHolder.sliderLayout;
}
}
And this adapter is set and updated from this fragment RestaurantFragment.java as:
private void setAdapter() {
dismissDialog();
if (getActivity() != null)
getActivity().runOnUiThread(new Runnable(){
#Override
public void run() {
if (restaurantList != null && restaurantList.size() > 0) {
restaurantRecyclerView.setVisibility(View.VISIBLE);
mEmptyListTextView.setVisibility(View.GONE);
restaurentListAdapter = new RestaurantAdapter(getActivity(), restaurantList, mRestaurantType);
restaurantRecyclerView.setAdapter(restaurentListAdapter);
restaurentListAdapter.updateAdapter(mData);
restaurantRecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(mLayoutManager) {
#Override
public void onLoadMore(int current_page) {
mCurrentPage = mCurrentPage + 1;
getHttpResturantData();
}
});
}
}
});
}
Is this much of an explanation helpful or should I paste more code?
Based on your code, it's possible to remove the header based on a certain condition.
Adjust your code to cater for the following:
#Override
public int getItemViewType(int position) {
if(hasHeaeder()) { // where you add the header
return position == 0 ? RECYCLER_HEADER : RECYCLER_ITEMS;
} else { // where you don't add the header
return RECYCLER_ITEMS;
}
}
This code also needs changing (currently it's wrong since it doesn't take care of the fact that the header adds 1 to the position).
final Restaurant restaurant = mList.get(i);
Replace it with
final Restaurant restaurant = hasHeader() ? mList.get(i +1) : mList.get(i);
Where hasHeader() is the code you need to write in order to determine whether or not the recycler should contain a header.

Categories

Resources