I have a Recycler view with GridLayoutManager attached. By Default, it will display ONE COLUMN and if user will click on button, it will displays in TWO COLUMN.
adapter = new ProductAdapter(getActivity(), productList);
gridLayoutManager = new GridLayoutManager(getActivity(), 1);
setLayoutManager(true);
below is function where i am changing columns
private void setLayoutManager(boolean isList) {
if (isList) {
adapter.VIEW_TYPE = 0 ;
gridLayoutManager.setSpanCount(1);
//product_recycler_view.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
product_recycler_view.setLayoutManager(gridLayoutManager);
} else {
adapter.VIEW_TYPE = 1 ;
gridLayoutManager.setSpanCount(2);
product_recycler_view.setLayoutManager(gridLayoutManager);
}
product_recycler_view.setAdapter(adapter);
adapter.notifyDataSetChanged();
// product_recycler_view.notify();
// product_recycler_view.notifyAll();
System.out.println("clicked isList "+ isList);
}
try this
private void setLayoutManager(boolean isList) {
if (isList) {
product_recycler_view.setLayoutManager(new LinearLayoutManager(this));
} else {
product_recycler_view.setLayoutManager(gridLayoutManager);
}
product_recycler_view.setAdapter(adapter);
adapter.notifyDataSetChanged();
// product_recycler_view.notify();
// product_recycler_view.notifyAll();
System.out.println("clicked isList "+ isList);
}
Related
I am using a Staggered Grid Layout to show data to recycler view from database.I have faced a problem where after deleting an item from db as well as remove position from adapter, I got some item rendering issues.Like the scattered all over the place.
Here is my code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note_favorite);
ButterKnife.bind(this);
toolbar = (Toolbar) findViewById(R.id.fav_note_toolbar);
setSupportActionBar(toolbar);
noteAdapter = new NoteAdapter(noteModelList, NoteFavoriteActivity.this);
layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(noteAdapter);
touchListenerRecycler();
loadDataAll();
}
private void loadAll() {
noteModelList.clear();
DBManagerFav dbManagerFav = DBManagerFav.getInstance(NoteFavoriteActivity.this);
dbManagerFav.openDataBase();
noteModelList = dbManagerFav.getAllNoteList();
Log.i(TAG, " size : " + noteModelList.size());
noteAdapter = new NoteAdapter(noteModelList, NoteFavoriteActivity.this);
recyclerView.setAdapter(noteAdapter);
noteAdapter.notifyDataSetChanged();
dbManagerFav.closeDataBase();
}
private void deleteOperation() {
DBManagerFav dbManagerFav = DBManagerFav.getInstance(NoteFavoriteActivity.this);
dbManagerFav.openDataBase();
NoteModel noteModel = new NoteModel();
noteModel.setId(noteModelList.get(adapterClickedPosition).getId());
int status = dbManagerFav.deleteNote(noteModelList.get(adapterClickedPosition).getId());
if (status > 0) {
noteAdapter.removeAt(adapterClickedPosition);
}
dbManagerFav.closeDataBase();
loadDataAll();
}
//this belongs to adapter
public void removeAt(int position) {
Log.d(TAG, " removing at position : " + position);
noteModelList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, noteModelList.size());
notifyDataSetChanged();
}
I have attached two screenshots before and after
Before deleting an item
after deleting an item
Can you point me out what else do I need ?
You can put inside loadDataAll(){
layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
//........
}
Voila..
I am setting up contact directory in section recyclerview with grid layout manager, what my problem is that header is also set as an item in the span if the span is empty.
I tried using the SpanSizeLookup method. It's not working as I expected.
layoutManager = new GridLayoutManager(getActivity(), 3);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
switch(adapterDocument.getItemViewType(position)){
case SectionedRecyclerViewAdapter.VIEW_TYPE_HEADER:
return 3;
case SectionedRecyclerViewAdapter.VIEW_TYPE_ITEM_LOADED:
return 1;
default:
return 1;
}
}
});
This is what I get
And this is what I really wants:
How to make header should be in next line with full width? Thank you.
there is something with your code, I changed the code in onCreateView from Example1 to:
sectionAdapter = new SectionedRecyclerViewAdapter();
for(char alphabet = 'A'; alphabet <= 'Z';alphabet++) {
List<String> contacts = getContactsWithLetter(alphabet);
if (alphabet == 'B' || alphabet == 'D') {
contacts = Collections.emptyList();
}
if (contacts.size() > 0) {
sectionAdapter.addSection(new ContactsSection(String.valueOf(alphabet), contacts));
}
}
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
GridLayoutManager glm = new GridLayoutManager(getContext(), 3);
glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
switch(sectionAdapter.getSectionItemViewType(position)) {
case SectionedRecyclerViewAdapter.VIEW_TYPE_HEADER:
return 3;
default:
return 1;
}
}
});
recyclerView.setLayoutManager(glm);
recyclerView.setAdapter(sectionAdapter);
and it's working fine, this is the result:
I have a recyclerview with FirebaseRecyclerAdapter and a spinner.
It show in activity a list of objects retrieve of firabase database.
My question is: Which better way for using filters in recycler view when user select a value in spinner? When selected a value in spinner below, nothing happens... Not update RecyclerView
exemple: When user select 'Brazil' in spinner, call a existent query like
query = databaseReference.child("People").orderByChild("country").equalTo("Brazil").getRef(); //I still dont know if this working.
query = databaseReference.child("People").getRef();
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
spinnerFilter = (Spinner) findViewById(R.id.spinFilter);
//--SPINNER EVENT SELECT--
AdapterView.OnItemSelectedListener selectedListener = new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> spinner, View container, int position, long id)
{
if(id == 0)
{
query = databaseReference.child("PeopleList").orderByChild("country").equalTo("Canada").getRef();
}else
if(id == 1)
{
query = databaseReference.child("PeopleList").orderByChild("country").equalTo("Brazil").getRef();
}else
if(id == 2)
{
query = databaseReference.child("PeopleList").orderByChild("country").equalTo("EUA").getRef();
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
query = databaseReference.child("PeopleList").getRef();
}
};
spinnerFilter.setOnItemSelectedListener(selectedListener);
//---RECYCLER VIEW----
if (mRecyclerView != null) {
mRecyclerView.setHasFixedSize(true);
}
gLayoutManager= new GridLayoutManager(this, 2);
mRecyclerView.setLayoutManager(gLayoutManager);
FirebaseRecyclerAdapter<People, PeopleListViewHolder> adapter = new FirebaseRecyclerAdapter<People, PeopleListViewHolder>
(
People.class,
R.layout.layout_people_item,
PeopleListViewHolder.class,
query
)
{
#Override
protected void populateViewHolder(PeopleListViewHolder viewHolder, People model, int position)
{
viewHolder.tvName.setText(model.getName());
Picasso.with(PeopleListActivity.this).load(model.getUrlThumbnail()).into(viewHolder.thumbnail);
}
};
mRecyclerView.setAdapter(adapter);
I check a lot links here but none success:
https://stackoverflow.com/questions/39076702/filtering-data-before-populating-view-from-firebaserecycleradapter?rq=1
https://github.com/firebase/FirebaseUI-Android/issues/15
https://groups.google.com/forum/#!topic/firebase-talk/O1kJ4VLUg10
https://github.com/firebase/FirebaseUI-Android/issues/15
Thanks very much if can help me.
I have a RecyclerView list of CardViews. New CardViews are inserted at the top of the list.
If the View is currently at the bottom of the CardView list and I click my "Add" button to create a new CardView, I want the RecyclerView to then show the new CardView at the top of the list. Currently, when the new CardView is created the RecyclerView just returns to the previous View at the bottom of the list.
I've tried many things, without any luck, including:
recyclerView.getLayoutManager().scrollToPosition(0);
recyclerView.scrollToPosition(0);
linearlayoutmanager.scrollToPositionWithOffset(0,0)
Adapter.java
public void add(Contact item) {
if (contactList.size()==0) {
contactList.clear();
notifyDataSetChanged();
}
contactList.add(item);
notifyItemInserted(0);
}
public void addAll(List<Contact> contactList) {
for (Contact contact : contactList) {
add(contact);
}
}
Activity.java
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EmptyRecyclerView recyclerView = (EmptyRecyclerView)findViewById(R.id.list_recyclerview);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setEmptyView(findViewById(R.id.empty_view));
contactListAdapter = new ContactListAdapter(this);
contactListAdapter.setOnItemClickListener(this);
recyclerView.setAdapter(contactListAdapter);
#Override
protected void onStart() {
super.onStart();
loadData();
}
void loadData(){
List<Contact> contactList = new ArrayList<>();
Cursor cursor = sqLiteDB.retrieve();
Contact contact;
try {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
do {
contact = new Contact();
contact.setI(cursor.getInt(0));
contact.setC(cursor.getInt(1));
contact.setT(cursor.getString(2));
contact.setN1(cursor.getString(3));
contact.setN2(cursor.getString(4));
contact.setD(cursor.getString(5));
contact.setDt(cursor.getString(6));
contact.setTm(cursor.getLong(7));
// add the item to the top of the List.
contactList.add(0, contact);
} while (cursor.moveToNext());
}
}
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
contactListAdapter.clear();
contactListAdapter.addAll(contactList);
do like this
recyclerview.post(new Runnable() {
#Override
public void run() {
LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
layoutManager.scrollToPositionWithOffset(0, 0);
}
});
if this does not work check where are you calling this and control executes this statement or not.
I use this with a "scroll to top" button, you can try work your way around with it :
LinearLayoutManager mlayoutManager = (LinearLayoutManager) rv.getLayoutManager();
mlayoutManager.scrollToPositionWithOffset(0, 0);
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.