Recyclerview load more lost item click when scrolling - java

I have a problem with Recyclerview item click. I fetch data to list() method and add via addItem() method in recyclerview custom adapter when scroll down in addOnScrollListener. I get item position with click interface on Fragment. First fetch data work perfectly but when fetch loadmore, can't retrive item positon to new data with onButtonLClick() method.
// in onBindViewHolder;
holder.lnl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
rcylviewItemNotify.onButtonLClick(position);
}catch (Throwable e){
//interface can be null
}
}
});
// addItem() method in adapter;
public void addItem(List<Image> img) {
for (Image im : img) {
arrayList.add(im);
}
notifyDataSetChanged();
}
// interface code;
public interface RcylviewItemNotify {
void onButtonLClick(int position);
}
// in Fragment code;
public void list() {
GetServices service = RetrofitInstance.getRetrofitInstance().create(GetServices.class);
Call<Images> call = service.getImages();
call.enqueue(new Callback<Images>() {
#Override
public void onResponse(Call<Images> call, Response<Images> response) {
Images body = response.body();
records = body.getImages();
adapter.addItem(records);
}
#Override
public void onFailure(Call<Images> call, Throwable t) {
Toast.makeText(getActivity(), "Network hatası onFailure", Toast.LENGTH_SHORT).show();
reflesh.setRefreshing(false);
}
});
}
#Override
public void onButtonLClick(int position) {
final String clickId = String.valueOf(records.get(position).getID());
Toast.makeText(getActivity(), "ID: " + clickId, Toast.LENGTH_SHORT).show();
}
// recycler settings;
public void loadView() {
layoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(layoutManager);
Collections.reverse(records);
adapter = new RecyclerViewAdapter(this,(ArrayList<Image>) records, getActivity());
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
reflesh.setRefreshing(false);
}

I'm not sure if this is your issue but you should be using the ViewHolder to get the position. Inside of your onBindViewHolder:
#Override
public void onClick(View view){
int itemPosition = holder.getAdapterPosition();
// Then do whatever you need to with the position
}

Related

Get cardview data to another activity with swipe

I want to get data of card on right swipe and on left i want to remove it from list but not to delete it from firebase how can i achieve it ? Here is my code
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
if(direction==ItemTouchHelper.RIGHT)
{
Toast.makeText(home.this, uplodinfo2.getBreed() +"/"+ uplodinfo2.getPrice()+"Right Swipe", Toast.LENGTH_SHORT).show();
}
if(direction==ItemTouchHelper.LEFT)
{
}
}
};
protected void onStart()
{ super.onStart();
FirebaseRecyclerAdapter<PetData,PetAdapter> firebaseRecyclerAdapter=new FirebaseRecyclerAdapter<PetData, PetAdapter>(PetData.class,R.layout.swipelayout,PetAdapter.class,query) {
#Override
protected void populateViewHolder(PetAdapter categoryviewHoder, final PetData uplodinfo, int i) {
uplodinfo2=uplodinfo;
categoryviewHoder.setDetail(getApplicationContext(),"Price: " + uplodinfo.getPrice() + "$","Breed Name: "+uplodinfo.getBreed(),uplodinfo.getImageUrl());
msg= uplodinfo.getName();
// txtcat.setText(Category);
categoryviewHoder.view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(home.this,rightview.class);
startActivity(i);
}
});
}
};
recyclerHome.setAdapter(firebaseRecyclerAdapter);
}

Stop animation of Recyclerview when load more data

i'm tying to load more data each time user reached at the bottom of Recyclerview by get data of next page , using this :
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (!recyclerView.canScrollVertically(1) && isEnd) {
page++;
isEnd = false;
new fetchData().execute(page);
}
}
});
And everything works fine , but i have a problem with animation , each time i load more data Recyclerview disappears and shows.
here's my rest of code :
public class fetchData extends AsyncTask<Integer, List<Wallpaper>, List<Wallpaper>> {
Document doc = null;
ArrayList<Wallpaper> urls = new ArrayList<>();
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected List<Wallpaper> doInBackground(Integer... integers) {
try {
doc = Jsoup.connect(URLSource+"/page/" + integers[0]).get();
} catch (IOException e) {
e.printStackTrace();
}
Elements newsHeadlines = doc.select(".thumbnail");
for (Element headline : newsHeadlines) {
String thumb = headline.select("img").attr("src");
String title = headline.select("img").attr("alt");
Wallpaper wallpaperInfo = new Wallpaper();
URL = URL.replace("/wallpapers/", "/walls/");
wallpaperInfo.setThumbnails(URL);
wallpaperInfo.setTitle(title);
urls.add(wallpaperInfo);
}
return urls;
}
#Override
protected void onPostExecute(List<Wallpaper> wallpapers) {
super.onPostExecute(wallpapers);
setAdapterForRecyclerView(wallpapers);
isEnd = true;
}
}
private void setAdapterForRecyclerView(List<Wallpaper> wallpapers) {
if (myAdapter == null) {
myAdapter = new MyAdapter(wallpapers, getActivity(), new RecyclerViewClickListener() {
#Override
public void onClick(View view, Wallpaper wallpaper) {
Intent intent = new Intent(getActivity(), FullScreen.class);
intent.putExtra("img", wallpaper.getThumbnails());
if (wallpaper.getTitle().isEmpty()) {
intent.putExtra("title", "Unknown");
} else {
intent.putExtra("title", wallpaper.getTitle());
}
startActivity(intent);
/* TODO: FULLSCREEN ACTIVITY HERE*/
}
#Override
public void onClick(View view, Category categories) {
}
});
recyclerView.setAdapter(myAdapter);
} else {
myAdapter.getItems().addAll(wallpapers);
myAdapter.notifyDataSetChanged();
}
progressbar.setVisibility(View.GONE);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (!recyclerView.canScrollVertically(1) && isEnd) {
page++;
isEnd = false;
new fetchData().execute(page);
}
}
});
}
hope you guys help me to stop this animation , i just want to load more data without any animation
i think that your problem is in the calling of setAdapterForRecyclerView as there you may create new adapter instance and set this new adapter to the recyclerview again which lead to this behavior.
i recommend to append the new list of wallpapers objects to the recyclerview list then call notifydatasetchanged

FirestoreRecyclerAdapter not updated after new firestore query

I have a FloatingSearchView in my app to perform some query on my Firestore database. When I check the size of each query, the result is as expected but my view is not updating with the result. I don't understand if this is the queries or if this is how I handle the different adapter.
I have one FirestoreRecyclerAdapter for each query. I don't understand what's wrong. Thank you for your help!
floatingSearchView.setOnSearchListener(new
FloatingSearchView.OnSearchListener() {
#Override
public void onSuggestionClicked(SearchSuggestion
searchSuggestion) {
mLastQuery = searchSuggestion.getBody();
com.google.firebase.firestore.Query qSuggestion =
db
.collection("article")
.whereEqualTo("category", category_key)
.whereEqualTo("type", mLastQuery);
qSuggestion
.get()
.addOnSuccessListener(new
OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot
documentSnapshots) {
int size = documentSnapshots
.getDocuments()
.size();
Toast.makeText(Blog.this, "size " + size,
Toast.LENGTH_LONG).show();
}
});
FirestoreRecyclerOptions<Blog_model> opt = new FirestoreRecyclerOptions.Builder<Blog_model>()
.setQuery(qSuggestion, Blog_model.class)
.build();
Log.d("option", opt.getSnapshots().toString());
suggestionAdapter = new FirestoreRecyclerAdapter<Blog_model, Blog.BlogViewHolder>(opt) {
#Override
public void onBindViewHolder(#NonNull Blog.BlogViewHolder holder, int position, #NonNull final Blog_model model) {
holder.setTitle(model.getTitle());
holder.setDesc(model.getDesc());
holder.setImage(getApplicationContext(), model.getPicture());
final String post_key = getSnapshots().getSnapshot(position).getId();
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Ordinary Intent for launching a new activity
final Intent intent = new Intent(Blog.this, BlogDetails.class);
intent.putExtra("article_id", post_key);
intent.putExtra("category_key", category_key);
intent.putExtra("image", model.getPicture());
intent.putExtra("title", model.getTitle());
startActivity(intent);
}
});
}
#Override
public Blog.BlogViewHolder onCreateViewHolder(ViewGroup group, int i) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.message for each item
View view = LayoutInflater.from(group.getContext())
.inflate(R.layout.blog_row, group, false);
return new Blog.BlogViewHolder(view);
}
};
floatingSearchView.clearSearchFocus();
mBlogList.setAdapter(suggestionAdapter);
}
#Override
public void onSearchAction(String currentQuery) {
mLastQuery = currentQuery;
// query to firebase
com.google.firebase.firestore.Query qSuggestion =
db
.collection("article")
.whereEqualTo("keyword."+mLastQuery, true);
FirestoreRecyclerOptions<Blog_model> options1 = new FirestoreRecyclerOptions.Builder<Blog_model>()
.setQuery(qSuggestion, Blog_model.class)
.build();
Log.d("option", options1.getSnapshots().toString());
searchAdapter = new FirestoreRecyclerAdapter<Blog_model, Blog.BlogViewHolder>(options1) {
#Override
public void onBindViewHolder(#NonNull Blog.BlogViewHolder holder, int position, #NonNull final Blog_model model) {
holder.setTitle(model.getTitle());
holder.setDesc(model.getDesc());
holder.setImage(getApplicationContext(), model.getPicture());
final String post_key = getSnapshots().getSnapshot(position).getId();
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Toast.makeText(Blog.this, "title", Toast.LENGTH_LONG).show();
// Ordinary Intent for launching a new activity
final Intent intent = new Intent(Blog.this, BlogDetails.class);
intent.putExtra("article_id", post_key);
intent.putExtra("category_key", category_key);
intent.putExtra("image", model.getPicture());
intent.putExtra("title", model.getTitle());
startActivity(intent);
}
});
}
#Override
public Blog.BlogViewHolder onCreateViewHolder(ViewGroup group, int i) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.message for each item
View view = LayoutInflater.from(group.getContext())
.inflate(R.layout.blog_row, group, false);
return new Blog.BlogViewHolder(view);
}
};
mBlogList.setAdapter(searchAdapter);
}
});
#Override
public void onStart() {
super.onStart();
adapter.startListening();
if(suggestionAdapter != null){
suggestionAdapter.startListening();
}
if(searchAdapter != null){
searchAdapter.startListening();
}
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
if(suggestionAdapter != null){
suggestionAdapter.stopListening();
}
if(searchAdapter != null){
searchAdapter.stopListening();
}
}
You are using two FirestoreRecyclerAdapter objects, which is correct, but the problem in your code is that you are not listening to the second adapter for changes in the right place. To solve this, add inside onSearchAction method:
searchAdapter.startListening();
Right after you create the adapter object. This means that for every character that you type in your FloatingSearchView, you create a new adapter and you populate it with the results that are coming from the database. If you are starting listening in the onStart method, it doesn't help you at all.

How to display data in a recyclerview using FirebaseUI?

I am new to firebase and I am in love with this real-time database thing.
However, I am not sure how to display nested data in a recycled view.
Following is my database structure :-
I want to display the data at 0,1,2...The data consist of information about different books.
This is what I have tried so far:-
private void getSelectedBooks() {
FirebaseRecyclerAdapter<BooksInfo, BooksViewHolder> adapter = new FirebaseRecyclerAdapter<BooksInfo, BooksViewHolder>(
BooksInfo.class,
R.layout.book_list,
BooksViewHolder.class,
nextOrder.child(String.valueOf(index))
) {
#Override
protected void populateViewHolder(BooksViewHolder viewHolder, final BooksInfo model, final int position) {
Log.d("BOOKDETAILS",model.getTitle());
// viewHolder.setTitle(model.getTitle());
// viewHolder.setISBN(model.getISBN());
// viewHolder.setDiscount(model.get());
// viewHolder.setQty(model.getQuantity());
// viewHolder.setPrice(model.getPrice());
// viewHolder.setGrossValue(model.get);
// viewHolder.setNetValue(model.get);
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DatabaseReference ref = getRef(position);
String key = ref.getKey();
Toast.makeText(AddOrderActivity.this, key, Toast.LENGTH_SHORT).show();
// getRetailerInfo(key);
}
});
}
};
selectedBookRecyclerView.setAdapter(adapter);
mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child(String.valueOf(index)).exists()) {
// run some code
// DisableProgress();
} else {
// DisableProgress();
// Toast.makeText(RetailerActivity.this, "No retailers to display", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Here DatabaseReference nextOrder = mDatabase.child(userId).child("order_details").child(String.valueOf(index));
Any help or suggestion is appreciated.Thank you.

CheckBox state inside RecyclerView

I created a Checkbox, however, whenever I click a few Items random checkboxes become clicked. I have a recycler view, and I have an adapter class as well. Here is my CheckBox method can anyone tell me the problem?
public void CheckBox(View view) {
final CheckBox checkBox = (CheckBox)view;
if (checkBox.isChecked()) {
System.out.println("SET TO CHECKED");
//Input instance of selected course(CHECKED)
// TODO: 2/5/16 Need to pass in Persisted ID
mVolleySingleton = VolleySingleton.getInstance();
mRequestQueue = mVolleySingleton.getRequestQueue();
CharSequence ID_PUT_COURSES = ((TextView) ((RelativeLayout) view.getParent()).getChildAt(1)).getText();
System.out.println(PUT);
String URL_PUT_COURSES = "URL"+ID_PUT+"\n";
System.out.print(PUT);
StringRequest UrlPut = new StringRequest(Request.Method.PUT, URL_PUT, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println(response + "reponse");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
System.out.println("************Answer" + error + "error");
}
});
mRequestQueue.add(UrlPutCourses);
System.out.println("Added");
}
else{
System.out.println("SET TO UNCHECKED");
//delete instance of selected course(UNCHECKED)
mVolleySingleton = VolleySingleton.getInstance();
mRequestQueue = mVolleySingleton.getRequestQueue();
// TODO: 2/5/16 Need to pass in Persisted ID
CharSequence DELETE = ((TextView) ((RelativeLayout) view.getParent()).getChildAt(1)).getText();
System.out.print(ID_PUT_COURSES);
String UR_DELETE = "URL"+ DELETE;
StringRequest UrlDeleteCourses = new StringRequest(Request.Method.DELETE, UR_DELETE, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println(response + "reponse");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
System.out.println("************Answer" + error + "error");
}
});
mRequestQueue.add(UR_DELETE);
System.out.println("Deleted");
}
}
ublic class AdapterSearch extends RecyclerView.Adapter<AdapterSearch.ViewSearch>{
private LayoutInflater mLayoutInflater;
private ArrayList<Search> ListSearch=new ArrayList<>();
public AdapterSearch(Context context){
mLayoutInflater=LayoutInflater.from(context);
}
public void setListSearch(ArrayList<Search> ListSearch){
this.ListSearch=ListSearch;
notifyItemRangeChanged(0,ListSearch.size());
}
#Override
public ViewSearch onCreateViewHolder(ViewGroup parent, int viewType) {
View view= mLayoutInflater.inflate(R.layout.custom_search,(ViewGroup)null);
ViewSearch holder=new ViewSearch(view);
return holder;
}
#Override
public void onBindViewHolder(ViewSearch holder, int position) {
Search currentSearch=ListSearch.get(position);
holder.mSearchText.setText(currentSearch.getMtitle());
holder.mAnswerPointsSearch.setText(currentSearch.getMkey());
holder.mSearchId.setText(currentSearch.getMid());
holder.mCourseId.setText(currentSearch.getCourseId());
}
#Override
public int getItemCount() {
return ListSearch.size();
}
public void setFilter(ArrayList<Search> Search) {
ListSearch = new ArrayList<>();
ListSearch.addAll(Search);
notifyDataSetChanged();
}
static class ViewSearch extends RecyclerView.ViewHolder{
private TextView mSearchText;
private TextView mAnswerPointsSearch;
private TextView mSearchId;
private TextView mCourseId;
public ViewSearch (View view){
super(view);
mSearchText=(TextView)itemView.findViewById(R.id.SearchText);
mAnswerPointsSearch=(TextView)itemView.findViewById(R.id.AnswerPointsSearch);
mSearchId=(TextView)itemView.findViewById(R.id.SearchId);
mCourseId=(TextView)itemView.findViewById(R.id.CourseTextView);
}
}
}
Better late then never I'd say, it might help other people stumbling upon this issue later, so here goes.
This might not be the best solution ever, but it should work.
In your Search class, you have some variables like title and key. Add the boolean isChecked to it, and make it false by default. Also create the matching getter and setter. (I'm using isChecked() & setChecked() in this example)
In your onBindViewHolder() method, add the following lines:
CheckBox checkBox = (CheckBox) itemView.findViewById(R.id.CheckBoxID);
// Instantiating the checkbox
holder.checkBox.setChecked(currentSearch.isChecked());
// Every time the holder (one list item) is shown, this gets called.
// It sets the checked state based on what's stored in currentSearch.
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (checkBox.isChecked()) {
currentSearch.setChecked(true)
} else {
currentSearch.setChecked(false);
}
});
}
// This listens for clicks on the checkbox, and changes the checked state of
// the boolean in currentSearch to the correct state based on
// what it already was on.
Please be aware that I haven't worked with checkboxes before, so some things (like setting the checked state) might be done slightly differently from what I've described above, but this should be a working base.
You also probably want the checkboxes to only persevere until you click a button or something like that, and then have them reset. You might want to add a simple for loop for that, something like:
public void resetAllCheckBoxes() {
for (Search s : ListSearch) {
s.setChecked(false);
}
}

Categories

Resources