ExpandableTextView icon indicating copy to clipboard operation
ExpandableTextView copied to clipboard

Expand/Collapse Bug with recyclerview

Open slidenerd opened this issue 10 years ago • 13 comments

testgif Hi, first of all , awesome library because yours probably is the only one that does this. I am using your library with a recyclerview in my code. I set 3 lines to be displayed in my custom_item snap 2015-03-13 at 12 50 19

As you saw the issue, some items expand once, the collapse incorrectly and never expand again, any ideas ,if you need any more source files , please let me know, thanks in advance for your help

public class AdapterFeed extends UltimateViewAdapter { private Context mContext; private ArrayList<Post> mListFeed = new ArrayList<>(); private LayoutInflater mLayoutInflater; private EventListener mEventListener; private SparseBooleanArray mTogglePositions = new SparseBooleanArray();

public AdapterFeed(Context context) {
    this.mContext = context;
    mLayoutInflater = LayoutInflater.from(context);
    setHasStableIds(true);
}

public void setFeed(ArrayList<Post> listFeed) {
    if (listFeed != null && listFeed.size() > 0) {
        mListFeed = listFeed;
        notifyItemRangeChanged(0, listFeed.size());
    }
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof HolderFeed) {
        Post currentPost = mListFeed.get(position);
        HolderFeed holderFeed = (HolderFeed) holder;
        holderFeed.textPost.setText(Post.isNotEmptyMessage(currentPost) ? currentPost.getMessage() : "No Text", mTogglePositions, position);

    }
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup) {
    View layout = mLayoutInflater.inflate(R.layout.item_feed, viewGroup, false);
    HolderFeed holderFeed = new HolderFeed(layout);
    return holderFeed;
}

@Override
public int getAdapterItemCount() {
    return mListFeed.size();
}


static class HolderFeed extends RecyclerView.ViewHolder {

    private ExpandableTextView textPost;

    public HolderFeed(View itemView) {
        super(itemView);
        textPost = (ExpandableTextView) itemView.findViewById(R.id.expand_text_view);
    }

}

}

slidenerd avatar Mar 13 '15 07:03 slidenerd

I forgot to mention one thing, I am using your library with this https://github.com/cymcsg/UltimateRecyclerView could that be any reason for a clash? Do let me know thanks

slidenerd avatar Mar 13 '15 07:03 slidenerd

I may have figured out whats causing this, unlike the ListView where the getView will be called every time and you are the one whose deciding if the view should be recycled or not, thats not the case with a recyclerview, the onCreateViewHolder and onBindViewHolder are called initially when no recycled views are available but later the only method that gets triggered is the onBindViewHolder, does this have something to do with the SparseBooleanArray because I am binding it inside the onBindViewHolder, so the thing is, items that are towards the end of the list or the ones that are being created from recyled views expand and collapse correctly but not the ones at the beginning, take a look at this screenshot, the one at the start incurs both the onCreateViewHolder and the onBindViewHolder whereas the one at the bottom is simply recycled directly with the onBindViewHolder testgif

slidenerd avatar Mar 13 '15 07:03 slidenerd

Thanks for the info. I will take a look this weekend and get back to you.

Manabu-GT avatar Mar 13 '15 09:03 Manabu-GT

I met a problem when I set ExpandableTextView's orientation horizontal:

<com.netease.cartoonreader.view.ExpandableTextView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:expandableTextView="http://schemas.android.com/apk/res-auto"
        android:id="@+id/expand_text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        expandableTextView:animAlphaStart="1"
        expandableTextView:animDuration="200"
        expandableTextView:maxCollapsedLines="4">

        <TextView
            android:id="@id/expandable_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageButton
            android:id="@id/expand_collapse"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/transparent" />
    </com.netease.cartoonreader.view.ExpandableTextView>

In a item of RecyclerView, when the state of ExpandableTextView is expandle, and scroll the RecyclerView to make this item rebind(onBindViewHolder again), click the ExpandableTextView will make the text invisible. The problem is solved by setting TextView's layout_width "wrap_content". But I don't know why.

fengshenzhu avatar May 13 '15 09:05 fengshenzhu

I had similar issue with ExpandableTextview in AOSP which this library is based on.

I solved it by simply using the plain old TextView and keeping expanded status my self. Whenever the onBindViewHolder is called, check the expanded status, and then setMaxLines to Integer.MAX_VALUE when it should be expanded or max lines you want when it should be collapsed. You may also opt-in for animation by calling notifyItemChanged(int position).

Hope this is helpful. :smiley_cat: Ref #18

aaronweihe avatar Mar 05 '16 02:03 aaronweihe

is the issue fixed which was mentioned by slidenerd....?

mohanraj546 avatar Mar 10 '16 09:03 mohanraj546

#44 This thread has the proper solution to this issue

nangsan avatar Feb 03 '17 13:02 nangsan

Encountered the same problem, how to solve?

CleverMod avatar Jun 14 '17 09:06 CleverMod

@wmq389122157 @mohanraj546 @slidenerd @aaronhe42 If the content of the TextView is long enough, you can set mAnimationDuration = 0, setDuration (mAnimationDuration), and cancel the animation

Mixiaomi avatar Jun 16 '17 10:06 Mixiaomi

@Mixiaomi Thank you very much. The problem is settled. Thanks again!

CleverMod avatar Jun 19 '17 13:06 CleverMod

@Mixiaomi Thank you. It Worked.

monikagupta94 avatar Aug 01 '17 09:08 monikagupta94

Hi, I am also facing an issue. While using the ExpandableTextView inside RecyclerView, whenever I am trying to collapse the TextView it becomes invisible.

pk4393 avatar Aug 10 '18 11:08 pk4393

i solve this problem. when this view detach from window , animion might not finish。you can use ValueAnimator。here is the code: `@Override public void onClick(View view) {

    if (mStateTv.getVisibility() != View.VISIBLE) {
        return;
    }

    mCollapsed = !mCollapsed;
    mStateTv.setText(mCollapsed ? mExpandString : mCollapsedString);

// mStateTv.setCompoundDrawablesWithIntrinsicBounds(mCollapsed ? mExpandDrawable : mCollapseDrawable, null, null, null);

    if (mCollapsedStatus != null) {
        mCollapsedStatus.put(mPosition, mCollapsed);
    }

    // mark that the animation is in progress
    mAnimating = true;

    //Animation animation;
    if (mCollapsed) {
        finalHeight = mCollapsedHeight;
    } else {
        finalHeight = getHeight() +
                mTextHeightWithMaxLines - mTv.getHeight();
    }

    animateExpandView(this, getHeight(), finalHeight);
}

private void animateExpandView(View mTargetView, int mStartHeight, int mEndHeight) {
    mAnimating = true;
    ValueAnimator animator = ValueAnimator.ofInt(mStartHeight, mEndHeight);
    animator.setInterpolator(new AccelerateDecelerateInterpolator());
    animator.setDuration(mAnimationDuration);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            final int newHeight = (int) animation.getAnimatedValue();
            mTv.setMaxHeight(newHeight - mMarginBetweenTxtAndBottom);
            mTargetView.getLayoutParams().height = newHeight;
            mTargetView.requestLayout();
        }
    });
    animator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {
            Utils.Log.e("Expand animator onAnimationEnd");
            clearAnimation();
            // clear the animation flag
            mAnimating = false;
            Utils.Log.e("Expand onAnimationEnd");
            // notify the listener
            if (mListener != null) {
                mListener.onExpandStateChanged(mTv, !mCollapsed);
            }
        }

        @Override
        public void onAnimationCancel(Animator animation) {

        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });
    animator.start();
}

`

Greatkingcj avatar Jan 22 '19 12:01 Greatkingcj