草庐IT

android - 具有多 View 滞后滚动的嵌套 RecyclerView

coder 2023-11-20 原文

我有一个带有多个 View 的 recyclerView,其中每一行都是一个 recyclerView。当我滚动 recyclerView 时,创建的每一行都滞后。这是我的一些代码。在下面你可以看到主要 recyclerView 的配置:

LinearLayoutManager mLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
    mRvPromotions.setLayoutManager(mLayoutManager);
    mRvPromotions.setItemViewCacheSize(20);
    mRvPromotions.setDrawingCacheEnabled(true);
    mRvPromotions.setHasFixedSize(true);
    mRvPromotions.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    mRvPromotions.setAdapter(adapter);

你可以在下面看到绑定(bind)在适配器中的内部 recyclerView 代码:

mRvPromotion.setLayoutManager(new GridLayoutManager(itemView.getContext(), 3));
    mRvPromotion.setItemViewCacheSize(20);
    mRvPromotion.setDrawingCacheEnabled(true);
    mRvPromotion.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    adapter = new PlaylistPromotionsRVAdapter(new PlaylistModelCallBack(), new PlaylistPromotionVHFactory());
    mRvPromotion.setAdapter(adapter);
    adapter.submitList(getVM().getPlaylist());

我使用 mRvPromotion.setNestedScrollingEnabled(false);ViewCompat.setNestedScrollingEnabled(childRecyclerView, false); 但存在滞后行为钢。 对于加载图像,我使用了 Fresco 并调整了它的大小配置。 如何防止滚动滞后?

编辑

这是我的适配器:

public class PlaylistRVAdapter extends ListAdapter<PlayListPromotionAndSlider, BaseViewHolder> {

private final PlaylistPageVHFactory mFactory;
private final PublishSubject<PlaylistSliderVHAction> mClickSliderPS = PublishSubject.create();
private final PublishSubject<PlaylistPromotionsVHAction> mClickPromotionPS = PublishSubject.create();

@Inject
PlaylistRVAdapter(@NonNull PlaylistPromotionModelCallBack diffCallback, PlaylistPageVHFactory factory) {
    super(diffCallback);
    mFactory = factory;
}

@NonNull
@Override
public BaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    return mFactory.create(parent, viewType);
}

@Override
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
    switch (getItemViewType(position)) {
        case 0:
            PlaylistSliderVH sliderVH = (PlaylistSliderVH) holder;
            sliderVH.getVM().setObject(getItem(position).getSlide());
            sliderVH.bind();
            sliderVH.itemOnClick(mClickSliderPS);
            break;
        case 1:
            PlaylistPromotionsVH promotionsVH = (PlaylistPromotionsVH) holder;
            promotionsVH.getVM().setObject(getItem(position).getPromotion());
            promotionsVH.bind();
            promotionsVH.itemOnClick(mClickPromotionPS);
            break;
    }
}

public Observable<PlaylistSliderVHAction> getClickPS() {
    return mClickSliderPS;
}

public PublishSubject<PlaylistPromotionsVHAction> getmClickPromotionPS() {
    return mClickPromotionPS;
}

@Override
public int getItemViewType(int position) {
    return getItem(position).getSlide() != null ? 0 : 1;
}

例如我的 viewHolder PlaylistPromotionsVH 如下所示:

public class PlaylistPromotionsVH extends BaseViewHolder<PlaylistPromotionsVHAction, PlaylistMasterModel, PlaylistPromotionsVM> {

@BindView(R.id.txtPromotionTitle)
AppCompatTextView mTxtPromotionTitle;
@BindView(R.id.txtMore)
AppCompatTextView mTxtMore;
@BindView(R.id.rvPromotion)
RecyclerView mRvPromotion;

PlaylistPromotionsRVAdapter adapter;

public PlaylistPromotionsVH(View itemView, PlaylistPromotionsVM viewModel) {
    super(itemView, viewModel);
    ButterKnife.bind(this, itemView);
}

@Override
public void bind() {
    mTxtPromotionTitle.setText(mVM.getPlaylistName());
    mRvPromotion.setLayoutManager(new GridLayoutManager(itemView.getContext(), 3));
    mRvPromotion.setItemViewCacheSize(20);
    mRvPromotion.setDrawingCacheEnabled(true);
    mRvPromotion.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    mRvPromotion.setHasFixedSize(true);
    int spacing = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12,
            itemView.getContext().getResources().getDisplayMetrics());
    mRvPromotion.addItemDecoration(new RecyclerView.ItemDecoration() {
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
            int position = parent.getChildAdapterPosition(view); // item position
            int spanCount = 3;
            if (position >= 0) {
                int column = position % spanCount; // item column

                outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
                outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

                if (position < spanCount) { // top edge
                    outRect.top = spacing;
                }
                outRect.bottom = spacing; // item bottom
            } else {
                outRect.left = 0;
                outRect.right = 0;
                outRect.top = 0;
                outRect.bottom = 0;
            }
        }
    });

    adapter = new PlaylistPromotionsRVAdapter(new PlaylistModelCallBack(), new PlaylistPromotionVHFactory());
    mRvPromotion.setAdapter(adapter);

    adapter.submitList(getVM().getPlaylist());
}

@Override
public void itemOnClick(PublishSubject<PlaylistPromotionsVHAction> actionSubject) {
    RxView.clicks(mTxtMore)
            .map(o -> new PlaylistPromotionsVHAction(getAdapterPosition()))
            .repeat()
            .subscribe(actionSubject);
}

在下面你可以看到主recyclerView每一行的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:background="@color/colorPromotionBackground"
android:descendantFocusability="blocksDescendants"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<RelativeLayout
    android:id="@+id/rlPromotionTitle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/txtPromotionTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="16dp"
        android:layout_toRightOf="@+id/txtMore"
        android:gravity="right"
        android:textColor="@android:color/white"
        tools:ignore="RtlHardcoded" />

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/txtMore"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:background="@drawable/ic_see_more" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
    android:id="@+id/rvPromotion"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/rlPromotionTitle"
    android:focusableInTouchMode="true"
    android:overScrollMode="never"
    android:scrollbars="none"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</RelativeLayout>

更新

这是我用 fresco 加载图片的代码:

ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
            .setResizeOptions(new ResizeOptions(width, height))
            .build();
    simpleDraweeView.setController(
            Fresco.newDraweeControllerBuilder()
                    .setOldController(simpleDraweeView.getController())
                    .setImageRequest(request)
                    .build());

最佳答案

首先,您可以使用 setInitialItemPrefetchCount() 为嵌套的 RecyclerView 提供预取功能。有关更多信息,请查看此 article

我认为,主要原因是从服务器加载图像阻塞了主线程。您可以异步执行此操作。请检查这个article也是。

关于android - 具有多 View 滞后滚动的嵌套 RecyclerView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52163251/

有关android - 具有多 View 滞后滚动的嵌套 RecyclerView的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  3. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  4. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  5. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  6. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  7. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  8. Ruby——嵌套类和子类是一回事吗? - 2

    下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby​​解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc

  9. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  10. ruby-on-rails - 使用回形针的嵌套形式 - 2

    我有一个名为posts的模型,它有很多附件。附件模型使用回形针。我制作了一个用于创建附件的独立模型,效果很好,这是此处说明的View(https://github.com/thoughtbot/paperclip):@attachment,:html=>{:multipart=>true}do|form|%>posts中的嵌套表单如下所示:prohibitedthispostfrombeingsaved:@attachment,:html=>{:multipart=>true}do|at_form|%>附件记录已创建,但它是空的。文件未上传。同时,帖子已成功创建...有什么想法吗?

随机推荐