RecyclerView,GridLayoutManager和动态计数跨度 [英] RecyclerView, GridLayoutManager and dynamic Spans count

查看:338
本文介绍了RecyclerView,GridLayoutManager和动态计数跨度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的 recyclerview 一个奇怪的错误。我设置和动态调整跨度,以适应从一个的AsyncTask下载的信息。

I encountered a strange bug with the recyclerview. I set and resize spans dynamically to fit with the informations downloaded from an AsyncTask.

有时不能正常显示。现在看来似乎显示在屏幕上。!

Sometimes it doesn't display properly. It seems like it displays over the screen.!

在这里输入的形象描述

在这里输入的形象描述

再经过一个或多个重载它显示正确。
这似乎走出屏幕,但我想不出为什么。

Then after one or more reload it displays correctly. It seems to go out the screen but I can't figure out why.

这是我的适配器:

   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()从活动调用

Every time before downloading new data, the method removeAll() is called from the activity.

推荐答案

其实我解决了这个问题。我注意到setSpanSizeLookup方法只notifyItemInserted后调用。我之后把我的尺寸调整方法。

Actually I solved the problem. I noticed the setSpanSizeLookup method was called only after notifyItemInserted. I have to put my resizes 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();
}

这篇关于RecyclerView,GridLayoutManager和动态计数跨度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆