I want to do a RESET button. I already successfully do for Spinner and Seekbar but failed to do for RecyclerView which is my filtering result. There is no error, but as you can see in my output interface, ONLY the recyclerView did not empty...
My coding:-
resetButton.setOnClickListener(new View.OnClickListener() {
final MediaPlayer mediaPlayer = MediaPlayer.create(FilterTuitionCentre.this, R.raw.soundeffect1);
#Override
public void onClick(View v) {
mediaPlayer.start();
spLocation.setSelection(0);
seekbarPrice.setProgress(0);
spAcademicLevel.setSelection(0);
spSubject.setSelection(0);
recyclerView.invalidate();
}
});
My interface output:-
My adapter coding:-
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(mAdapter);
I assume that you have following initialization for your recyclerView :
YourAdapter adapter = new YourAdapter(items);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
To clear items(Empty) RecyclerView you need to :
items.clear();
adapter.notifyDataSetChanged();
Related
I want to make a custom insert animation in RecyclerView when adding items. This is what I got so far:
private void init(View view, Context context) {
recyclerView = view.findViewById(R.id.messagesList);
layoutManager = new LinearLayoutManager(context);
layoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
recyclerView.setItemAnimator(new DefaultItemAnimator() {
#Override
public boolean animateAdd(RecyclerView.ViewHolder holder) {
holder.itemView.setScaleY(0);
holder.itemView.animate().scaleY(1).setDuration(3000).start();
return super.animateAdd(holder);
}
});
}
private void onNewItem(Item item){
adapter.onNewItem(item);
layoutManager.smoothScrollToPosition(recyclerView, null, adapter.getItemCount());
}
Then in the adapter
private void onNewItem(Item item){
items.addItem(item);
notifyItemInserted(items.size());
}
The item just appears when it's added, there is no scroll nor custom animation.
Replacing smoothScrollToPosition with scrollToPosition solved the problem.
Also I had a bug calling to notifyItemInserted(items.size()); instead of notifyItemInserted(items.size() - 1);
Actually, I make a 1st query which returns a number of objects.
As we could with a standard recyclerView, I would like to filter dynamically these objects with an EditText after the view is created, and update the view dynamically.
For example, if my first query returns and displays 10 objects, the user will be able to search one objet through the 10 objects by making a request with an EditText. The view will display only this object.
Query query = collectionRef.whereArrayContains("customerNearMe", getCurrentUser().getUid());
private void sendToAdapter(Query query) {
FirestoreRecyclerOptions<Restaurant> options = new FirestoreRecyclerOptions.Builder<Restaurant>()
.setQuery(query, Restaurant.class)
.build();
adapter = new RestaurantAdapter(options);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
recyclerView.addItemDecoration(new SimpleItemDecorator(getContext()));
adapter.notifyDataSetChanged();
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onDestroy() {
super.onDestroy();
adapter.stopListening();
}
Actually, I know how to do it with a simple RecyclerView
private void filter(String text) {
ArrayList<ExampleItem> filteredList = new ArrayList<>();
for (ExampleItem item : mExampleList) {
if (item.getText1().toLowerCase().contains(text.toLowerCase())) {
filteredList.add(item);
}
}
mAdapter.filterList(filteredList);
}
but I am a newbie with Firestore.
Just trying to show in a RecyclerView the info from my database.
everything works fine. The objects are displayed.
but logcat says:
E/RecyclerView: No adapter attached; skipping layout
This is my the code (DisplayImages.java)
public class DisplayImages extends AppCompatActivity {
DatabaseReference databaseReference;
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
ProgressDialog progressDialog;
List<ImageUploadInfo> list = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_images);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(DisplayImages.this));
progressDialog = new ProgressDialog(DisplayImages.this);
progressDialog.setMessage("Loading Images From Firebase.");
progressDialog.show();
// Setting up Firebase image upload folder path in databaseReference.
// The path is already defined in MainActivity.
databaseReference = FirebaseDatabase.getInstance().getReference(Main.Database_Path);
databaseReference.addValueEventListener(new ValueEventListener() {
#override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
ImageUploadInfo imageUploadInfo = postSnapshot.getValue(ImageUploadInfo.class);
list.add(imageUploadInfo);
}
adapter = new RecyclerViewAdapter(getApplicationContext(), list);
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
And If it makes any difference, this is what i wrote in MainActivity about the DataBase_Path :
public class Main extends AppCompatActivity implements View.OnClickListener {
DatabaseReference databaseReference;
public static final String Database_Path = "All_Image_Uploads_Database";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseReference = FirebaseDatabase.getInstance().getReference(Database_Path);
As you can see I have attached an adapter for Recycleview. so why do I keep getting this error?
i have read other questions related to same problem but none helps.
Yyou need to set the adapter after you set the layour manager, otherwise you'll get the error message you're seeing.
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
//don't set adapter here
recyclerView.setLayoutManager(new LinearLayoutManager(DisplayImages.this));
//set adapter here
Moreover, you can set the adapter with an empty list first and then when you receive the callback from firebase you can update the list and call notifyDatasetChanged() on the adapter. The problem you see is due to the fact that you're not actually setting the adapter until very later in the process (when your firebase call comes back)
Like this:
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(DisplayImages.this));
adapter = new RecyclerViewAdapter(getApplicationContext(), list);
recyclerView.setAdapter(adapter);
databaseReference.addValueEventListener(new ValueEventListener() {
#override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
ImageUploadInfo imageUploadInfo = postSnapshot.getValue(ImageUploadInfo.class);
list.add(imageUploadInfo);
}
adapter.notifyDatasetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
I don't see anywhere you are creating an adapter and setting that adapter to RecyclerView. You need to create an adapter and set adapter like following:
mAppAdapter = new AppAdapter(mModel); // or whatever constructor you want
recyclerView.setAdapter(mAppAdapter);
EDIT:
You are setting adapter to RecyclerView inside an asynchronous method. So your program will have a non deterministinc amount of time where the adapter is not actually set to recyclerView. To get rid off the warning you get you should initialize and set the adapter above the async method and only update data of the adapter inside the async method
I have a RecyclerView with a LinearLayoutManager that is backed by an adapter with items of different height. Is there a way to tell the RecyclerView to set the scroll position so that item X appears (more or less) exactly at the bottom of the screen?
I tried LinearLayoutManager.scrollToPosition() but this will position the item at the top of the view.
MyAdapter mAdapter;
RecyclerView recyclerView;
List<ItemData> data = new ArrayList<>();
LinearLayoutManager llm = new LinearLayoutManager(this);
try this in OnCreate method
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(llm);
llm.setStackFromEnd(true);
mAdapter = new MyAdapter(data, getApplication());
recyclerView.setAdapter(mAdapter);
and when you insert an item try this
mAdapter.notifyItemInserted(data.size() - 1);
llm.scrollToPosition(data.size() - 1);
Try this in mainActivity.class
rv_journey.setAdapter(ca);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
scrollList();
}
}, 500);
Here is my scroll Method
private void scrollList(){
rv_journey.post(new Runnable() {
#Override
public void run() {
// Call smooth scroll
rv_journey.smoothScrollToPosition(Index);
}
});
}
Set index from Adapter class which extend RecyclerView.Adapter Where You need to scroll...
if (Condition) {
mainActivity.Index=position+1;
}
}
Happy Coding...
Am I using RecyclerView correctly? Whenever I update the data, the is one moment in which the view still displays the old data, despite having modified the dataset and having called the relevant notify method. On top of that, I don't see any animations, so I must be doing something wrong.
Here is the relevant snippet of code:
private void refreshData() {
Utils.hideSoftKeyboard(this);
if (!Utils.isOnline(getApplicationContext())) {
Toast.makeText(getApplicationContext(), R.string.toast_no_conn, Toast.LENGTH_SHORT).show();
return;
}
String stopNumber = mStopEdit.getText().toString();
if (stopNumber.isEmpty()) {
Toast.makeText(getApplicationContext(), R.string.toast_no_stop, Toast.LENGTH_SHORT).show();
return;
}
mResultNoStop.setVisibility(View.GONE);
mResults.setVisibility(View.GONE);
mProgressCircle.setVisibility(View.VISIBLE);
if (!mDataset.isEmpty()) {
int size = mDataset.size();
mDataset.clear();
mAdapter.notifyItemRangeRemoved(0, size);
}
FiveT.getStopData(stopNumber, mRequestQueue, new FiveT.StopDataClientListener() {
#Override
public void onResponse(ApiResult result) {
mProgressCircle.setVisibility(View.GONE);
if (result.getStopResults().size() == 0) {
mResultNoStop.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), R.string.toast_no_data, Toast.LENGTH_SHORT).show();
return;
}
int i = 0;
mStopName.setText(result.getStopName());
for (StopResult res : result.getStopResults()) {
mDataset.add(res);
mAdapter.notifyItemInserted(i++);
}
mResults.setVisibility(View.VISIBLE);
}
});
}
EDIT: I initialize the RecyclerView like this:
mDataset = new ArrayList<StopResult>();
mRecyclerView = (RecyclerView) findViewById(R.id.results_recycler_view);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new RecyclerViewAdapter(mDataset, getApplicationContext());
mRecyclerView.setAdapter(mAdapter);
Based on the question's comments:
What you're missing there, in RecyclerView's initialisation, is the set of a item animator.
According to your code:
mDataset = new ArrayList<StopResult>();
mRecyclerView = (RecyclerView) findViewById(R.id.results_recycler_view);
mRecyclerView.setItemAnimator(new MyItemAnimator());
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new RecyclerViewAdapter(mDataset, getApplicationContext());
mRecyclerView.setAdapter(mAdapter);
You can refer to this library in order to find an animation that it is best for your needs.