Android-android如何实现一个可以展开和叠起每一项的listview?

Android-android如何实现一个可以展开和叠起每一项的listview?

泛泛之交 发布于 2017-04-06 字数 71 浏览 1062 回复 3

点击每一项可以看这项的详细内容。最好是在展开和收缩的时候有动画。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜无邪 2017-10-29 3 楼

做过这个效果,关键是动画的实现,
list的主代码

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;

public class ExpandAnimationDemo extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //To change body of overridden methods use File | Settings | File Templates.
setContentView(R.layout.main);

ListView list = (ListView)findViewById(R.id.udiniList);

// Creating the list adapter and populating the list
ArrayAdapter<String> listAdapter = new CustomListAdapter(this, R.layout.list_item);
for (int i=0; i<20;i++)
listAdapter.add("udini"+i);
list.setAdapter(listAdapter);

// Creating an item click listener, to open/close our toolbar for each item
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {

View toolbar = view.findViewById(R.id.toolbar);

// Creating the expand animation for the item
ExpandAnimation expandAni = new ExpandAnimation(toolbar, 500);

// Start the animation on the toolbar
toolbar.startAnimation(expandAni);
}
});
}

/**
* A simple implementation of list adapter.
*/
class CustomListAdapter extends ArrayAdapter<String> {

public CustomListAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.list_item, null);
}

((TextView)convertView.findViewById(R.id.title)).setText(getItem(position));

// Resets the toolbar to be closed
View toolbar = convertView.findViewById(R.id.toolbar);
((LinearLayout.LayoutParams) toolbar.getLayoutParams()).bottomMargin = -50;
toolbar.setVisibility(View.GONE);

return convertView;
}
}
}

**关键的动画模块实现**

import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.LinearLayout.LayoutParams;

/**
* This animation class is animating the expanding and reducing the size of a view.
* The animation toggles between the Expand and Reduce, depending on the current state of the view
* @author Udinic
*
*/
public class ExpandAnimation extends Animation {
private View mAnimatedView;
private LayoutParams mViewLayoutParams;
private int mMarginStart, mMarginEnd;
private boolean mIsVisibleAfter = false;
private boolean mWasEndedAlready = false;

/**
* Initialize the animation
* @param view The layout we want to animate
* @param duration The duration of the animation, in ms
*/
public ExpandAnimation(View view, int duration) {

setDuration(duration);
mAnimatedView = view;
mViewLayoutParams = (LayoutParams) view.getLayoutParams();

// if the bottom margin is 0,
// then after the animation will end it'll be negative, and invisible.
mIsVisibleAfter = (mViewLayoutParams.bottomMargin == 0);

mMarginStart = mViewLayoutParams.bottomMargin;
mMarginEnd = (mMarginStart == 0 ? (0- view.getHeight()) : 0);

view.setVisibility(View.VISIBLE);
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);

if (interpolatedTime < 1.0f) {

// Calculating the new bottom margin, and setting it
mViewLayoutParams.bottomMargin = mMarginStart
+ (int) ((mMarginEnd - mMarginStart) * interpolatedTime);

// Invalidating the layout, making us seeing the changes we made
mAnimatedView.requestLayout();

// Making sure we didn't run the ending before (it happens!)
} else if (!mWasEndedAlready) {
mViewLayoutParams.bottomMargin = mMarginEnd;
mAnimatedView.requestLayout();

if (mIsVisibleAfter) {
mAnimatedView.setVisibility(View.GONE);
}
mWasEndedAlready = true;
}
}

布局文件maim.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>

<ListView android:id="@+id/udiniList"
android:layout_height="fill_parent"
android:layout_width="fill_parent"></ListView>

</LinearLayout>

list_item.xml

 <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/title"
android:padding="20dip"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_width="fill_parent"
android:layout_height="wrap_content"></TextView>

<!--***********************-->
<!--*** TOOLBAR LAYOUT ****-->
<!--***********************-->

<LinearLayout android:id="@+id/toolbar"
android:layout_marginBottom="-50dip"
android:visibility="gone"
android:layout_height="50dip"
android:layout_width="fill_parent">
<Button android:id="@+id/doSomething1"
android:layout_height="50dip"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_width="wrap_content"
android:text="Harder"></Button>
<Button android:id="@+id/doSomething2"
android:layout_height="50dip"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_width="wrap_content"
android:text="Better"></Button>
<Button android:id="@+id/doSomething3"
android:layout_height="50dip"
android:layout_width="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Faster"></Button>
<Button android:id="@+id/doSomething4"
android:layout_height="50dip"
android:layout_width="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false"
android:text="Stronger"></Button>

</LinearLayout>
</LinearLayout>

想挽留 2017-04-28 2 楼

上面的我试了,不行,只是显示了view之后再往下晃动一下,下面的可以做伸缩

 import java.lang.reflect.Method;

import android.view.View;
import android.view.View.MeasureSpec;
import android.view.animation.Animation;
import android.view.animation.Transformation;

public class ExpandAnimationUtil {

/**展开伸缩动画*/
public static Animation expand(final View v, final boolean expand,
long duration) {
try {
Method m = v.getClass().getDeclaredMethod("onMeasure", int.class,
int.class);
m.setAccessible(true);
m.invoke(v,
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(
((View) v.getParent()).getMeasuredWidth(),
MeasureSpec.AT_MOST));
} catch (Exception e) {
e.printStackTrace();
}
final int initialHeight = v.getMeasuredHeight();
if (expand) {
v.getLayoutParams().height = 0;
} else {
v.getLayoutParams().height = initialHeight;
}
v.setVisibility(View.VISIBLE);
Animation a = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
int newHeight = 0;
if (expand) {
newHeight = (int) (initialHeight * interpolatedTime);
} else {
newHeight = (int) (initialHeight * (1- interpolatedTime));
}
v.getLayoutParams().height = newHeight;
v.requestLayout();
if (interpolatedTime == 1 && !expand)
v.setVisibility(View.GONE);
}

@Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration(duration);
return a;
}
}

调用方法

  Animation expandAnimation = ExpandAnimationUtil.expand(mMoreLayout,
true, 1000);
mMoreLayout.startAnimation(expandAnimation);

参考自http://softsoulandroid.wordpress.com/2012/01/21/android-view-expandcollapse-animation/

清晨说ぺ晚安 2017-04-20 1 楼

1、首先创建我们的Activity,继承 android.app.ExpandableListActivity。

 package com.ideasandroid.sample;
import android.app.ExpandableListActivity;
import android.os.Bundle;
import com.ideasandroid.sample.adapter.IdeasExpandableListAdapter;
/**
* @author IdeasAndroid
* 可展开(收缩)列表示例
*/

public class IdeasExpandableListView extends ExpandableListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置列表适配器IdeasExpandableListAdapter
setListAdapter(new IdeasExpandableListAdapter(this));
}
}

2、创建适配器,继承android.widget.BaseExpandableListAdapter。

 package com.ideasandroid.sample.adapter;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
/**
* @author IdeasAndroid
* 可展开(收缩)列表示例
*/

public class IdeasExpandableListAdapter extends BaseExpandableListAdapter {
private Context mContext = null;
// 测试数据,开发时可能来自数据库,网络....
private String[] groups = { "家人", "朋友", "同事" };
private String[] familis = { "老爸", "老妈", "妹妹" };
private String[] friends = { "小李", "张三", "李四" };
private String[] colleagues = { "陈总", "李工", "李客户" };
private List<String> groupList = null;
private List<List<String>> itemList = null;
public IdeasExpandableListAdapter(Context context) {
this.mContext = context;
groupList = new ArrayList<String>();
itemList = new ArrayList<List<String>>();
initData();
}
/**
* 初始化数据,将相关数据放到List中,方便处理
*/

private void initData() {
for (int i = 0; i < groups.length; i++) {
groupList.add(groups[i]);
}

List<String> item1 = new ArrayList<String>();
for (int i = 0; i < familis.length; i++) {
item1.add(familis[i]);
}

List<String> item2 = new ArrayList<String>();
for (int i = 0; i < friends.length; i++) {
item2.add(friends[i]);
}

List<String> item3 = new ArrayList<String>();

for (int i = 0; i < colleagues.length; i++) {
item3.add(colleagues[i]);
}

itemList.add(item1);
itemList.add(item2);
itemList.add(item3);

}

public boolean areAllItemsEnabled() {
return false;
}

/*

* 设置子节点对象,在事件处理时返回的对象,可存放一些数据

*/

public Object getChild(int groupPosition, int childPosition) {
return itemList.get(groupPosition).get(childPosition);
}

public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}

/*

* 字节点视图,这里我们显示一个文本对象

*/

public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
TextView text = null;

if (convertView == null) {
text = new TextView(mContext);
} else {
text = (TextView) convertView;
}

// 获取子节点要显示的名称

String name = (String) itemList.get(groupPosition).get(childPosition);

// 设置文本视图的相关属性

AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 40);
text.setLayoutParams(lp);
text.setTextSize(18);
text.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
text.setPadding(45, 0, 0, 0);
text.setText(name);
return text;
}

/*

* 返回当前分组的字节点个数

*/

public int getChildrenCount(int groupPosition) {
return itemList.get(groupPosition).size();
}

/*

* 返回分组对象,用于一些数据传递,在事件处理时可直接取得和分组相关的数据

*/

public Object getGroup(int groupPosition) {
return groupList.get(groupPosition);
}

/*

* 分组的个数

*/

public int getGroupCount() {
return groupList.size();
}

public long getGroupId(int groupPosition) {
return groupPosition;
}

/*
* 分组视图,这里也是一个文本视图
*/

public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
TextView text = null;
if (convertView == null) {
text = new TextView(mContext);
} else {
text = (TextView) convertView;
}

String name = (String) groupList.get(groupPosition);

AbsListView.LayoutParams lp = new AbsListView.LayoutParams(

ViewGroup.LayoutParams.FILL_PARENT, 40);

text.setLayoutParams(lp);

text.setTextSize(18);

text.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);

text.setPadding(36, 0, 0, 0);

text.setText(name);

return text;

}

/*

* 判断分组是否为空,本示例中数据是固定的,所以不会为空,我们返回false

* 如果数据来自数据库,网络时,可以把判断逻辑写到这个方法中,如果为空

* 时返回true

*/

public boolean isEmpty() {

return false;

}

/*

* 收缩列表时要处理的东西都放这儿

*/

public void onGroupCollapsed(int groupPosition) {

}

/*

* 展开列表时要处理的东西都放这儿

*/

public void onGroupExpanded(int groupPosition) {

}

/*

* Indicates whether the child and group IDs are stable across changes to

* the underlying data.

*/

public boolean hasStableIds() {

return false;

}

/*

* Whether the child at the specified position is selectable.

*/

public boolean isChildSelectable(int groupPosition, int childPosition) {

return true;

}

}