加快观点通胀

时间:2015-02-18 09:11:08

标签: android android-recyclerview

在我的应用中,我必须每天显示带有自定义布局的日历。为此,我使用了一个带有此布局管理器的RecyclerView:new GridLayoutManager(view.getContext(), 7)和一个自定义适配器。适配器必须在35到49个项目之间进行充气(一周中有7天,另外4到6行,每个月中有7个项目)。所有这些都需要1秒或更多,这太长了,因为它使应用程序滞后。我注意到延迟的原因在于使观点膨胀。对视图进行充气需要15到25毫秒,乘以+ -50视图就可以得到一秒钟。这是我用于在onCreateViewHolder中膨胀视图的代码,大约需要20毫秒:

View view = LayoutInflater.from(viewGroup.getContext()).inflate(this.itemLayout, viewGroup, false);

有什么方法可以加快速度吗?


修改

XML:

<android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView_monthEntries"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:overScrollMode="never"/>

片段:

    RecyclerView recyclerViewMonthEntries = (RecyclerView) view.findViewById(R.id.recyclerView_monthEntries);
    this.monthEntryAdapter = new CalendarMonthEntryAdapter(view.getContext(), calendar, null, R.layout.listitem_calendar_month_entry, R.layout.listitem_calendar_month_day, recommendedRowHeight);
    this.monthEntryAdapter.setListener(this);
    recyclerViewMonthEntries.setLayoutManager(new GridLayoutManager(view.getContext(), 7));
    recyclerViewMonthEntries.setAdapter(this.monthEntryAdapter);
    recyclerViewMonthEntries.setItemAnimator(new DefaultItemAnimator());

OnCreateViewHolder:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
{
    switch (viewType)
    {
        case TYPE_HEADER:
            View viewHeader = LayoutInflater.from(viewGroup.getContext()).inflate(this.headerLayout, viewGroup, false);
            return new DayOfWeekViewHolder(viewHeader);
        case TYPE_ENTRY:
            View viewEntry = LayoutInflater.from(viewGroup.getContext()).inflate(this.itemLayout, viewGroup, false);
            return new CalendarMonthEntryViewHolder(viewEntry);
        default:
            return null;
    }
}

OnBindViewHolder:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i)
{
    switch (this.getItemViewType(i))
    {
        case TYPE_HEADER:
            this.onBindHeaderViewHolder((DayOfWeekViewHolder) viewHolder, i);
            break;

        case TYPE_ENTRY:
            this.onBindEntryViewHolder((CalendarMonthEntryViewHolder) viewHolder, i - 7);
            break;
    }
}

绑定没什么特别的,只是一些setText和setVisibility。绑定大约需要1毫秒。我在膨胀之前和之后放了日志,这就是所有时间都消耗的东西。

2 个答案:

答案 0 :(得分:0)

我不知道你的代码,但我盲目地建议在线性布局中使用表适配器。

但要进一步发展:

你需要做出决定。加载后是否需要完全可用的自定义视图,或者您可以使用一些基本视图格式显示日历(对所有视图格式相同),然后根据需要进行自定义。这是一个设计和用户体验决策。

作为一种方法,你可以,

  1. 将日历作为包含表适配器的单个视图加载。
  2. 加载自定义视图onClick
  3. 在应用启动后使用自定义视图填充所有表格单元格。这是用户体验设计。您必须决定是否只是在准备好后立即加载并展示它们。或者展示一些自定义的“旋转”动画。或者将整个加载工作隐藏在动画演示效果中(以动画方式呈现日历,这将被视为UX增强)。

答案 1 :(得分:0)

我最后逐个添加我的项目。我从1开始计数,然后在onBindViewHolder结束时将计数加1:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i)
{
    //Normal code here

    new Handler().post(new Runnable()
    {
        @Override
        public void run()
        {
            if(currentCount < maxCount)
            {
                currentCount++;
                notifyItemInserted(currentCount - 1);
            }
        }
    });
}

我认为不是最佳解决方案,但它有效。这些项目一个接一个地弹出屏幕。