web-dev-qa-db-ja.com

Androidアニメーションを使用したExpandableListView

私は使っています

<ExpandableListView
     Android:id="@+id/listView"
     Android:layout_width="match_parent"
     Android:layout_height="match_parent" >
</ExpandableListView>

onclick parentの場合、子のアニメーションスライドを追加します。どうすればいいですか?

15

最終更新

この答えを書いてからかなりの時間が経ちました。それ以来、多くのことが変わりました。最大の変更点は、リストまたはグリッドのアニメーションを簡単にするRecyclerViewの導入です。可能であれば、RecyclerViewsに切り替えることを強くお勧めします。できない人のために、私のライブラリのバグを修正するために私ができることを見ていきます。


元の答え

私の使用例では、各グループには多くの子供がいたため、通常のListViewを子供として使用することは実行可能ではなかったため、実際にはListViewを展開アニメーションで使用するExpandableListViewの人気のある実装は実際には好きではありませんビューはリサイクルされず、パフォーマンスが低下するとメモリ使用量が膨大になります。代わりに、はるかに難しいが、よりスケーラブルで柔軟なアプローチを採用しました。

ExpandableListViewクラスを拡張し、onCollapse関数とonExpand関数をオーバーライドし、AnimatedExpandableListAdapterというBaseExpandableListAdapterのサブクラスも作成しました。アダプター内で、getChildView関数をオーバーライドし、関数を再度オーバーライドできないように、関数をfinalにしました。代わりに、サブクラスが実際の子ビューを提供するためにオーバーライドするgetRealChildViewという別の関数を提供しました。次に、アニメーションフラグをクラスに追加し、アニメーションフラグが設定されている場合はgetChildViewがダミービューを返し、フラグが設定されていない場合は実際のビューを返すようにしました。ステージセットを使用して、onExpandに対して以下を実行します。

  1. アダプターにアニメーションフラグを設定し、どのグループが展開されているかをアダプターに伝えます。
  2. notifyDataSetChanged()を呼び出します(画面上のすべてのビューに対してgetChildView()を呼び出すようにアダプターを強制します)。
  3. 次に、アダプターは(アニメーションモードで)初期高さ0を持つ拡張グループのダミービューを作成します。その後、アダプターは実際の子ビューを取得し、これらのビューをダミービューに渡します。
  4. ダミービューは、それ自身のonDraw()関数内で実際の子ビューの描画を開始します。
  5. アダプタは、適切なサイズになるまでダミービューを展開するアニメーションループを開始します。また、アニメーションリスナーが設定され、アニメーションが完了するとアニメーションフラグがクリアされ、notifyDataSetChanged()も呼び出されます。

最後に、これらすべてを実行した後、この方法は100人以上の子供を持つグループで機能するため、目的のアニメーション効果だけでなく、目的のパフォーマンスを得ることができました。

折りたたみアニメーションの場合、これをすべてセットアップして実行するには、もう少し作業が必要です。特に、onCollapseをオーバーライドする場合、親の関数を呼び出すとグループがすぐに折りたたまれ、アニメーションを再生する機会がなくなります。代わりに、折りたたみアニメーションの最後にsuper.onCollapseを呼び出します。

UPDATE:

私はこの週末にこのAnimatedExpandableListViewの実装を書き換えるために時間を費やし、ここで使用例を使用してソースをリリースしています: https://github.com/idunnololz/AnimatedExpandableListView/

52
idunnololz

@idunnololzソリューションは非常に効果的です。ただし、以前に展開したグループを折りたたむためのコードを追加したいと思います。

private int previousGroup=-1;

    listView.setOnGroupClickListener(new OnGroupClickListener() {

        @Override
        public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
            // We call collapseGroupWithAnimation(int) and
            // expandGroupWithAnimation(int) to animate group 
            // expansion/collapse.
            if (listView.isGroupExpanded(groupPosition)) {
                listView.collapseGroupWithAnimation(groupPosition);
                previousGroup=-1;
            } else {
                listView.expandGroupWithAnimation(groupPosition);
                if(previousGroup!=-1){
                    listView.collapseGroupWithAnimation(previousGroup); 
                }
                previousGroup=groupPosition;
            }

            return true;
        }

    });
6
Hiren Dabhi
animateLayoutChanges adds auto-animation
<ExpandableListView
        Android:animateLayoutChanges="true"
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent"/>
5
KursikS

@idunnololzソリューションはうまく機能していますが、グループのカスタムレイアウトで奇妙な動作を経験しました。展開操作は適切に実行されませんでしたが、折りたたみは完璧に機能しました。彼のテストプロジェクトをインポートしたところ、問題なく動作したため、カスタムレイアウトに問題があることに気付きました。しかし、調査を行って問題を特定できなかったため、AnimatedExpandListViewで次のコード行のコメントを外すことにしました。

       if (lastGroup && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            return expandGroup(groupPos, true);
        }

これが問題を引き起こしました(私のアプリはAndroid 4.0+)を対象としています)。

0
vanomart