【问题标题】:updating recyclerView in onResume ();更新 onResume() 中的 recyclerView;
【发布时间】:2018-02-14 01:20:54
【问题描述】:

我在 onResume 方法中从 recyclerView “重新创建”适配器时遇到了一些问题。 基本上,这是我的方案。

MainActivit  -ViewPager
   - fragment A (has a recyclerView)
   - fragment B (nop)
   - fragment C (nop)
   - fragment D (it has the same recyclerView as the framgnet A)

onResume 我一直呼吁

> myCustomAdapter adapter = new myCustomAdapter (
> mListItems,getContext(),ParseUser.getCurrentUser().getObjectId(),
> "type");
>                recyclerView.setAdapter(adapter);

但这会导致一些问题,例如当我从另一个活动返回 MainActivity 时。例如。

Activityt A
 - click on item in recylerView
 - start Activity B

Activity B
user does some actions, sees some news, and returns to Activity A.

Activity A
recreates the adapter and set recyclerView.setAdapter (new Adapter);
this is slow, causes a delay of 2 seconds after onBackPressed is pressed in Activity B.

我还有一个 setMenuVisibility 方法,它也与 onResume 做同样的事情,因为如片段 D 中所述,我在片段 A 中有 recyclerView,所以如果用户在 recyclerView 中进行了一些更改即在片段 D 中,当用户返回片段 A 时,我需要更新片段 A 的 recyclerView。

为什么 Fragment D 中的 recyclerView 在 Fragment A 中?

我们可以考虑以下内容,在片段 A 中,我有一个仅包含“用户兴趣”的 recyclerView,在片段 D 中,我有用户信息,例如用户名、照片等......还有“用户兴趣”。

结论:问题是当我从Activity B返回到Activity A时,当我在viewPager中在fragment A和fragment D之间交替时,这会导致重新创建适配器的延迟.

在这种情况下我该怎么办?

我为这糟糕的英语道歉,我正在使用谷歌翻译。

【问题讨论】:

  • 您是否在 RecyclerView 项目中加载图像?
  • 我是,而且可能方式不对。我需要在 recyclerView 的每一行中添加 8 个不同图像的 ImageView。
  • 图片加载导致卡顿,请使用 Glide 或 Picasso 等图片加载库
  • 我刚刚删除了添加 ImageViews 的代码,这确实“解决了”问题,但我真的需要 ImageViews。我已经用毕加索了。目前我正在添加 imageViews,如下所示。 holder.ContainerImageViews.addView (imageView);删除这段代码后,延迟就停止了,你认为如果我在xml中添加8个imageView,会不会对性能产生影响?或者同样的延迟会继续吗?每个 imageView 的大小为 45dp / 45dp

标签: android performance android-recyclerview


【解决方案1】:

这是一个Scope Problem。您需要在某个类成员中定义adapter

  1. 如果您希望 Fragment A 和 Fragment D 中呈现的数据不同,则将 adapter 设为彼此的成员,并在每个 Fragment.onCreate() 中初始化它。所以它不会重新创建适配器。 (确保 ViewPager 有足够的缓存数量,否则它仍然会重新创建整个非缓存的 Fragment)

  2. 如果您希望 FragmentA 和 FragmentD 显示相同的数据或相同数据的一部分,请在 MainActivity.onCreate 中创建 adapter,并将其作为参数传递给 FragmentA、FragmentD。

不需要每次onResume 都重新创建adapter,因为这确实是一项繁重的工作。无需更改任何视图层属性。确保您要共享的数据(适配器)在同一范围内或可以传递给它。

例如:

//MainActivity
private Adapter adapter;

void onCreate(Bundle savedInstanceState){
    //...other stuff
    adapter = new myCustomAdapter (mListItems,getContext(),ParseUser.getCurrentUser().getObjectId(), "type");
}
public Adapter getAdapter(){ return adapter;}


//FragmentA or FragmentD
void onCreateView(){
    MainActivity activity = (MainActivity) getActivity(); //This fragment should be created with `MainActivity`
    recyclerView.setAdapter(activity.getAdapter());
}

【讨论】:

  • 您好,谢谢。这向我澄清了一些事情,你能给我提供一个示例代码来在片段之间共享适配器吗?我应该如何将此活动数据传递给片段?原谅我和我的傲慢,我是 android 编程的初学者。
  • 你好,这真的有效,但问题仍然存在,如何“通知”适配器的变化?我尝试使用 adapter.notifySetDataChange ();但这不会改变recyclerView中的适配器数据,如何解决?谢谢!
  • 你在哪里更改数据集(list.add()),它必须在主线程中,recyclerview 将自行填充。如果在后台线程中更改,则 notifySetDataChange 应该在 activity.post(runnable) 块中
【解决方案2】:

在处理大图或多张小图时,不要使用ImageView的“src”属性设置set image 使用像 Glide 或 Picasso 这样的图像加载库。 以下 sn-p 适用于 Glide v4

Glide.with(context).load(<url_or_res_id>).into(imageView)

您可以将 url 作为字符串传递。或者如果你从drawable加载图像,你可以传递它的资源id(例如R.drawable.image_id)

【讨论】:

  • 我正在使用:Picasso.with(context).load(url).into(img_profilePicture);请查看我的评论并告诉我您对 holder.ContainerView.addView (img_profilePicture) 的看法;
  • 你没有使用recyclerview的回收能力。不要使用 addView,而是从数组列表中加载每个视图,并在将项目添加到列表后调用 adapter.notifyDatasetChanged()。 Recyclerview 将管理其余部分
  • 所以,你建议我在 xml 中添加 8 个 imageViews,将它们保留为 Gone,然后只需 setVisible (View.Visible);必要时?
  • 不,让它们可见,只需删除 xml 中的 src 属性。创建 8 个 ImageView 变量并使用一个库将图像加载到每个图像视图中。 (据我了解,每个列表项中有 8 个 imageView)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
相关资源
最近更新 更多