I have a RecyclerView and I update the Data in the adapter, my problem is that After Change I can not refresh RecyclerView Data.
i used notifyDataSetChanged(); but is doesn't work
UpdateStudent edits the student name, the problem is that after the change, RecyclerView needs to refresh list
ReyclerView Adapter :
public class RecyclerViewAdapter_StudentList extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<StudentTable> tableData = new ArrayList<>();
Context context;
private LayoutInflater mInflater;
public RecyclerViewAdapter_StudentList(Context context, List<StudentTable> tableData) {
this.mInflater = LayoutInflater.from(context);
this.context = context;
this.tableData = tableData;
}
public class itemHolder extends RecyclerView.ViewHolder {
TextView studentName;
return new itemHolder(view);
}
}
onBindViewHolder
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
itemHolder itemHolder = (itemHolder) holder;
String studentName = tableData.get(position).getStudentName();
itemHolder.studentName.setText(studentName);
itemHolder.editStudent_Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
String studentName_new = studentName_EditText.getText().toString();
database.UpdateStudent(classId , studentName_new);
notifyDataSetChanged();// does not work
}
}
}
Try this:
itemHolder.editStudent_Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
String studentName_new = studentName_EditText.getText().toString();
database.UpdateStudent(classId , studentName_new);
StudentTable student = tableData.get(position);
student.setName(studentName_new);
tableData.set(position, student);
notifyItemChanged(position);
}
}
itemHolder.editStudent_Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
String studentName_new = studentName_EditText.getText().toString();
database.UpdateStudent(classId , studentName_new);
StudentTable student = tableData.get(position);
student.setName(studentName_new);
notifyItemChanged(position);
}
}
Here you are notifying only adapter without changing data list so you need to do is
After updating retrieve data from table and store it in your current list tableData and then you have to call notifyDataSetChanged();
Related
I am stuck need your kind help, i have an activity in android user sign up, and apart from general information i have a list of existing users/entities shown in recyclerview and each item of recyclerview list contains a follow button, i want to captures the position/ buttons that were clicked to check which users/entities the new user has followed. Any suggest how to do it?
I had customer adapter and recycler view, Check the attached image for clarity. I want to create an array list that will contain ids of each list item whose button is clicked.
RecyclerView containing list item and follow button
//this adapter use on admin
public class FollowLocalBusinessAdapter extends RecyclerView.Adapter {
AlertDialog.Builder alertDialogBuilder;
private Context context;
private List<FollowLocalBusinessMC> list;
private LayoutInflater layoutInflater;
private DatabaseReference mDatabase;//database reference
private FollowLocalBusinessMC localBusinessMC;
private ListAdapterListener mListener;
public FollowLocalBusinessAdapter(Context context, List<FollowLocalBusinessMC> list) {
this.context = context;
this.list = list;
layoutInflater = LayoutInflater.from(context);
alertDialogBuilder = new AlertDialog.Builder(context);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int position) {
View view = layoutInflater.inflate(R.layout.list_item_local_business, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(final FollowLocalBusinessAdapter.MyViewHolder holder, final int position)//is called
{
localBusinessMC = list.get(position);
if (holder != null) {
if (holder.followBtn.getText().equals("Follow")) {
holder.followBtn.setBackgroundResource(R.drawable.follow_btn_bg);
holder.followBtn.setTextColor(context.getResources().getColor(R.color.colorBlueButton));
} else {
holder.followBtn.setBackgroundResource(R.drawable.following_btn_bg);
holder.followBtn.setTextColor(context.getResources().getColor(R.color.colorWhite));
}
holder.mainHeading.setText(localBusinessMC.getMainHeading());
holder.subHeading.setText(localBusinessMC.getSubHeading());
Glide.with(context).load(localBusinessMC.getIcon()).into(holder.icon);
holder.followBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "" + list.get(position).getId(), Toast.LENGTH_SHORT).show();
if (holder.followBtn.getText().equals("Follow")) {
holder.followBtn.setText("Following");
holder.followBtn.setTextColor(context.getResources().getColor(R.color.colorWhite));
holder.followBtn.setBackgroundResource(R.drawable.following_btn_bg);
} else {
holder.followBtn.setText("Follow");
holder.followBtn.setBackgroundResource(R.drawable.follow_btn_bg);
holder.followBtn.setTextColor(context.getResources().getColor(R.color.colorBlueButton));
}
}
});
}
}
#Override
public int getItemCount() {
return list.size();
}
public interface ListAdapterListener { // create an interface
void onClickAtOKButton(int position); // create callback function
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView mainHeading, subHeading;
ImageView icon;
Button followBtn;
MyViewHolder(View v) {
super(v);
mainHeading = v.findViewById(R.id.main_lbsr_id);
subHeading = v.findViewById(R.id.sub_lbsr_id);
icon = v.findViewById(R.id.icon_lbsr_id);
followBtn = v.findViewById(R.id.followBtn_lbsr_id);
}
}
}
create an interface in your Adapter with one method :
public interface CallBack{
void onItemClicked(int position , /*anyThing else*/);
}
then get an instance of interface in your Adapter :
private YourAdapter.CallBack;
in your Adpater constructor get object of CallBack :
public YourAdapter(Context context, List</* */> list, YourAdapter.CallBackcallback callBack) {
this.context = context;
this.list= list;
this.callback = callback;
}
#Override
public void onBindViewHolder(#NonNull ChoosenExerciseViewHolder holder, final int position) {
holder.View.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
callback.onItemClicked(
//pass any parameter youe defined
//for ex : position , ///);
}
});
}
then in your Activity/Fragment :
private YourAdapter.CallBack callback= (position, /* */ ) -> {
// do what you want
};
YourAdapter adapter = new YourAdapter(getContext(), calback, list);
receyclerview.setAdapter(adapter )
I am working with recyclerview and sqlite database. i want to place a button in cardview such that whenever user clicks on that button, the respective record should be deleted from the table.
This is my adapter class for recyclerview
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.CardViewHolder> {
private Context mContext;
private Cursor mCursor;
private butttonsAdapetrListener mlistener;
private RecyclerView.ViewHolder v;
public CardAdapter(Context context, Cursor cursor ,butttonsAdapetrListener listener){
mContext=context;
mCursor=cursor;
mlistener=listener;
}
#NonNull
#Override
public CardViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.mycard,parent,false);
return new CardViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CardViewHolder holder, int position) {
if(!mCursor.moveToPosition(position)){
return;
}
String name = mCursor.getString(mCursor.getColumnIndex("NAME"));
int total = mCursor.getInt(mCursor.getColumnIndex("TOTAL"));
int bunked = mCursor.getInt(mCursor.getColumnIndex("BUNK"));
int color = mCursor.getInt(mCursor.getColumnIndex("COLOR"));
long id= mCursor.getLong(mCursor.getColumnIndex("_id"));
holder.nameText.setText(name);
holder.totalText.setText(Integer.toString(total));
holder.bunkedText.setText(Integer.toString(bunked));
holder.colorText.setBackgroundColor(color);
holder.itemView.setTag(id);
v=holder;
}
#Override
public int getItemCount() {
return mCursor.getCount();
}
public class CardViewHolder extends RecyclerView.ViewHolder{
public TextView nameText;
public TextView totalText;
public TextView bunkedText;
public TextView colorText;
public Button delete;
public CardViewHolder(#NonNull View itemView) {
super(itemView);
nameText= itemView.findViewById(R.id.name);
totalText = itemView.findViewById(R.id.total_num);
bunkedText = itemView.findViewById(R.id.bunked_num);
colorText= itemView.findViewById(R.id.color);
delete= itemView.findViewById(R.id.delete);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mlistener.deleteOnClick(v,getAdapterPosition());
}
});
}
}
public interface butttonsAdapetrListener{
void deleteOnClick(RecyclerView.ViewHolder v,long position);
}
public void swapCursor(Cursor newCursor){
if(mCursor!=null){
mCursor.close();
}
mCursor=newCursor;
if(newCursor!=null){
notifyDataSetChanged();
}
}
}
This is my main activity code to delete record from database
public class MainActivity extends AppCompatActivity {
private SQLiteDatabase db;
private CardAdapter mAdapter;
private long id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SQLiteOpenHelper proBunkerDatabaseHelper = new ProBunkerDatabaseHelper(this);
db = proBunkerDatabaseHelper.getWritableDatabase();
RecyclerView recyclerView = findViewById(R.id.rv);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new CardAdapter(this, getCursor(), new CardAdapter.butttonsAdapetrListener() {
#Override
public void deleteOnClick(RecyclerView.ViewHolder v, long position) {
id = (long)v.itemView.getTag();
db.delete("MYTABLE","_id="+id,null);
mAdapter.swapCursor(getCursor());
}
});
recyclerView.setAdapter(mAdapter);
FloatingActionButton b = findViewById(R.id.fab);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,AddSubject.class);
startActivity(intent);
}
});
}
public Cursor getCursor(){
return db.query("MYTABLE",null,null,null,null,null,"_id ASC");
}
}
The main problem is the when I click on the delete button in any item it is deleting the item which is last in the cursor.
there are no compilation errors and runtime issues only the records are not deleting in correct order.
Try it like this:
Your interface:
public interface butttonsAdapetrListener{
void deleteOnClick(int id,long adapterPos);
}
Inside your CardViewHolder:
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int id = (int)view.getTag();
mlistener.deleteOnClick(id,getAdapterPosition());
}
});
In onBindViewHolder
holder.delete.setTag(id);
In MainActivity onCreate
mAdapter = new CardAdapter(this, getCursor(), new CardAdapter.butttonsAdapetrListener() {
#Override
public void deleteOnClick(int id, long position) {
db.delete("MYTABLE","_id="+id,null);
mAdapter.swapCursor(getCursor());
}
});
Another alternative
If you want your activity to be clean and not handle data from within.
Keep it for the adapter to handle the data being deleted and notifying any change.
Just create a listener for the button in the onbindviewholder method.
Is it all possible to access an adapter's data via another adapter?
I want to start an activity and pass data from an adapter to a fragment which is used in TabLayout as one of three fragments, I have two adapters and a button which is clicked to start an activity, its Java code is in my first adapter and I need to pass second adapter's data via second adapter itself
here is my codes:
my first adapter:
public class RecyclerViewDataAdapter extends RecyclerView.Adapter<RecyclerViewDataAdapter.ItemRowHolder>{
private ArrayList<SectionDataModel> dataList;
private Context mContext;
private RecyclerView.RecycledViewPool recycledViewPool;
private SnapHelper snapHelper;
public RecyclerViewDataAdapter(ArrayList<SectionDataModel> dataList, Context mContext) {
this.dataList = dataList;
this.mContext = mContext;
recycledViewPool = new RecyclerView.RecycledViewPool();
}
#Override
public ItemRowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
ItemRowHolder rowHolder = new ItemRowHolder(v);
snapHelper = new GravitySnapHelper(Gravity.START);
return rowHolder;
}
#Override
public void onBindViewHolder(ItemRowHolder holder, int position) {
ArrayList singleSectionItems = dataList.get(position).getAllItemInSection();
final String sectionName = dataList.get(position).getHeaderTitle();
holder.itemTitle.setText(sectionName);
SectionDataAdapter adapter = new SectionDataAdapter(singleSectionItems, mContext);
holder.recyclerView.setHasFixedSize(true);
holder.recyclerView.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
holder.recyclerView.setAdapter(adapter);
holder.recyclerView.setRecycledViewPool(recycledViewPool);
snapHelper.attachToRecyclerView(holder.recyclerView);
holder.btnMore.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//here i can start the activity but..(second adapter)
Toast.makeText(view.getContext(), sectionName, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return (null != dataList ? dataList.size() : 0);
}
public class ItemRowHolder extends RecyclerView.ViewHolder {
protected ImageView mitemImage;
protected TextView mitemtext;
protected TextView itemTitle;
protected RecyclerView recyclerView;
protected Button btnMore;
public ItemRowHolder(View itemView) {
super(itemView);
this.mitemImage = itemView.findViewById(R.id.itemImage);
this.mitemtext = itemView.findViewById(R.id.tvTitle);
this.itemTitle = itemView.findViewById(R.id.itemTitle);
this.recyclerView = itemView.findViewById(R.id.recycler_view_list);
this.btnMore = itemView.findViewById(R.id.btnMore);
}
}
} '
and my second adapter:
import java.net.PortUnreachableException;
import java.util.ArrayList;
public class SectionDataAdapter extends RecyclerView.Adapter<SectionDataAdapter.SssingleItemRowHolder>{
private ArrayList<SingleItemModel> itemModels;
private Context mContext;
public SectionDataAdapter(ArrayList<SingleItemModel> itemModels, Context mContext) {
this.itemModels = itemModels;
this.mContext = mContext;
}
#Override
public SingleItemRowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_single_card, null);
SingleItemRowHolder singleItemRowHolder = new SingleItemRowHolder(v);
return singleItemRowHolder;
}
#Override
public void onBindViewHolder(SingleItemRowHolder holder, int position) {
SingleItemModel itemModel = itemModels.get(position);
holder.tvTitle.setText(itemModel.getName());
holder.mitemImage.setImageResource(itemModel.getImage());
}
#Override
public int getItemCount() {
return (null != itemModels ? itemModels.size() : 0);
}
public class SingleItemRowHolder extends RecyclerView.ViewHolder {
protected TextView tvTitle;
protected ImageView mitemImage;
public SingleItemRowHolder(View itemView) {
super(itemView);
final Intent intent = new Intent(mContext,MainActivity.class);
this.mitemImage = itemView.findViewById(R.id.itemImage);
this.tvTitle = itemView.findViewById(R.id.tvTitle);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//... need to start the activity from here
Toast.makeText(view.getContext(), tvTitle.getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
Like #MilaDroid said you simply need a getter that returns the another Adapter's ArrayList<SingleItemModel> but the problem you will face is that you need to have the same instance of the Adapter from the Activity in order to get the populated ArrayList<SingleItemModel>.
A good workaround is to used Bill Pugh's Singleton in the Adapter
public class Adapter {
private ArrayList<SingleItemModel> list;
private Adapter() {}
public static Adapter getInstance() {
return InstInit.INSTANCE;
}
// Don't forget to set the list (or NPE)
// because we can't argue with a Singleton
public void setList(ArrayList<SingleItemModel> list) {
this.list = list;
}
// You can now get the ArrayList
public ArrayList<SingleItemModel> getList() {
return list;
}
private static class InstInit {
private static final Adapter INSTANCE = new Adapter();
}
// Overrided RecyclerView.Adapter Methods
.................
}
Retrieving the ArrayList assuming that the following Adapters are Singleton
AdapterOne a1 = AdapterOne.getInstance();
AdapterTwo a2 = AdapterTwo.getInstance();
ArrayList<SingleItemModel> a1RetrievedList = a1.getList();
// You don't need to create a new instance
// creating a new instance doesn't make sense
// because you need to repopulate the list
// for the new instance.
ArrayList<SingleItemModel> a2RetrievedList = a2.getList();
// You can also retrieve from AdapterTwo
i want to list all my stored data on database and show it on using a recycler view/adapter. Can anyone help me about this.
-i have a class of getter and setter(PWClass)
Here are some of my codes:
This is the time i am storing some data on class and add it on list but it is only a sample.
PWClass pwc = new PWClass("Facebook", "Action & Adventure", "2015");
pwList.add(pwc);
pwc = new PWClass("Instagram", "Action & Adventure", "2015");
pwList.add(pwc);
mAdapter.notifyDataSetChanged();
My problem is how can i combine the code above and calling a query on database to display datas like:
//i declare on top
private List<PWClass> pwList = new ArrayList<>();
private RecyclerView recyclerView;
private PWAdapter mAdapter;
Database controller;
//and from a method below
pwList.add(controller.add_pw());//adding on list array by calling my db method
Should i use some for/while loops/arrays? I am thinking the code above but i know its wrong. Do you get my point?
Please help so i can understand more, i appreciate your suggestions thanks!
read this post, you will get clear idea on Sqlite database.
check this out
public List<userData> getAlluser() {
List<userData> usersdetail = new ArrayList<>();
curser = dbs.query("data_table", null, null, null, null, null, null);
try {
if (curser.moveToFirst()) {
do {
userData muser = new userData();
muser.appname = curser.getString(curser.getColumnIndex("appname"));
muser.user = curser.getString(curser.getColumnIndex("email"));
muser.passwordss = curser.getString(curser.getColumnIndex("password"));
usersdetail.add(muser);
} while (curser.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
}
return usersdetail;
}
public class RecyclerViewAdopterMy extends RecyclerView.Adapter<RecyclerViewAdopterMy.MyViewHolder> implements View.OnClickListener {
List<userData> user = new ArrayList<>();
Context context;
public RecyclerViewAdopterMy(List<userData> user, Context context) {
this.user = user;
this.context = context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, null);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.appR.setText(user.get(position).appname);
holder.nameR.setText(user.get(position).user);
holder.passR.setText(user.get(position).passwordss);
holder.cardR.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
AlertDialog.Builder alertbox = new AlertDialog.Builder(view.getRootView().getContext());
alertbox.setMessage("Do you want delete this item");
alertbox.setTitle("Delete");
alertbox.setIcon(R.drawable.delete);
alertbox.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
int pos = holder.getAdapterPosition();
user.remove(user.get(position));
notifyItemRemoved(position);
notifyItemRangeChanged(position, getItemCount());
notifyItemChanged(position);
}
});
alertbox.show();
return true;
}
});
}
#Override
public int getItemCount() {
return user.size();
}
#Override
public void onClick(View view) {
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
private final TextView appR;
private final TextView nameR;
private final TextView passR;
private final CardView cardR;
public MyViewHolder(View view) {
super(view);
appR = (TextView) view.findViewById(R.id.Appstore);
nameR = (TextView) view.findViewById(R.id.userStore);
passR = (TextView) view.findViewById(R.id.passstore);
cardR = (CardView) view.findViewById(R.id.card);
}
}
}
I'm doing a RecyclerView example. The thing is that when I add the first item on the list it shows the item correctly on the recyclerview but the next items I add aren't showing on the recycle view.
Please help me.
Adapter code is:
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.PersonViewHolder> {
private ArrayList<Person> mData;
LayoutInflater inflater;
public PersonAdapter() {
}
public PersonAdapter(Context context, ArrayList<Person> data) {
inflater = LayoutInflater.from(context);
update(data);
}
public void update(ArrayList<Person> data) {
mData = data;
notifyDataSetChanged();
}
#Override
public PersonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.custom_row, parent, false);
PersonViewHolder holder = new PersonViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(PersonViewHolder holder, int position) {
Person person = mData.get(position);
holder.ivImagen.setImageResource(R.drawable.ic_action_android);
holder.tvNombre.setText(person.getName());
holder.tvApellido.setText(person.getLast_name());
}
#Override
public int getItemCount() {
return mData.size();
}
public static class PersonViewHolder extends RecyclerView.ViewHolder {
ImageView ivImagen;
TextView tvNombre;
TextView tvApellido;
public PersonViewHolder(View itemView) {
super(itemView);
ivImagen = (ImageView) itemView.findViewById(R.id.cr_iv_imagen);
tvNombre = (TextView) itemView.findViewById(R.id.cr_tv_name);
tvApellido = (TextView) itemView.findViewById(R.id.cr_tv_last_name);
}
}}
Main Activity Code is:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
ArrayList<Person> persons = new ArrayList<>();
EditText et_name;
EditText et_last_name;
RecyclerView rv_names;
PersonAdapter adapter;
Button btAgregar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name = (EditText) findViewById(R.id.tv_name);
et_last_name = (EditText) findViewById(R.id.tv_last_name);
btAgregar = (Button) findViewById(R.id.bt_agregar);
rv_names = (RecyclerView) findViewById(R.id.rv_nombres);
LinearLayoutManager manager = new LinearLayoutManager(this);
rv_names.setLayoutManager(manager);
adapter = new PersonAdapter(this, persons);
rv_names.setAdapter(adapter);
btAgregar.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Person person = new Person(et_name.getText().toString(), et_last_name.getText().toString());
persons.add(person);
Toast.makeText(this, "Items: " + String.valueOf(persons.size()), Toast.LENGTH_SHORT).show();
} }
Try this code for onClick function
#Override
public void onClick(View v) {
Person person = new Person(et_name.getText().toString(), et_last_name.getText().toString());
persons.add(person);
adapter.update(persons);
Toast.makeText(this, "Items: " + String.valueOf(persons.size()), Toast.LENGTH_SHORT).show();
}
UPDATE:
In Adapter code, try the following changes..
public void update(ArrayList<Person> data) {
mData.clear();
mData.addAll(data)
notifyDataSetChanged();
}
In the onClick you are adding a person, but you are not passing the updated list to the adapter by calling the adapter's update method. Might this be the reason?
i just added called adapter.notifyDataSetChanged();