I want to update my SQLite database on checkbox state changes inside recycler view. All data is listed in recycler view. when i click the checkbox i want to call a databaase function to update the database
public class OverTimeAdapter extends RecyclerView.Adapter<OverTimeAdapter.MyViewHolder> {
private Context context;
private ArrayList otId,otDate,otShift,paymentStatus;
private DatabaseHelper attendanceDB;
OverTimeAdapter(Context context,ArrayList otId,ArrayList otDate,ArrayList otShift ,ArrayList paymentStatus){
this.context =context;
this.otId = otId;
this.otDate = otDate;
this.otShift=otShift;
this.paymentStatus = paymentStatus;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, int position) {
if (paymentStatus.get(position)=="1"){
holder.otListPayment.setChecked(true);
}else {
holder.otListPayment.setChecked(false);
}
OtDbId =String.valueOf(otId.get(position));
holder.otListPayment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
boolean checked =holder.otListPayment.isChecked();
if (checked){
payStatus=1;
}else{
payStatus=0;
}
// call db update function from here
// attendanceDB = new DatabaseHelper(this); This is error
//attendanceDB.updateOvertime() /*error*/
}
});
}
#Override
public int getItemCount() {
return otDate.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
public CheckBox otListPayment;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
otListPayment =(CheckBox) itemView.findViewById(R.id.chk_ot_list_payment);
}
}
}
How can we initialize the DBHelper object and call the function? and from where(inside which function) i can do it?
Pass a callback from adapter to fragment/activity. Do database changes in fragment/activity.
Check this: https://stackoverflow.com/a/42234382/3797879
Related
I am getting data from server and then parsing it and storing it in a List. I am using this list for the RecyclerView's adapter. I am using Fragments.
I extended
RecyclerView.Adapter<RecyclerView.ViewHolder>
this my complete adapter class
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.ViewHolder> {
private List<ProductModel> list;
ItemClickListener itemClickListener;
public GridAdapter(List<ProductModel> list, ItemClickListener itemClickListener) {
this.list = list;
this.itemClickListener = itemClickListener;
}
public void update(int position,ProductModel pm){
Log.v("update adapter",position+"");
list.set(position,pm);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final ProductModel cp = list.get(position);
holder.tvName.setText(cp.name);
holder.tvPrice.setText(cp.price);
holder.ratingBar.setRating(cp.rate);
Log.v("grid",cp.id + "=="+ cp.checked);
if(cp.checked==1){
holder.imgCheck.setVisibility(View.VISIBLE);
}else{
holder.imgCheck.setVisibility(View.GONE);
}
LayerDrawable stars = (LayerDrawable) holder.ratingBar.getProgressDrawable();
stars.getDrawable(2).setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);
holder.lnrItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemClickListener.onItemClick(cp,position);
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvName, tvPrice;
ImageView imgMenu, imgCheck;
LinearLayout lnrItem;
RatingBar ratingBar;
public ViewHolder(View itemView) {
super(itemView);
lnrItem = itemView.findViewById(R.id.lnrItem);
imgMenu = itemView.findViewById(R.id.imgMenu);
imgCheck = itemView.findViewById(R.id.imgCheck);
tvName = itemView.findViewById(R.id.tvName);
ratingBar = itemView.findViewById(R.id.ratingBar);
tvPrice = itemView.findViewById(R.id.tvPrice);
}
}
}
and in fragment activity i use this code to load adapter to recyclerview
public void fillListProduct(List<ProductModel> mItems) { //method for load adapter for the first time
mAdapterGrid = new GridAdapter(mItems,this);
recGrid.setAdapter(mAdapterGrid);
}
void update(){ //method to change checked value
mAdapterGrid.update(cp.row,cp);
mAdapterGrid.notifyDataSetChanged();
}
in my custom adapter i have 3 variable lets call id, name, checked, everything work properly, in first load i set 0 as default value for checked, in my scenario user can change checked value by tap the row of recycleview.
my question is, when user tap desire row then checked will change from 0 to 1 and display it to recycelview, i already use notifydatasetchange() but not working.
Please help.
thanks
Try to remove mAdapterGrid.notifyDataSetChanged();
and modify this function in your adpater:
public void update(int position,ProductModel pm){
Log.v("update adapter",position+"");
list.set(position,pm);
notifyItemChanged(position);
}
I want remove selected item from recyclerView list.
In my list I have delete image icon each row and I want delete item when clicked delete image icon. How can do it?
My adapter code this is see my code how can do it:
thank you
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ItemViewHolder>{
private Context context;
private List<Items> items=new ArrayList<>();
public ListAdapter(Context context){
this.context=context;
}
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(context);
View view=layoutInflater.inflate(R.layout.item,parent,false);
return new ItemViewHolder(view);
}
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
holder.bindItem(items.get(position));
}
#Override
public int getItemCount() {
return items.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder{
private TextView titleTextView;
private ImageView editIcon;
private ImageView deleteIcon;
public ItemViewHolder(View itemView) {
super(itemView);
titleTextView =itemView.findViewById(R.id.item_title);
editIcon=itemView.findViewById(R.id.item_edit);
deleteIcon=itemView.findViewById(R.id.item_delete);
}
public void bindItem(Items item){
titleTextView.setText(item.getTitle());
}
public void removeItem(int position){
items.remove(position);
notifyItemRemoved(position);
}
}
public void addItem(Items item){
items.add(item);
notifyItemInserted(items.size()-1);
}
}
Try below code
public ItemViewHolder(View itemView) {
super(itemView);
titleTextView =itemView.findViewById(R.id.item_title);
editIcon=itemView.findViewById(R.id.item_edit);
deleteIcon=itemView.findViewById(R.id.item_delete);
// put this code
deleteIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
removeItem(getAdapterPosition())
}
});
}
The answer above does the job but it is always better to use interface callback for easier implementation and code modularity. Below is the code that i like to write for removing the list item from activity. In this method you dont have to alter much code of adapter class and in case you want to do more complicated such as: remove the list element only when element from firebase database is removed, this method does this job perfectly.
here is a code snippet
new DeclinedClickListener() {
#Override
public void declinedClick(int position, View v) {
fbDB.getReference("news_requests").child(articles.get(position).getNewsID()).removeValue(new DatabaseReference.CompletionListener() {
#Override
public void onComplete(#Nullable DatabaseError databaseError, #NonNull DatabaseReference databaseReference) {
articles.remove(position);
if(article_req_rv.getAdapter()!=null) {
article_req_rv.getAdapter().notifyDataSetChanged();
}
}
});
you make a interface for it
public interface DeclinedClickListener {
void declinedClick(int position, View v);
}
Use this inteface in recyclerview
holder.declined_btx.setOnClickListener(l->{
declinedClickListener.declinedClick(position,l);
});
Everything works well and my onClick in my recyclerView is working in getting the positions of my items, but what my design calls for is to be able to click an item of the recyclerView and open up a new activity (as a popover or pop up). I can achieve this but my problems comes with the information I need to display on the popover. The information comes like this inside the activity (inside a Firebase value call)
attributeList.removeAll(attributeList);
for (DataSnapshot child : dataSnapshot.child("Attribute").getChildren()){
Attribute attribute = child.getValue(Attribute.class);
attribute_list newAttributeList = new attribute_list( attribute.Name + ": " + attribute.Value);
attributeList.add(newAttributeList);
}
attributeAdapter = new attribute_list_adapter(attributeList, getContext());
recyclerAttribute.setAdapter(attributeAdapter);
This works perfectly for displaying the information, but there's more then just a "value" and a "name" associated with the click.
Basically when I select an item, I need to get the position of the item clicked (which I have) and compare it to the position inside attributeList so I can call a Firebase call (or pass the data somehow) to the popover to display values from the "Attribute" class (such as Name, Value, Description, and another list (recyclerView).
My recyclerView:
public class attribute_list_adapter extends RecyclerView.Adapter<attribute_list_adapter.ViewHolder> {
private List<attribute_list> listItems;
private Context context;
public attribute_list_adapter(List<attribute_list> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.attribute_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
attribute_list listItem = listItems.get(position);
holder.txtTitle.setText(listItem.getTxtTitle());
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView txtTitle;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
txtTitle = (TextView) itemView.findViewById(R.id.txtTitle);
}
#Override
public void onClick(View v) {
}
}
}
This is example:
public class attribute_list_adapter extends RecyclerView.Adapter<attribute_list_adapter.ViewHolder> {
private List<attribute_list> listItems;
private Context context;
public attribute_list_adapter(List<attribute_list> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.attribute_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.onClickListener() {
#Override
public void onClick(View v) {
onItemClickListener.onItemClick(position);
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView txtberita;
ImageView imgberita;
TextView txtnama;
public ViewHolder(View itemView) {
super(itemView);
txtnama = (TextView) itemView.findViewById(R.id.txtnama);
txtberita = (TextView) itemView.findViewById(R.id.txtberita);
imgberita = (ImageView) itemView.findViewById(R.id.imgberita);
}
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener = onItemClickListener;
}
OnItemClickListener onItemClickListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
}
your Activity. in Oncreate()
public class TestActivity extends AppCompatActivity implements attribute_list_adapter.OnItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
attribute_list_adapter adapter = new attribute_list_adapter(listItems, this);
adapter.setOnItemClickListener(this);
}
#Override
public void onItemClick(int position) {
// code here
}
}
Create an interface something like
public interface OnSingleItemClickListener{
void onSingleItemClick(int position);
}
Then implement it on your ViewHolder like this
public class ViewHolder extends RecyclerView.ViewHolder implements OnSingleItemClickListener {
public ViewHolder(View itemView) {
super(itemView);
}
#Override
void onSingleItemClick(int position){
if(listItems.get(position) == listItems.get(getAdapterPosition)){
// TODO do something here
}
}
now on your OnBindViewHolder inside your adapter you must do this.
holder.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
holder.onSingleItemClick(position);
}
}):
In my MainActivity I have something like this:
recyclerAdapter = new RecyclerAdapter(this, arrayList);
recyclerView.setAdapter(recyclerAdapter);
To update my RecyclerView, I do: (in MainActivity, too)
Item item = new Item();
item.setId(id);
item.setMessage(message);
arrayList.set(position, item);
recyclerAdapter.notifyItemChanged(position);
I want to have a button within every RecyclerView list item which can enable/disable the current entry. Therefore I need to get the current toggle state.
My problem is, how can I update the RecyclerView in MainActivity from within my ViewHolder?
RecyclerView.ViewHolder:
public class SetViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{//, View.OnLongClickListener{
public ImageView toggle;
public SetViewHolder(View itemView){
super(itemView);
toggle = (ImageView) itemView.findViewById(R.id.img_main_card_toggle);
toggle.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v.getId() == toggle.getId()) {
int clicked_position = getAdapterPosition();
//TODO update Item of RecyclerView of MainActivity
}
}
My Recycler.Adapter:
public class RulesAdapter extends RecyclerView.Adapter<SetViewHolder>{
private Activity activity;
List<Item> items = Collections.emptyList();
private OnTapListener onTapListener;
public RulesAdapter(Activity activity, List<Item> items){
this.activity = activity;
this.items = items;
}
#Override
public SetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rules_list_item,parent,false);
return new SetViewHolder(view);
}
#Override
public void onBindViewHolder(SetViewHolder holder, final int position) {
holder.recevied_message.setText(items.get(position).getReceived_message());
holder.reply_message.setText(items.get(position).getReply_message());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(onTapListener != null){
onTapListener.OnTapView(position);
}
}
});
}
#Override
public int getItemCount() {
return items.size();
}
public void setOnTapListener(OnTapListener onTapListener){
this.onTapListener = onTapListener;
}
}
Define an Interface.
public interface OnRecyclerItemToggleClickListener {
void onToggleClick(int adapterPosition);
}
Implement this in your adapter. And pass the adapter instance to the ViewHolder through a setter method in the onCreateViewHolder callback.
public class SetViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{//, View.OnLongClickListener{
public ImageView toggle;
private OnRecyclerItemToggleClickListener listener;
public SetViewHolder(View itemView){
super(itemView);
toggle = (ImageView)
itemView.findViewById(R.id.img_main_card_toggle);
toggle.setOnClickListener(this);
}
public void setRecyclerItemToggleClickListener( OnRecyclerItemToggleClickListener listener) {
this.listener = listener;
}
#Override
public void onClick(View v) {
if (v.getId() == toggle.getId()) {
int clicked_position = getAdapterPosition();
//TODO update Item of RecyclerView of MainActivity
listener.onToggleClick(clicked_position);
}
}
In your adapter:
#Override
public SetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rules_list_item,parent,false);
SetViewHolder holder = new SetViewHolder(view);
holder.setOnRecyclerItemToggleClickListener(this);
return holder;
}
#Override public void onToggleClick(int adapterPosition) {
// you will get the callback here when the toggle button is clicked.
// you can update the ArrayList here.
// Or similarly, call an interface method to Activity.
}
And call this onToggleClick method from ViewHolder when the toggle is clicked. You will get a callback to adapter, where you can update the ArrayList. Otherwise you can have another similar Interface to give callback to Activity from the adapter.
You just have to add a static function and make items static too:
public static ArrayList<Items> getAreayList()
{
return items;
}
And get this function in MainActivity:
onStart()
I have to two data sets with different adapters inside a single activity and I want to use notifyDataSetChanged() however its not working for the other adapter. So inside my adapterFirst class I have LongCLickListener which is using notifyDataSetChanged() and I want to call the adapterSecond to notify too if adapterFirst is updated. The AdapterSecond data is not being updated when pressing LongClick
public class AdapterFirst extends RecyclerView.Adapter <AdapterFirst .ViewHolder> {
private List<Object> objectList;
private Context mContext;
AdapterSecond adapterSecond;
public AdapteFirst(List<Object> list) { objectList= list; }
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//query method
notifyDataSetChanged(); //working
//here it gets the nullpointerexception error
adapterSecond = new AdapteSecond();
adapterSecond.notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return (objectList != null? objectList.size():0);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView data;
public ViewHolder(View itemView) {
super(itemView);
data= (TextView) itemView.findViewById(R.id.text);
}
}
}
AdapterSecond
public class AdapterSecond extends
RecyclerView.Adapter <AdapterSecond.ViewHolder> {
private List<Object> objectList;
private Context mContext;
public AdapterSecond () {}
public AdapterSecond (List<Object> list) { objectList= list; }
#Override
public AdapterSecond.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_2, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final AdapterSecond.ViewHolder holder, int position) {
final Object object = objectList.get(holder.getAdapterPosition());
holder.data2.setText(object.getData());
}
#Override
public int getItemCount() {
return (objectList != null? objectList.size():0);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView data2;
public ViewHolder(View itemView) {
super(itemView);
data2= (TextView) itemView.findViewById(R.id.text2);
}
}
}
Seems like the order of initialization of the adapters have some issues.
Just make sure that you have initialize the secondAdapter before the firstAdapter
secondAdapter= new SecondAdapter();
firstAdapter = new FirstAdapter();
Just check the order in which they initialize!