Ali*_*Ali 102 android android-fragments android-recyclerview
我有一个RecyclerView,它从API加载一些数据,包括一个图像URL和一些数据,我使用networkImageView来延迟加载图像.
@Override
public void onResponse(List<Item> response) {
mItems.clear();
for (Item item : response) {
mItems.add(item);
}
mAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
Run Code Online (Sandbox Code Playgroud)
这是适配器的实现:
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
if (isHeader(position)) {
return;
}
// - get element from your dataset at this position
// - replace the contents of the view with that element
MyViewHolder holder = (MyViewHolder) viewHolder;
final Item item = mItems.get(position - 1); // Subtract 1 for header
holder.title.setText(item.getTitle());
holder.image.setImageUrl(item.getImg_url(), VolleyClient.getInstance(mCtx).getImageLoader());
holder.image.setErrorImageResId(android.R.drawable.ic_dialog_alert);
holder.origin.setText(item.getOrigin());
}
Run Code Online (Sandbox Code Playgroud)
问题是当我们在recyclerView中刷新时,它在开始时很短暂地看起来很奇怪.
我只使用了GridView/ListView,它按预期工作.没有瞎眼.
RecycleView的配置onViewCreated of my Fragment:
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
mGridLayoutManager = (GridLayoutManager) mRecyclerView.getLayoutManager();
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return mAdapter.isHeader(position) ? mGridLayoutManager.getSpanCount() : 1;
}
});
mRecyclerView.setAdapter(mAdapter);
Run Code Online (Sandbox Code Playgroud)
有人遇到过这样的问题吗?可能是什么原因?
小智 109
尝试在RecyclerView.Adapter中使用稳定的ID
setHasStableIds(true)和覆盖getItemId(int position).
如果没有稳定的ID,notifyDataSetChanged()ViewHolders通常会分配到不同的位置.这就是我案件中闪烁的原因.
Sab*_*med 97
根据这个问题页面....它是默认的recycleview项目更改动画...你可以关闭它..试试这个
recyclerView.getItemAnimator().setSupportsChangeAnimations(false);
Run Code Online (Sandbox Code Playgroud)
更新最新版本
请注意,此新API不向后兼容.如果您之前实现了ItemAnimator,则可以扩展SimpleItemAnimator,它通过包装新API来提供旧API.您还会注意到一些方法已从ItemAnimator中完全删除.例如,如果您正在调用recyclelerView.getItemAnimator().setSupportsChangeAnimations(false),则此代码将不再编译.您可以将其替换为:
Run Code Online (Sandbox Code Playgroud)ItemAnimator animator = recyclerView.getItemAnimator(); if (animator instanceof SimpleItemAnimator) { ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false); }
Ham*_*boh 39
这简单有效:
recyclerView.getItemAnimator().setChangeDuration(0);
Run Code Online (Sandbox Code Playgroud)
Wes*_*ely 10
我有一些问题从一些网址加载图像,然后imageView闪烁.通过使用解决
notifyItemRangeInserted()
Run Code Online (Sandbox Code Playgroud)
代替
notifyDataSetChanged()
Run Code Online (Sandbox Code Playgroud)
这避免了重新加载那些未更改的旧数据.
小智 9
尝试此操作以禁用默认动画
ItemAnimator animator = recyclerView.getItemAnimator();
if (animator instanceof SimpleItemAnimator) {
((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
}
Run Code Online (Sandbox Code Playgroud)
这是自Android支持23以来禁用动画的新方法
这种旧方法适用于旧版本的支持库
recyclerView.getItemAnimator().setSupportsChangeAnimations(false)
Run Code Online (Sandbox Code Playgroud)
科特林解决方案:
(recyclerViewIdFromXML.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
Run Code Online (Sandbox Code Playgroud)
Recyclerview 使用 DefaultItemAnimator 作为默认动画制作器。正如您从下面的代码中看到的,它们会在项目更改时更改视图持有者的 alpha:
@Override
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) {
...
final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView);
...
ViewCompat.setAlpha(oldHolder.itemView, prevAlpha);
if (newHolder != null) {
....
ViewCompat.setAlpha(newHolder.itemView, 0);
}
...
return true;
}
Run Code Online (Sandbox Code Playgroud)
我想保留其余的动画但删除“闪烁”,所以我克隆了 DefaultItemAnimator 并删除了上面的 3 条 alpha 线。
要使用新的动画师,只需在 RecyclerView 上调用 setItemAnimator():
mRecyclerView.setItemAnimator(new MyItemAnimator());
Run Code Online (Sandbox Code Playgroud)
在 Kotlin 中,您可以对 RecyclerView 使用“类扩展”:
fun RecyclerView.disableItemAnimator() {
(itemAnimator as? SimpleItemAnimator)?.supportsChangeAnimations = false
}
// sample of using in Activity:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// ...
myRecyclerView.disableItemAnimator()
// ...
}
Run Code Online (Sandbox Code Playgroud)
假设mItems是支持您的集合Adapter,为什么要删除所有内容并重新添加?您基本上是在告诉它一切都已更改,因此 RecyclerView 会重新绑定所有视图,而不是我假设图像库无法正确处理它,即使它是相同的图像 url,它仍然会重置视图。也许他们为 AdapterView 提供了一些解决方案,以便它在 GridView 中正常工作。
不要调用notifyDataSetChanged会导致重新绑定所有视图的调用,而是调用粒度通知事件(通知添加/删除/移动/更新),以便 RecyclerView 将仅重新绑定必要的视图,并且不会出现任何闪烁。
| 归档时间: |
|
| 查看次数: |
46910 次 |
| 最近记录: |