我在recyclerview
遇到了一个奇怪的错误。我动态设置和调整跨度以适应从AsyncTask下载的信息。
有时它无法正常显示。它似乎显示在屏幕上。!
然后在重新加载一次或多次后,它会正确显示。 它似乎走出了屏幕,但我无法弄清楚原因。
这是我的适配器:
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's 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;
}
}
}
每次下载新数据之前,都会从活动中调用removeAll()方法。
答案 0 :(得分:1)
其实我解决了这个问题。我注意到只在notifyItemInserted之后调用了setSpanSizeLookup方法。我必须把调整大小的方法放在。
之后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();
}