如何阻止RecyclerView回收切换可见和消失的项目

时间:2016-09-10 08:34:06

标签: android android-recyclerview

我已在我的应用中成功实施了RecyclerView。 RecyclerView有三个项目,即。 title(TextView),ImageButton,description(TextView)。

标题和ImageButton始终可见,同时通过单击ImageButton来切换描述的可见性(默认设置为GONE)。

我遇到的问题是,当您单击一个项目中的ImageButton并且描述变得可见时,向下或向上滚动时,即使我没有单击,第五个(向上或向下)项目也会显示描述ImageButton让它可见。

我的代码:

book_card.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="4dp"
    card_view:cardElevation="4dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/book_image"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:id="@+id/book_title"
            android:textStyle="bold"/>

        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_arrow_name"
            android:id="@+id/arrow_button"
            android:layout_below="@+id/book_title"
            android:layout_centerHorizontal="true"
            android:onClick="onArrowClick"
            android:padding="5dp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/arrow_button"
            android:visibility="gone"
            android:id="@+id/book_descrip"/>

    </RelativeLayout>

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

BookItem

public class BookItems implements Parcelable, Collection<BookItems> {
    private String book_title;
    private String book_descrip;

    public String getBook_title() {
        return book_title;
    }

    public void setBook_title(String book_title) {
        this.book_title = book_title;
    }

    public String getBook_descrip() {
        return book_descrip;
    }

    public void setBook_descrip(String book_descrip) {
        this.book_descrip = book_descrip;
    }
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.book_title);
        dest.writeString(this.book_descrip);
    }

    public BookItems() {
    }

    protected BookItems(Parcel in) {
        this.book_title = in.readString();
        this.book_descrip = in.readString();
    }

    public static final Parcelable.Creator<BookItems> CREATOR = new Parcelable.Creator<BookItems>() {
        @Override
        public BookItems createFromParcel(Parcel source) {
            return new BookItems(source);
        }

        @Override
        public BookItems[] newArray(int size) {
            return new BookItems[size];
        }
    };

    @Override
    public boolean add(BookItems object) {
        return false;
    }

    @Override
    public boolean addAll(Collection<? extends BookItems> collection) {
        return false;
    }

    @Override
    public void clear() {

    }

    @Override
    public boolean contains(Object object) {
        return false;
    }

    @Override
    public boolean containsAll(Collection<?> collection) {
        return false;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    @NonNull
    @Override
    public Iterator<BookItems> iterator() {
        return null;
    }

    @Override
    public boolean remove(Object object) {
        return false;
    }

    @Override
    public boolean removeAll(Collection<?> collection) {
        return false;
    }

    @Override
    public boolean retainAll(Collection<?> collection) {
        return false;
    }

    @Override
    public int size() {
        return 0;
    }

    @NonNull
    @Override
    public Object[] toArray() {
        return new Object[0];
    }

    @NonNull
    @Override
    public <T> T[] toArray(T[] array) {
        return null;
    }
}

BookAdapter

public class BookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

    private Context mContext;
    private OnItemClickedListener mItemClickedListener;

    //List of books
    private List<BookItems> mBookItems;

    private int lastPosition = -1;


    public BookAdapter(List<BookItems> bookItems, Context context) {
        super();

        //Getting all books
        this.mBookItems = bookItems;
        this.mContext = context;
        this.mItemClickedListener = null;
    }

    public void setItemClickedListener (OnItemClickedListener onItemClickedListener) {
        this.mItemClickedListener = onItemClickedListener;
    }


    @Override
    public RecyclerView.ViewHolder  onCreateViewHolder (ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.book_card, parent, false);
            return new CardViewHolder(v);
    }


    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            final BookItems bookList = mBookItems.get(position);
            ((CardViewHolder) holder).bookTitle.setText(Html.fromHtml(bookList.getBook_title()));
            ((CardViewHolder) holder).bookDescrip.setText(Html.fromHtml(bookList.getBook_descrip()));

            ((CardViewHolder) holder).bookDescrip.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mItemClickedListener != null) {
                        mItemClickedListener.onItemClicked(bookList.getBookId(), "Book");
                    }
                }
            });

            ((CardViewHolder) holder).bookTitle.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mItemClickedListener != null) {
                        mItemClickedListener.onItemClicked(bookList.getBookId(), "Book");
                    }
                }
            });
            setAnimation(holder.itemView, position);
    }

    private void setAnimation(View viewToAnimate, int position) {
        if (position > lastPosition) {
            Animation animation = AnimationUtils.loadAnimation(mContext, R.anim.recycler_anim_up);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }

    @Override
    public int getItemCount(){
        return mBookItems.size();
    }

    @Override
    public void onViewDetachedFromWindow(final RecyclerView.ViewHolder holder) {
        holder.itemView.clearAnimation();
    }

    public class CardViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        @BindView(R.id.book_title) TextView bookTitle;
        @BindView(R.id.book_descrip) TextView bookDescrip;
        @BindView(R.id.arrow_button) ImageButton imageButton;

        public CardViewHolder (final View bookView) {
            super(bookView);
            ButterKnife.bind(this, bookView);
            imageButton.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            if (v.getId() == imageButton.getId()) {
                int visibility = bookDescrip.getVisibility();
                if (visibility == View.VISIBLE) {
                    bookDescrip.setVisibility(View.GONE);

                } else {
                    bookDescrip.setVisibility(View.VISIBLE);
                }
            }
        }

    }
}

无论如何,请阻止这种不端行为吗?

1 个答案:

答案 0 :(得分:0)

我遵循了Tasos的建议,这是如何修复的。

BookItem 中我添加了这个:

private boolean descVisible = false;

public boolean isDescVisible() {
    return descVisible;
}

public void setDescVisible(boolean descVisible) {
    this.descVisible = descVisible;
}

然后在 BookAdapter onBindViewHolder 中,我这样做了:

if (bookList.isVisible()) {
            ((CardViewHolder) holder).bookDescrip.setVisibility(View.VISIBLE);
        } else {
            ((CardViewHolder) holder).bookDescrip.setVisibility(View.GONE);
        }

        ((CardViewHolder) holder).imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (bookList.isDescVisible()) {
                    ((CardViewHolder) holder).bookDescrip.setVisibility(View.GONE);
                    bookList.setDescVisible(false);

                } else {
                    ((CardViewHolder) holder).bookBody.setVisibility(View.VISIBLE);
                    bookList.setDescVisible(true);
                }
            }
        });