AndroidのCollapsibleメニューを実現するには?

android-collapsible.png

ExpandableListを使う方法

このサイト[5]の方法でできた。
子メニューにラジオボタンにするには、
子メニューをRadioGroupにしたらできた
子メニューに追加してはいけないViewもあるらしい
CompoundButtonを子にしたらこんなエラーになった。

    java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams

LinearLayoutでやるやり方

ViewのsetVisible(GONE)/setVisible(VISIBLE)を切り替えるのが一般的
INVISIBLEだとレイアウトの大きさが残ってしまうのでご注意
テキストをこんな風にすれば手抜きで実装できるかな

TextView textview=new TextView(context);
textview.setText("もっと見る>");

Collapse/Expandにアニメを加えるには?

StackOverflowの回答[1]にちょっとアニメんの時間長めに設定すると何が起こってるか把握できました

public static void expand(final View v) {
    v.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    final int targetHeight = v.getMeasuredHeight();
 
    v.getLayoutParams().height = 0;
    v.setVisibility(View.VISIBLE);
    Animation a = new Animation()
    {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            v.getLayoutParams().height = interpolatedTime == 1
                    ? LayoutParams.WRAP_CONTENT
                    : (int)(targetHeight * interpolatedTime);
            v.requestLayout();
        }
 
        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };
 
    // 1dp/ms*20
    a.setDuration(20*(int)(targetHeight / v.getContext().getResources().getDisplayMetrics().density));
    v.startAnimation(a);
}
 
public static void collapse(final View v) {
    final int initialHeight = v.getMeasuredHeight();
 
    Animation a = new Animation()
    {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if(interpolatedTime == 1){
                v.setVisibility(View.GONE);
            }else{
                v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
                v.requestLayout();
            }
        }
 
        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };
 
    // 1dp/ms*20
    a.setDuration(20*(int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density));
    v.startAnimation(a);
}

+ Expandableと普通のListViewを混ぜることができるのか?
もし混ぜたいならまず、子要素は配列はnewしておくけど、実際には中身が何も入っていない状態にする

遭遇したエラー

java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams

java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
            at android.widget.ListView.measureScrapChild(ListView.java:1163)
            at android.widget.ListView.measureHeightOfChildren(ListView.java:1246)
            at android.widget.ListView.onMeasure(ListView.java:1155)
            at android.view.View.measure(View.java:12758)
            at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
            at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1369)
            at android.widget.LinearLayout.measureVertical(LinearLayout.java:660)
            at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)

このブログ[6]が参考になった
結局私の場合はListViewの子要素にボタンを配置したときになったのですが、
そのボタンをsetLayoutParams
mButton.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));

と書いてるところ全部なくしたら治った
もしレイアウト設定するならこうすればよかったのかな
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 64);

collapsible

サポートサイト Wikidot.com collapsible