在RecyclerView中快速滚动时,如何解决位置编号不匹配的问题?

时间:2019-04-13 04:50:15

标签: java android xml android-recyclerview

在我的Android本机项目中,我正在制作一个阅读器。因此,我使用一个recyclerview来显示卡和适配器类中的文本内容,在onBindViewHolder方法内部,我使用了参数位置来显示pageNo,如下所示-

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)

现在,它显示页码。当我缓慢滚动时可以正确显示,但是当我快速滚动或向相反方向滚动时,有时显示的位置错误。我的阅读器中也有一个Seekbar,如下图-

enter image description here

当我使用搜索栏从一个特定的页面移动到一段距离的页面时,那么它的位置也不正确。

这是recyclerview中每一行的xml部分-

   <android.support.v7.widget.CardView
            xmlns:card_view="http://schemas.android.com/apk/res-auto"
            android:id="@+id/card_view_left"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            card_view:cardCornerRadius="5dp"
            card_view:contentPadding="10dp"
            card_view:cardBackgroundColor="@color/colorTransparent"
            card_view:cardElevation="4dp"
            card_view:cardMaxElevation="5dp"
            android:layout_marginBottom="12dp"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="-7dp"
            >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                >

            <TextView
                android:id="@+id/tvPageNo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"

                android:layout_gravity="right"
                android:text=""
                android:layout_marginRight="20dp"
                />

            <com.actinarium.aligned.TextView
                android:layout_marginStart="10dp"
                android:layout_marginEnd="10dp"
                android:id="@+id/tv_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"

                android:textAppearance="@style/TextAppearance.AppCompat.Body1"
                android:textSize="14sp"
                app:leading="16sp"
                app:firstLineLeading="24sp"
                android:layout_marginBottom="10dp"
                />

            </LinearLayout>

        </android.support.v7.widget.CardView>

在onBindViewHolder内的RecyclerAdapter类中,我就是这样工作的-

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        ((ViewHolderText) holder).tvContent.setText("");

        if(preparedPage[position]==null){

            ((ViewHolderText) holder).loadingIndicator.smoothToShow();
            PageViewFragment.rvPageView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    return true;
                }
            });

            //Prepare page item as spannable string
            Flowable.fromCallable(() -> preparePage(position)).subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(finalText -> {
                        ((ViewHolderText) holder).loadingIndicator.hide();

                        PageViewFragment.rvPageView.setOnTouchListener(new View.OnTouchListener() {
                            @Override
                            public boolean onTouch(View v, MotionEvent event) {
                                return false;
                            }
                        });

                        preparedPage[position] = finalText;

                        ((ViewHolderText) holder).tvContent.setText(finalText);
                        ((ViewHolderText) holder).tvPageNo.setText(""+holder.getAdapterPosition());

                    }, this::onError);

        }else {

            ((ViewHolderText) holder).loadingIndicator.hide();
            ((ViewHolderText) holder).tvContent.setText(preparedPage[position]);
            Log.d(TAG, "BOOK: "+preparedPage[position].length()+" "/*+preparedPage[position]*/);
        }

}

我在片段类中声明了一个名为updateView的方法,这是该方法的实现-

private void updateView() {
    seekBar.setMax(pagesItems.size() - 1);
    seekBar.setOnProgressChangeListener(
            new DiscreteSeekBar.OnProgressChangeListener() {
                @Override
                public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) {

                    tvPageNumber.setText((seekBar.getProgress() + 1) + " of " + pagesItems.size());
                }

                @Override
                public void onStartTrackingTouch(DiscreteSeekBar seekBar) {}

                @Override
                public void onStopTrackingTouch(DiscreteSeekBar seekBar) {

                    rvPageView.scrollToPosition(seekBar.getProgress());
                    CURRENT_PAGE = seekBar.getProgress();
                    saveBookSettings();
                }
            });

    Log.d(TAG, "updateView: " + CURRENT_PAGE + " " + bookSettings.toString());
    tvPageNumber.setText((CURRENT_PAGE + 1) + " of " + pagesItems.size());
    rvPageView.scrollToPosition(CURRENT_PAGE);
    seekBar.setProgress(CURRENT_PAGE);
}

那么,如何在RecyclerView中跟踪每张卡的数量并正确显示它们,同时滚动太快或使用搜索栏进行更改?

1 个答案:

答案 0 :(得分:1)

尝试仅将这一行添加到您的Recycleradpater中,这将解决您的问题

    @Override
    public int getItemViewType(int position) {
        return position;
    }
}