RecyclerViewアイテムの展開/折りたたみ


145

詳細を表示するために、recyclerViewのアイテムを展開/折りたたみます。SlideExpandableListViewと同じ効果を実現したいのですが。

基本的に私のviewHolderには表示されていないビューがあり、可視性をVISIBLE / GONEのみに設定するのではなく、スムーズな展開/縮小アニメーションを実行したいと思います。一度に展開する必要があるのはアイテムだけです。アイテムが選択されていることを示すためにある程度の高さがあると便利です。

これは、新しいAndroidの最近の通話履歴リストと同じ効果です。オプション「コールバック」と「詳細」は、アイテムが選択されている場合にのみ表示されます。

RecyclerView展開可能なアイテム


関連する質問があります。時計アプリでは、アラームセットアクティビティにも同様の機能があります。同じ方法で行われますか?
user2731584

ねえ、あなたは解決策を手に入れましたか?私も自分のアプリに同じ解決策を探しています。
Arpit Patel

何か解決策を見つけましたか?
Armin Ghoreishi 2016年

1
私は2016年に私の答えを参照してくださいGoogleのI / Oによると、それを行うための推奨される方法を更新しましたstackoverflow.com/questions/27203817/...
ハイゼンベルク

ここで私の答えを確認してください。シンプルでクールなソリューションstackoverflow.com/a/48092441/5962715
Kiran Benny Joseph

回答:


192

このエフェクトにはライブラリを使用しないでください。代わりに、Google I / Oに従って推奨される方法を使用してください。recyclerViewのonBindViewHolderメソッドで次のようにします。

final boolean isExpanded = position==mExpandedPosition;
holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mExpandedPosition = isExpanded ? -1:position;
        TransitionManager.beginDelayedTransition(recyclerView);
        notifyDataSetChanged();
    }
});
  • どこの詳細タッチに表示されます私の見解である(あなたのケースでコールの詳細を。デフォルトVisibility.GONE)。
  • mExpandedPositionは、-1に初期化されたint変数です。

そして、あなたが望むクールな効果のために、これらをlist_item属性として使用してください:

android:background="@drawable/comment_background"
android:stateListAnimator="@animator/comment_selection"

ここで、comment_backgroundは次のとおりです。

<selector
xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true"
android:enterFadeDuration="@android:integer/config_shortAnimTime"
android:exitFadeDuration="@android:integer/config_shortAnimTime">

<item android:state_activated="true" android:drawable="@color/selected_comment_background" />
<item android:drawable="@color/comment_background" />
</selector>

そしてcomment_selectionは:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_activated="true">
    <objectAnimator
        android:propertyName="translationZ"
        android:valueTo="@dimen/z_card"
        android:duration="2000"
        android:interpolator="@android:interpolator/fast_out_slow_in" />
</item>

<item>
    <objectAnimator
        android:propertyName="translationZ"
        android:valueTo="0dp"
        android:duration="2000"
        android:interpolator="@android:interpolator/fast_out_slow_in" />
</item>
</selector>

22
このコードを使用すると、展開アニメーションが奇妙に見えます。一番上のアイテムが消え、すべてが1つ上の位置に移動します。同様のことを経験したことがありますか?
chris-pollux 2016年

6
アニメーションを作成しようとしていますが、これをアダプターに実装していますがTransitionManager.beginDelayedTransition(recyclerView);、リサイクラービューの参照を妨げることができない場合の解決策は何でしょうか。
マルティンセラーノ

2
@Ranveerそれは一種の働きをします。私は2つの非常によく似たrecyclerViewsを持っていますが、1つだけ正しく機能します。なぜだかわかりません。@MartínDanielをrecyclerViewアダプターのコンストラクターのパラメーターとして渡す必要があります
chris-pollux

26
これはひどいアプローチです。Google I / Oで推奨されたとは思えません。Plaidプロジェクトを調査し、そこから必要なすべての回避策を実装した後でも、アニメーションによってRecyclerViewにいくつかの大きな不具合が発生します。また、アニメーションの実行中にスクロールすると、すべてのものがひどく混乱します。一般に、このアプローチによって引き起こされるすべての問題を修正することは、宣伝されているように「1行入力するだけですべてが機能する」とは言えないかもしれません。
Vitali Olshevski

6
この問題については、2019年にもっと新鮮で簡単な方法がありますか?
Ponomarenko Oleh

76

これには、複雑ではなく単純な行が必要でした

onBindViewHolderメソッドで、以下のコードを追加します

final boolean isExpanded = position==mExpandedPosition;
holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mExpandedPosition = isExpanded ? -1:position;
        notifyItemChanged(position);
    }
});

mExpandedPositionは、-1に初期化されたintグローバル変数です。

1つのアイテムのみを展開したい場合、他のアイテムは折りたたまれます。これを使って

最初に、previousExpandedPosition = -1でグローバル変数を宣言します

その後

    final boolean isExpanded = position==mExpandedPosition;
    holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
    holder.itemView.setActivated(isExpanded);

    if (isExpanded)
       previousExpandedPosition = position;

    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mExpandedPosition = isExpanded ? -1:position;
            notifyItemChanged(previousExpandedPosition);
            notifyItemChanged(position);
        }
    });

完了!!!。シンプルで控え目な.. :)


素晴らしいソリューション。また、私は、設定に移動してお勧めOnClickListenerするのをonCreateViewHolder代わりにonBindViewHolder
YTerle

1
非常にうまく機能します。まあ、RecyclerView作業を実行させる適切なソリューションがあった頃、つまりLayoutManager、レイアウトを管理しない場合の、それ以外の場合のポイントは何ですか?このソリューションは、コードが少なく、RecyclerView処理が簡単で、うまく機能するため、上位投票のソリューションよりも優れています。
マークキーン

1
「詳細」ビューを追加する方法がよくわかりませんでした。ホルダーごとに静的にする必要がありますか?リスト項目ごとに異なるビューを追加する必要がある場合はどうなりますか?
BekaBot

@BekaBotアイテムを折りたたむときに非表示にするビューです
Kiran Benny Joseph

@KiranBennyJosephはい、わかりました。この場合、ビューはすべてのアイテムで同じでなければなりませんか?アイテムごとに異なるビューが必要な場合はどうなりますか?
BekaBot 2018年

72

これが最善のアプローチであるとは言いませんが、私にはうまくいくようです。

完全なコードは次の場所にあります。サンプルコード: https //github.com/dbleicher/recyclerview-grid-quickreturn

まず、セル/アイテムレイアウトに拡張領域を追加し、それを囲むセルレイアウトをanimateLayoutChanges = "true"にします。これにより、展開/折りたたみが確実にアニメーション化されます。

<LinearLayout
    android:id="@+id/llCardBack"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:animateLayoutChanges="true"
    android:padding="4dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center|fill_horizontal"
        android:padding="10dp"
        android:gravity="center"
        android:background="@android:color/holo_green_dark"
        android:text="This is a long title to show wrapping of text in the view."
        android:textColor="@android:color/white"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tvSubTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center|fill_horizontal"
        android:background="@android:color/holo_purple"
        android:padding="6dp"
        android:text="My subtitle..."
        android:textColor="@android:color/white"
        android:textSize="12sp" />

    <LinearLayout
        android:id="@+id/llExpandArea"
        android:visibility="gone"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="6dp"
            android:text="Item One" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="6dp"
            android:text="Item Two" />

    </LinearLayout>
</LinearLayout>

次に、RVアダプタークラスにView.OnClickListenerを実装して、クリックされているアイテムを操作できるようにします。1つの拡張ビューの位置を保持するintフィールドを追加し、それを負の値に初期化します。

private int expandedPosition = -1;

最後に、ViewHolder、onBindViewHolder()メソッドを実装し、onClick()メソッドをオーバーライドします。位置が「expandedPosition」と等しい場合はonBindViewHolderでビューを展開し、そうでない場合は非表示にします。あなたはonClickリスナーのexpandedPositionの値を設定します:

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

    int colorIndex = randy.nextInt(bgColors.length);
    holder.tvTitle.setText(mDataset.get(position));
    holder.tvTitle.setBackgroundColor(bgColors[colorIndex]);
    holder.tvSubTitle.setBackgroundColor(sbgColors[colorIndex]);

    if (position == expandedPosition) {
        holder.llExpandArea.setVisibility(View.VISIBLE);
    } else {
        holder.llExpandArea.setVisibility(View.GONE);
    }
}

@Override
public void onClick(View view) {
    ViewHolder holder = (ViewHolder) view.getTag();
    String theString = mDataset.get(holder.getPosition());

    // Check for an expanded view, collapse if you find one
    if (expandedPosition >= 0) {
        int prev = expandedPosition;
        notifyItemChanged(prev);
    }
    // Set the current position to "expanded"
    expandedPosition = holder.getPosition();
    notifyItemChanged(expandedPosition);

    Toast.makeText(mContext, "Clicked: "+theString, Toast.LENGTH_SHORT).show();
}

/**
 * Create a ViewHolder to represent your cell layout
 * and data element structure
 */
public static class ViewHolder extends RecyclerView.ViewHolder {
    TextView tvTitle;
    TextView tvSubTitle;
    LinearLayout llExpandArea;

    public ViewHolder(View itemView) {
        super(itemView);

        tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
        tvSubTitle = (TextView) itemView.findViewById(R.id.tvSubTitle);
        llExpandArea = (LinearLayout) itemView.findViewById(R.id.llExpandArea);
    }
}

これは、レイアウト変更のシステムデフォルトアニメーションを使用して、一度に1つの項目のみを展開する必要があります。少なくとも私にとってはうまくいきます。それが役に立てば幸い。


アイテムを1つだけ選択したままにする方法を知っています。そのアイテムのアニメーションの仕方がよくわかりません。デフォルトのシステムアニメーションを使用した展開/折りたたみアニメーションは、非常に滑らかに見えません。
stanete

1
私はまだ以下を試していませんが、うまくいくようです。stackoverflow.com/a/26443762/2259418
MojoTosh

2
@ user2731584-そうは思いません。彼らのソース(私が信じていること)を見ると、Lollipopの時計がListViewを使用してアラームのリストを表示しているようです。レイアウト:android.googlesource.com/platform/packages/apps/DeskClock / + / これらには、このリストの展開/折りたたみ項目をアニメーション化するカスタムコードがあるようです。次のソースをご覧ください:android.googlesource.com/platform/packages/apps/DeskClock
+/…

1
@MojoToshあなたは正しいです。彼らはListViewを使用しており、コードを使用してアニメーションを行っています。ファイル内のexpandAlarm関数AlarmClockFragment.javaは拡張部分を実行します。
user2731584

4
どちらonClick()をオーバーライドする必要がありますか?ありませんonClickアダプターには。
Vicky Leong

15

Gradleをサポートする非常にシンプルなライブラリを使用できます:https : //github.com/cachapa/ExpandableLayout

ライブラリのドキュメントから:

<net.cachapa.expandablelayout.ExpandableLinearLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:el_duration="1000"
    app:el_expanded="true">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Click here to toggle expansion" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="Fixed height"
        app:layout_expandable="true" />

 </net.cachapa.expandablelayout.ExpandableLinearLayout>

あなたがマークした後、拡張可能なビューを、単に容器上にこれらのメソッドを呼び出しますexpand()collapse()またはtoggle()


これはまだそれを行うための最良の方法ですか?私はあなたが書いたものをフォローしようとしています。クリックするとグラフが表示されるように展開したいリサイクルビューがいくつかあります
sourlemonaid

10

元の質問が投稿されてから久しぶりのことです。しかし、私は私のような遅い人のために@ハイゼンベルクの答えの少しの説明が役立つと思います。

アダプタクラスで2つの変数を次のように宣言します。

private int mExpandedPosition= -1;
private RecyclerView recyclerView = null;

次に、元の回答で指定されているonBindViewHolderに従います。

      // This line checks if the item displayed on screen 
      // was expanded or not (Remembering the fact that Recycler View )
      // reuses views so onBindViewHolder will be called for all
      // items visible on screen.
    final boolean isExpanded = position==mExpandedPosition;

        //This line hides or shows the layout in question
        holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);

        // I do not know what the heck this is :)
        holder.itemView.setActivated(isExpanded);

        // Click event for each item (itemView is an in-built variable of holder class)
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

 // if the clicked item is already expaned then return -1 
//else return the position (this works with notifyDatasetchanged )
                mExpandedPosition = isExpanded ? -1:position;
    // fancy animations can skip if like
                TransitionManager.beginDelayedTransition(recyclerView);
    //This will call the onBindViewHolder for all the itemViews on Screen
                notifyDataSetChanged();
            }
        });

最後に、アダプターのオーバーライドでrecyclerViewオブジェクトを取得します

@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);

    this.recyclerView = recyclerView;
}

お役に立てれば。


3
素晴らしいシンプルなソリューション。小さな改善。マジックナンバー-1ではなくRecyclerView.NO_POSITIONを使用します。
キャスパーバン

8

サードパーティのライブラリを使用する必要はまったくありません。少し微調整で立証方法でGoogleのI / O 2016このトピックにとハイゼンベルク、トリックを行います。

notifyDataSetChanged() 完全なを再描画するRecyclerViewのでnotifyDataItemChanged()、位置とをViewHolder自由に使用notifyDataItemChanged()でき、特定のViewHolder位置でのみ特定の再描画するため、これはより良いオプションです(最良ではありません)。

しかし、問題は、ViewHolderクリックしたときの早期の消滅とその出現が排除されないことです。notifyDataItemChanged()使用さです。

次のコードではありませんに頼るnotifyDataSetChanged()notifyDataItemChanged()、各ViewHolderがありRecyclerViewに使用されたときAPI 23と魅力のような作品でテストされCardView、それのルート要素として:

holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final boolean visibility = holder.details.getVisibility()==View.VISIBLE;

            if (!visibility)
            {
                holder.itemView.setActivated(true);
                holder.details.setVisibility(View.VISIBLE);
                if (prev_expanded!=-1 && prev_expanded!=position)
                {
                    recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.setActivated(false);
                    recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.findViewById(R.id.cpl_details).setVisibility(View.GONE);
                }
                prev_expanded = position;
            }
            else
            {
                holder.itemView.setActivated(false);
                holder.details.setVisibility(View.GONE);
            }
            TransitionManager.beginDelayedTransition(recycler);              
        }
});

prev_position -1に初期化されたグローバル整数です。 details展開すると表示され、折りたたむとクローク表示される完全なビューです。

言ったように、のルート要素ViewHolderCardViewwith foregroundstateListAnimatorこのトピックにハイゼンベルグで言ったように属性が正確に定義されました。

更新:上記のデモンストレーションは、以前に展開されたアイテムの1つが展開されている場合、折りたたまれます。この動作を変更し、別のアイテムが展開されている場合でも展開されたアイテムをそのままにするには、次のコードが必要です。

if (row.details.getVisibility()!=View.VISIBLE)
    {
        row.details.setVisibility(View.VISIBLE);
        row.root.setActivated(true);
        row.details.animate().alpha(1).setStartDelay(500);
    }
    else
    {
        row.root.setActivated(false);
        row.details.setVisibility(View.GONE);
        row.details.setAlpha(0);
    }
    TransitionManager.beginDelayedTransition(recycler);

更新:リストの最後のアイテムを展開すると、展開された部分が画面の下に移動するため、完全に表示されない場合があります。画面内の完全なアイテムを取得するには、次のコードを使用します。

LinearLayoutManager manager = (LinearLayoutManager) recycler.getLayoutManager();
    int distance;
    View first = recycler.getChildAt(0);
    int height = first.getHeight();
    int current = recycler.getChildAdapterPosition(first);
    int p = Math.abs(position - current);
    if (p > 5) distance = (p - (p - 5)) * height;
    else       distance = p * height;
    manager.scrollToPositionWithOffset(position, distance);

重要:上記のデモを機能させるには、RecyclerViewとそのLayoutManagerのインスタンスをコード内に保持する必要があります(柔軟性のために後者)。


ありがとう、この解決策は私にとってうまくいきます。私はURLから画像をロードnotifyItemChangedするので使用を避けようとしImageViewます。notifyItemChanged画像をリロードすると見た目がおかしくなります
Tam Huynh '19

それを釘付けにする線はTransitionManager.beginDelayedTransition(recycler);、素晴らしい発見です。しかし、この方法を使用して、連続して複数の行をスパムクリックすると、最終的に内部クラッシュがトリガーされることがわかりましたThe specified child already has a parent. You must call removeView() on the child's parent first。これはリサイクラービューの境界でのビューのリサイクルによるものだと思いますが、はっきりとはわかりません。誰かに同じ問題がありましたか?
ロジャーオバ

これはまだそれを行うための最良の方法ですか?私はあなたが書いたものをフォローしようとしています。クリックするとグラフが表示されるように展開したいリサイクルビューがあります。私は何をすべきかを正確に理解するのに苦労しています
sourlemonaid

誰かがこの実装の完全な例を持っていますか?実用的なコード例です。助けてください。やり方がわかりません。
ムナザ

7

HeisenBergによって応答さRecyclerViewれたRecyclerViewの展開 /折りたたみ項目にある展開/折りたたみ可能な項目を実装する推奨方法を使用した後、呼び出しとその後の更新によってが更新されるたびに、いくつかの顕著なアーティファクトが見られましたRecyclerViewTransitionManager.beginDelayedTransition(ViewGroup)notifyDatasetChanged()

彼の元の答え:

final boolean isExpanded = position==mExpandedPosition;
holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mExpandedPosition = isExpanded ? -1 : position;
        TransitionManager.beginDelayedTransition(recyclerView);
        notifyDataSetChanged();
    }
});

変更:

final boolean isExpanded = position == mExpandedPosition;
holder.details.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
holder.view.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mExpandedHolder != null) {
            mExpandedHolder.details.setVisibility(View.GONE);
            notifyItemChanged(mExpandedPosition);
        }
        mExpandedPosition = isExpanded ? -1 : holder.getAdapterPosition();
        mExpandedHolder = isExpanded ? null : holder;
        notifyItemChanged(holder.getAdapterPosition());
    }
}
  • 詳細は、アイテムの展開/縮小時に表示/非表示にするビューです
  • mExpandedPositionは、int展開されたアイテムを追跡する
  • mExpandedHolderは、ViewHolderアイテムの折りたたみ中に使用されます

メソッドTransitionManager.beginDelayedTransition(ViewGroup)notifyDataSetChanged()は、notifyItemChanged(int)特定のアイテムといくつかの小さな調整をターゲットにするために置き換えられていることに注意してください。

変更後は、以前の不要な影響はなくなります。ただし、これは完全なソリューションではない場合があります。それは私が望んでいたことだけを行い、目障りなものを排除しました。

::編集::

明確にするために、mExpandedPositionmExpandedHolderは両方ともグローバルです。


mExpandedHolderを宣言して使用する方法と場所を説明してください。
ヴェルナー

1
@Werner答えがどこに宣言されているかを表示するように編集しました。使用方法は、スニペット自体と目的内にあります。折りたたみ、展開されたアイテムをアニメーション化するために使用されます。
Chan Teck Wei

アニメーションに関しては、このアプローチが一番好きですが、アイテムをクリックすると、この小さな「フェード」が生じます。あなたはそれを持っていますか、または別の言い方をすると、これはnotifyItemChanged()を使用するためですか?drive.google.com/file/d/1GaU1fcjHEfSErYF50otQGLGsIWkSyQSe/...
kazume

はい。あなたが推測したように、それはによって引き起こされnotifyItemChanged()ます。アイテムの高さを手動でアニメーション化して変更し、ビューを追加することができます。
Chan Teck Wei

@ChanTeckWei:recyclerviewアイテムの行を折りたたんだり展開したりすると、ソリューションは正常に機能しますが、行の画像がちらつきます。これに対する解決策はありますか?
Pragya Mendiratta

3

onClickリスナーをViewHolderクラスに設定した後、以下を実行します。

@Override
    public void onClick(View v) {
        final int originalHeight = yourLinearLayout.getHeight();
        animationDown(YourLinearLayout, originalHeight);//here put the name of you layout that have the options to expand.
    }

    //Animation for devices with kitkat and below
    public void animationDown(LinearLayout billChoices, int originalHeight){

        // Declare a ValueAnimator object
        ValueAnimator valueAnimator;
        if (!billChoices.isShown()) {
            billChoices.setVisibility(View.VISIBLE);
            billChoices.setEnabled(true);
            valueAnimator = ValueAnimator.ofInt(0, originalHeight+originalHeight); // These values in this method can be changed to expand however much you like
        } else {
            valueAnimator = ValueAnimator.ofInt(originalHeight+originalHeight, 0);

            Animation a = new AlphaAnimation(1.00f, 0.00f); // Fade out

            a.setDuration(200);
            // Set a listener to the animation and configure onAnimationEnd
            a.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    billChoices.setVisibility(View.INVISIBLE);
                    billChoices.setEnabled(false);
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
            // Set the animation on the custom view
            billChoices.startAnimation(a);
        }
        valueAnimator.setDuration(200);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer value = (Integer) animation.getAnimatedValue();
                billChoices.getLayoutParams().height = value.intValue();
                billChoices.requestLayout();
            }
        });


        valueAnimator.start();
    }
}

私はそれが助けになると思います、それが私が実装した方法であり、最近の通話ビューで同じグーグルが行います。


2

このような展開/折りたたみアニメーションは2行のコードで非常に簡単に実現できますが、まだ簡潔な答えがないことに驚きます。

(recycler.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false // called once

一緒に

notifyItemChanged(position) // in adapter, whenever a child view in item's recycler gets hidden/shown

だから私にとっては、以下のリンクの説明は本当に役に立ちました:https : //medium.com/@nikola.jakshic/how-to-expand-collapse-items-in-recyclerview-49a648a403a6


1
//Global Variable

private int selectedPosition = -1;

 @Override
    public void onBindViewHolder(final CustomViewHolder customViewHolder, final int i) {

        final int position = i;
        final GetProductCatalouge.details feedItem = this.postBeanses.get(i);
        customViewHolder.lly_main.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectedPosition = i;
                notifyDataSetChanged();
            }
        });
        if (selectedPosition == i) {

          if (customViewHolder.lly_hsn_code.getVisibility() == View.VISIBLE) {

            customViewHolder.lly_hsn_code.setVisibility(View.GONE);
            customViewHolder.lly_sole.setVisibility(View.GONE);
            customViewHolder.lly_sole_material.setVisibility(View.GONE);

        } else {

            customViewHolder.lly_hsn_code.setVisibility(View.VISIBLE);
            customViewHolder.lly_sole.setVisibility(View.VISIBLE);
            customViewHolder.lly_sole_material.setVisibility(View.VISIBLE);
        }


        } else {
            customViewHolder.lly_hsn_code.setVisibility(View.GONE);
            customViewHolder.lly_sole.setVisibility(View.GONE);
            customViewHolder.lly_sole_material.setVisibility(View.GONE);
        }
}

ここに画像の説明を入力してください


0

で2つのビュータイプを使用しますRVAdapter。1つは展開されたレイアウト用、もう1つは折りたたまれたレイアウト用です。そして魔法はandroid:animateLayoutChanges="true"RecyclerView チェックアウトの設定で発生します。このビデオの 0:42にこれを使用して達成される効果


これをもっとよく説明してもらえますか?
うまく動か

@sourlemonaidは基本的に、stackoverflow.com / a / 26245463/3731795で説明されているように、リストに対して複数のビュータイプを作成します。 ...アイテムが展開されているインデックスの追跡を続け、残りのアイテムはその時点で折りたたまれています。さてif(current_item_index == expanded_item_index){return VIEW_TYPE_EXPANDED} else {reutrn VIEW_TYPE_COLLAPSED}
penduDev
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.