如何让 RecyclerView 更新其布局?

Posted

技术标签:

【中文标题】如何让 RecyclerView 更新其布局?【英文标题】:How do I make RecyclerView update its layout? 【发布时间】:2014-10-08 00:50:45 【问题描述】:

我有一个RecyclerView 有一堆自定义视图,它们可能会在一段时间后改变高度,因为它们包含异步加载图像的ImageViews。尽管我在ImageView 上调用了forceLayoutRecyclerView 并用setHasFixedSize(false) 初始化,但RecyclerView 并没有反映此布局更改。 ImageView 的所有容器父级都设置了android:layout_height="wrap_content"

如何使RecyclerView 更新其布局?使用 good'ol ListView 这不是问题。

【问题讨论】:

如何加载图像数据?是从Loader<D> 异步加载吗?来自AsyncTask?数据是否保存在Cursor 中?我想了解您是如何维护数据状态的。 我类似于具有回调 (github.com/koush/ion) 的 AsyncTask。在回调中,我尝试调用 forceLayout 把你的代码带到这里。如何将适配器设置为 RecyclerView 以及通知DataSetChanged() 的位置和线程。 我对 23.1.0 支持 lib 版本有同样的问题。我刚刚在回收站视图上设置了一个新的布局管理器。 【参考方案1】:

如果您的所有图像同时更改,您可以使用Adapter 中的notifyDataSetChangedRecyclerView,如果只有其中一项更改,则可以使用notifyItemChanged(int position)。这将告诉RecyclerView 重新绑定特定的View

【讨论】:

注意这个问题,因为当前调用 notifyDataSetChanged 可能会抛出异常。 code.google.com/p/android/issues/detail?id=77846 这将更新整个回收站视图。如果它在平板电脑上用图像占用了整个屏幕,这将导致严重的性能问题,用户会注意到这一点。当只有一小部分布局发生变化时,您应该避免更新整个 recyclerview。【参考方案2】:

Google 终于在 support library v23.2 中解决了这个问题。在使用 SDK 管理器更新您的支持存储库后,通过更新 build.gradle 中的这一行来解决问题:

compile 'com.android.support:recyclerview-v7:23.2.0'

【讨论】:

嘿@Nilzor 可以帮我解决这个问题***.com/questions/49952965/…【参考方案3】:

主线程调用RecyclerView.AdapternotifyDataSetChanged()notifyItemChanged(int position)方法。从AsyncTask 调用它可能会导致主线程不更新ImageViews。最方便的是在activity/fragment中有一个回调方法作为监听器,并由onPostExecute()中的AsyncTask调用

【讨论】:

【参考方案4】:
int wantedPosition = 25; // Whatever position you're looking for
int firstPosition = linearLayoutManager.findFirstVisibleItemPosition(); // This is the same as child #0
int wantedChild = wantedPosition - firstPosition;

if (wantedChild < 0 || wantedChild >= linearLayoutManager.getChildCount()) 
    Log.w(TAG, "Unable to get view for desired position, because it's not being displayed on screen.");
    return;


View wantedView = linearLayoutManager.getChildAt(wantedChild);
mlayoutOver =(LinearLayout)wantedView.findViewById(R.id.layout_over);
mlayoutPopup = (LinearLayout)wantedView.findViewById(R.id.layout_popup);

mlayoutOver.setVisibility(View.INVISIBLE);
mlayoutPopup.setVisibility(View.VISIBLE);

这段代码对我有用。

【讨论】:

这不适用于列表底部的孩子。【参考方案5】:

我遇到了同样的问题,我只是为 ImageView 设置了一个固定的宽度和高度。试试看,看看你在哪里。你也可以为此使用一个库,我使用 Square Picasso,并让它与 RecyclerView 一起使用。

【讨论】:

固定和高度不是一个选项。设计要求高度由图片高度决定。

以上是关于如何让 RecyclerView 更新其布局?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 UIStackView 更新其布局?

如何根据其在 onCreateViewHolder 方法中的位置在 RecyclerView 中膨胀不同的布局

如何让 RecyclerView 平滑滚动?

又来一个库,WebView,RecyclerView 多布局连贯滑动

Tab + Swipe+ RecyclerView + Collapsed

android RecyclerView的Grid布局案例