RecyclerView, GridLayoutManager and dynamic span
I ran into a strange error with recyclerview
. I am setting and resizing dynamically dynamically to match the information loaded from AsyncTask.
Sometimes it does not display correctly. It seems to be showing up on the screen.!
Then after one or more reboots, it displays correctly. It seems to come out of the screen, but I can't figure out why.
Here is my adapter:
public class ScheduleAdapter extends RecyclerView.Adapter<ScheduleAdapter.ViewHolder> {
private List<Schedule> mDataset;
/**
* First parameter is the position in the dataset
* The value returned is the number of schedules to display
*/
private TreeMap<Integer, Integer> schedulesToDisplay;
private int maxSpans;
private static final String TAG="LINE_ADATER";
// Provide a suitable constructor (depends on the kind of dataset)
public ScheduleAdapter() {
mDataset = new ArrayList<Schedule>();
schedulesToDisplay = new TreeMap<Integer, Integer>();
}
// Create new views (invoked by the layout manager)
@Override
public ScheduleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_schedule, parent, false);
// set the view size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder((LinearLayout) v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
Log.d(""+position, "BINDVIEW");
holder.setItem(mDataset.get(position));
Schedule s = mDataset.get(position);
holder.time.setText(s.toString());
}
public void add(Schedule item) {
Integer nbHour = schedulesToDisplay.get(item.hour);
int position = mDataset.size();
if(nbHour == null){
schedulesToDisplay.put(item.hour, 1);
Log.d(item.toString()+" : 1 span ("+position+")", TAG);
}
else{
nbHour++;
schedulesToDisplay.put(item.hour, nbHour);
Log.d(item.toString()+ " : " + nbHour +" spans ("+position+")", TAG);
if(nbHour > maxSpans){
maxSpans = nbHour;
}
}
mDataset.add(position, item);
notifyItemInserted(position);
}
public List<Schedule> getDataSet(){
return mDataset;
}
public int getSchedulesToDisplay(int position, GridLayoutManager layoutManager){
Integer nbHour = schedulesToDisplay.get(mDataset.get(position).hour);
if(nbHour==null){
return 0;
}
int nbHourInt = nbHour.intValue();
if( maxSpans%nbHourInt != 0){ // Si la nouvelle ligne n'est pas un multiple de la précédente
maxSpans = (maxSpans*nbHourInt)/ MathsUtils.pgcd(maxSpans, nbHourInt);
Log.d("New Max Span "+maxSpans, TAG);
}
layoutManager.setSpanCount(maxSpans);
layoutManager.requestLayout();
layoutManager.getSpanSizeLookup().invalidateSpanIndexCache();
Log.d("Span count "+layoutManager.getSpanCount(), TAG);
Log.d("Heure "+mDataset.get(position).hour+" ("+nbHourInt+") : "+(maxSpans/nbHourInt)+" spans", TAG+" SPAN");
return (maxSpans/nbHourInt);
}
public void removeAll() {
mDataset.clear();
schedulesToDisplay.clear();
maxSpans = 1;
notifyDataSetChanged();
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
// each data item is just a string in this case
TextView time;
Schedule scheduleItem;
public ViewHolder(LinearLayout lyt_main) {
super(lyt_main);
time = (TextView) lyt_main.findViewById(R.id.time);
}
public void setItem(Schedule item) {
scheduleItem = item;
}
}
}
The removeAll () method is called every time before loading new data from the object.
+2
source to share
1 answer
I actually solved the problem. I noticed that the setSpanSizeLookup method was only called after notifyItemInserted. I have to put the resize method after.
public void add(Schedule item) {
Integer nbHour = schedulesToDisplay.get(item.hour);
int position = mDataset.size();
if(nbHour == null){
schedulesToDisplay.put(item.hour, 1);
Log.d(item.toString()+" : 1 span ("+position+")", TAG);
}
else{
nbHour++;
schedulesToDisplay.put(item.hour, nbHour);
Log.d(item.toString()+ " : " + nbHour +" spans ("+position+")", TAG);
if(nbHour > maxSpans){
maxSpans = nbHour;
}
}
mDataset.add(position, item);
notifyItemInserted(position);
layoutManager.setSpanCount(maxSpans);
layoutManager.requestLayout();
}
+1
source to share