本文介绍了Android RecyclerView创建并绑定有关数据集更改的所有视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常大的应用程序,其中几乎所有地方都使用过RecylclerViews,我知道如何实现RecyclerViews,而且我从来没有任何问题!但是最近我在其中一个RV上遇到了一个非常糟糕的滞后,(让我确保我的bindview方法非常好,我将所有图像加载到asynctasks中,然后...),这就是在首先显示RV时取得ANR!

I have a very large app in which I have used RecylclerViews almost everywhere, I know how to implement RecyclerViews and I did not have any problem, ever !but lately I came across a really bad lag on one of the RVs, (let me assure you my bindview methods are perfectly good, I load all the images in the asynctasks and ... ), and that is on first showing the RV I get an ANR !

经过数小时的调试,我发现每次数据集发生更改(notifyDataset())时,包括RV首次填充时,所有视图都被创建并绑定(是200倍于onCreateView( ),这与RecyclerView的原理恰恰相反!)一旦创建并绑定了所有视图,该应用程序便开始正常运行,我的意思是不再需要onCreateView()和onBindView()调用,没有任何滞后.

after hours of debuging, I found out that each time the dataset changes (notifyDataset()), including the very first time that the RV populates, all of the views are both created and bound (yes like 200 times the onCreateView() is called, which is just the opposite of the RecyclerView's philosophy!) Once all the views are created and bound, the app starts functioning normally, I mean no more onCreateView() and as required onBindView() calling, with no lag whatsoever.

我知道很难找到原因,但是我认为也许有一个明显的设置或...导致这种情况或SO用户的一些过去的经验可能对我有所帮助.

I know it's really hard to find the reason, but I thought maybe there is an obvious setting or ... which causes this or some past experience from SO users may help me.

显然原因是由于我的XML以及我如何使RV填充自由区域,因为当我将其高度设置为指定值(例如400 dp)时,一切正常,但是如果我使用LinearLayout和layout_weight或对RelativeLayout(设置在顶部对齐的元素下方和底部对齐的元素上方)进行相同操作会重新产生此问题.

apparently the reason is due to my XML and how I made the RV to fill the free area, as when I set it's height to a specified value (eg. 400 dp) everything works fine, but either if I use LinearLayout and layout_weight or doing same with RelativeLayout (set below a aligned-top element and above a align-bottomed element) recreates the issue.

所以我能说的是,当需要动态计算RV的高度时会发生此问题,我猜想它会创建所有的孩子来计算其高度,这显然是支持库中的一个错误(com.android .support:recyclerview-v7:23.4.0当时)

so what I can say is this issue happens when the height of the RV is needed to calculate dynamically and I guess it creates all of it's childs to calculate it's height, which obviously is a bug in the support library (com.android.support:recyclerview-v7:23.4.0 at the time)

有人有解决方法吗?还是可以告诉我我的错误?

anyone has a workaround ? or perhaps can tell me my mistake ?

针对未来的Google员工

for future googlers

似乎解决方案是在LayoutManager上使用setAutoMeasureEnabled(false);.此方法已在支持库的23.2.0版本中引入,应该有助于将wrap_content用作RV项目的布局参数,无论如何,我用这种方法克服了我的问题,并且将wrap_content用于我的商品高度没有问题,

It seems that the solution is to use setAutoMeasureEnabled(false); on the LayoutManager.this method has been introduced in the 23.2.0 version of support library and is supposed to be helpful to use wrap_content as the layout params of the RV items, any way I overcame my problem with this method, and am using wrap_content for my item heights with no problem,

推荐答案

我遇到了类似的问题,我在ViewPager中使用了RecyclerView.将项目设置为适配器时,RecyclerView还会将所有视图绑定两次.而且我在基本ViewPager类中发现了问题.我放了几行代码,根据它的孩子动态地计算ViewPager的高度.当我删除该代码时,RecyclerView可以正常工作.该代码在下面;

I faced similar problem, I used RecyclerView inside ViewPager. RecyclerView was binding all views also two times when set items to adapter. And I found problem inside base ViewPager class. I put some lines of code for calculating ViewPager height dynamically according to it's childs. When I remove that codes RecyclerView works fine. That code is below;

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int mode = MeasureSpec.getMode(heightMeasureSpec);
    // Unspecified means that the ViewPager is in a ScrollView WRAP_CONTENT.
    // At Most means that the ViewPager is not in a ScrollView WRAP_CONTENT.
    if (mode == MeasureSpec.UNSPECIFIED || mode == MeasureSpec.AT_MOST) {
        // super has to be called in the beginning so the child views can be initialized.
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if (h > height) height = h;
        }
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
    }
    // super has to be called again so the new specs are treated as exact measurements
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

这篇关于Android RecyclerView创建并绑定有关数据集更改的所有视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 20:30