ExpandableListViewのアイテムを展開/折りたたみするときに、ニーススライドアップ/ダウン効果を使用できますか?
はいの場合、どのように?
前もって感謝します。
したがって、これは this の完全な複製です。つまり、通常のリストを使用し、独自のドロップダウンビューを作成し、カスタムドロップダウンアニメーションを使用して成功しました(詳細についてはリンクを参照してください)。
編集:ステップバイステップガイド:
まず、xml list_rowを作成します。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:id="@+id/row_parent"
Android:orientation="vertical">
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:id="@+id/row_simple_parent"
>
<View
Android:id="@+id/row_simple_parent_invis_cover"
Android:visibility="gone"
Android:layout_height="something that fills out your content"
Android:layout_width="match_parent"
Android:background="@Android:color/transparent"/>
</RelativeLayout>
<!-- Dropdown -->
<RelativeLayout
Android:id="@+id/row_dropdown"
Android:layout_height="wrap_content"
Android:layout_width="match_parent">
</RelativeLayout>
</LinearLayout>
ドロップダウンのアニメーションは次のとおりです。
import Android.app.Activity;
import Android.util.DisplayMetrics;
import Android.view.View;
import Android.view.View.MeasureSpec;
import Android.view.animation.Animation;
import Android.view.animation.Transformation;
/**
* Class for handling collapse and expand animations.
* @author Esben Gaarsmand
*
*/
public class ExpandCollapseAnimation extends Animation {
private View mAnimatedView;
private int mEndHeight;
private int mStartVisibility;
/**
* Initializes expand collapse animation. If the passed view is invisible/gone the animation will be a drop down,
* if it is visible the animation will be collapse from bottom
* @param view The view to animate
* @param duration
*/
public ExpandCollapseAnimation(View view, int duration) {
setDuration(duration);
mAnimatedView = view;
mEndHeight = mAnimatedView.getLayoutParams().height;
mStartVisibility = mAnimatedView.getVisibility();
if(mStartVisibility == View.GONE || mStartVisibility == View.INVISIBLE) {
mAnimatedView.setVisibility(View.VISIBLE);
mAnimatedView.getLayoutParams().height = 0;
}
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (interpolatedTime < 1.0f) {
if(mStartVisibility == View.GONE || mStartVisibility == View.INVISIBLE) {
mAnimatedView.getLayoutParams().height = (int) (mEndHeight * interpolatedTime);
} else {
mAnimatedView.getLayoutParams().height = mEndHeight - (int) (mEndHeight * interpolatedTime);
}
mAnimatedView.requestLayout();
} else {
if(mStartVisibility == View.GONE || mStartVisibility == View.INVISIBLE) {
mAnimatedView.getLayoutParams().height = mEndHeight;
mAnimatedView.requestLayout();
} else {
mAnimatedView.getLayoutParams().height = 0;
mAnimatedView.setVisibility(View.GONE);
mAnimatedView.requestLayout();
mAnimatedView.getLayoutParams().height = mEndHeight;
}
}
}
/**
* This methode can be used to calculate the height and set itm for views with wrap_content as height.
* This should be done before ExpandCollapseAnimation is created.
* @param activity
* @param view
*/
public static void setHeightForWrapContent(Activity activity, View view) {
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenWidth = metrics.widthPixels;
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY);
view.measure(widthMeasureSpec, heightMeasureSpec);
int height = view.getMeasuredHeight();
view.getLayoutParams().height = height;
}
}
次に、アダプター内で(もちろん、さらに構文を追加します。リスト内で見えなくなったときにドロップダウンを閉じないようにするには、何らかのパラメーターを使用して、これをホルダーに記憶する必要があります):
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null) {
// setup holder
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.list_row, null);
holder.mDropDown = convertView.findViewById(R.id.row_dropdown);
convertView.setTag(holder);
} else {
// get existing row view
holder = (ViewHolder) convertView.getTag();
}
holder.mDropDown.setVisibility(View.GONE);
return convertView;
}
次に、ItemClickのリストで魔法が発生します。
@Override
public void onListItemClick(ListView list, View view, int position, long id) {
final ListItem item = (ListItem) list.getAdapter().getItem(position);
// set dropdown data
ViewHolder holder = (ViewHolder) view.getTag();
final View dropDown = holder.mDropDown;
// set click close on top part of view, this is so you can click the view
// and it can close or whatever, if you start to add buttons etc. you'll loose
// the ability to click the view until you set the dropdown view to gone again.
final View simpleView = view.findViewById(R.id.row_simple_parent_invis_cover);
simpleView.setVisibility(View.VISIBLE);
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if(msg.what == 0) {
// first we measure height, we need to do this because we used wrap_content
// if we use a fixed height we could just pass that in px.
ExpandCollapseAnimation.setHeightForWrapContent(getActivity(), dropDown);
ExpandCollapseAnimation expandAni = new ExpandCollapseAnimation(dropDown, DROP_DOWN_TIME);
dropDown.startAnimation(expandAni);
Message newMsg = new Message();
} else if(msg.what == 1) {
ExpandCollapseAnimation expandAni = new ExpandCollapseAnimation(dropDown, DROP_DOWN_TIME);
dropDown.startAnimation(expandAni);
simpleView.setOnClickListener(null);
simpleView.setVisibility(View.GONE);
}
}
};
simpleView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
handler.sendEmptyMessage(1);
}
});
// start drop down animation
handler.sendEmptyMessage(0);
}
最終コメント:これが最善の方法であるかどうかはわかりませんが、これが私にとってはうまくいったことです。
Edit:YouTubeでDevBytesが見ることができる別のソリューションがあります here 。
Warpzitが指摘したアンサーは正しいです。このアプローチを使用して、実際にどのように機能するかを知らなくても、アプリケーションに簡単に埋め込むことができるライブラリを提供しました。
https://github.com/tjerkw/Android-SlideExpandableListView
詳細については、このブログ投稿をご覧ください: http://tjerktech.wordpress.com/2012/06/23/an-emerging-Android-ui-pattern-for-contextual-actions/
展開/折りたたみは、次のコードでは機能しません: https://github.com/tjerkw/Android-SlideExpandableListView なぜなら_OnItemExpandCollapseListener expandCollapseListener
_ AbstractSlideExpandableListAdapter
からはnull
です。アニメーションの開始時にメソッドnotifiyExpandCollapseListener
が呼び出されますが、リスナーはnull
になります。なぜなら、ActionSlideExpandableListView
を持っているからです:
_ActionSlideExpandableListView lv = (ActionSlideExpandableListView) findViewById(R.id.list_view);
SlideExpandableListAdapter slideAdapter = new SlideExpandableListAdapter(adapter,R.id.expandable_toggle_button, R.id.expandable);
_
アダプターを設定します:lv.setAdapter(slideAdapter);
はsetAdapter
からメソッドSlideExpandableListView
を呼び出し、SlideExpandableListAdapter
の新しいインスタンスが作成されます。
私はこのように変更しました:setAdapter
のActionSlideExpandableListView
メソッドは、setAdapter
からSlideExpandableListView
メソッドに渡される_AbstractSlideExpandableListAdapter.OnItemExpandCollapseListener
_からもパラメーターとして受け取ります。そこでSlideExpandableListAdapter
を作成すると、このリスナーも渡されます。
_ public void setAdapter(ListAdapter adapter, AbstractSlideExpandableListAdapter.OnItemExpandCollapseListener expandCollapseListener) {
this.adapter = new SlideExpandableListAdapter(adapter, expandCollapseListener);
super.setAdapter(this.adapter);
}
public SlideExpandableListAdapter(ListAdapter wrapped, OnItemExpandCollapseListener expandCollapseListener) {
this(wrapped, R.id.expandable_toggle_button, R.id.expandable);
setItemExpandCollapseListener(expandCollapseListener);
}
_
単純な解決策は、Gary Guoが作成したクラスAnimatedExpandableListView
を使用することです。これは、BaseExpandableListAdapter
を拡張するExpandableListAdapter
を既に使用している場合は、 here を使用できます。この方法では、ListView
の変更を使用する必要はありません。
AnimatedExpandableListAdapter
の代わりにBaseExpandableListAdapter
およびAnimatedExpandableListView
の代わりにExpandableListView
をサブクラス化するだけで済みます。
@Override getChildrenCount
の代わりに@Override getRealChildrenCount
を使用してください。代わりに@Override getChildView,
を使用して@Override getRealChildView
についても同じことを行います。
次に、アニメーションを次のように使用します。
expandableListView.setOnGroupClickListener(new AnimatedExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
if (expandableListView.isGroupExpanded(groupPosition))
expandableListView.collapseGroupWithAnimation(groupPosition);
else
expandableListView.expandGroupWithAnimation(groupPosition);
return true;
}
});
もう1つの詳細は、レイアウトxmlファイルで、AnimatedExpandableListView
ではなくExpandableListView
を参照する必要があることです。
<com.your.package.project.class.location.AnimatedExpandableListView
Android:id="@+id/listView"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
プロジェクトのサンプルコードとAnimatedExpandableListView
クラスに関するコメントは、さらにサポートが必要な場合に非常に役立ちます。