使用listview的展开和收起效果
来源:互联网 发布:知乎 特朗普 编辑:程序博客网 时间:2024/04/29 09:11
在实际项目中,许多地方都会用到类似ExpandableListView的效果,但是实际使用ExpandableListView的时候比较复杂,而且这个控件展开的时候会改变它的下标。比如: 点击展开第二项的子item时,子item的第一个下标为2,这样计算点击事件就比较复杂。 所以我想了思路比较的简单的,比较容易实现的方法。
大概思路是这样的:在布局中使用一个button加一个listview作为一个整体,设置listview为隐藏。然后点击button就设置listview可见,这样就基本实现ExpandableListView的功能。 只是这个方法比较笨,代码冗余比较多,还请多多包涵。
效果如下
package com.example.exapmples;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import android.view.animation.Transformation;import android.widget.AdapterView;import android.widget.ImageView;import android.widget.ListAdapter;import android.widget.ListView;import android.widget.RadioButton;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class MainActivity extends Activity implements View.OnClickListener{ private ListView listView1,listView2,listView3; private ImageView img1,img2,img3; private TextView textview1 ,textview2,textview3; private RelativeLayout relative1,relative2,relative3; private List<String> list=new ArrayList<String>(); private MyAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { listView1= (ListView) findViewById(R.id.list1); listView2= (ListView) findViewById(R.id.list2); listView3= (ListView) findViewById(R.id.list3); img1= (ImageView) findViewById(R.id.img1); img2= (ImageView) findViewById(R.id.img2); img3= (ImageView) findViewById(R.id.img3); textview1= (TextView) findViewById(R.id.textview1); textview2= (TextView) findViewById(R.id.textview2); textview3= (TextView) findViewById(R.id.textview3); relative1= (RelativeLayout) findViewById(R.id.relative1); relative2= (RelativeLayout) findViewById(R.id.relative2); relative3= (RelativeLayout) findViewById(R.id.relative3); relative1.setOnClickListener(this); relative2.setOnClickListener(this); relative3.setOnClickListener(this); for (int i =0 ; i < 5 ; i++){ list.add("item"+i); } adapter =new MyAdapter(this,list); listView1.setAdapter(adapter); listView2.setAdapter(adapter); listView3.setAdapter(adapter); listView1.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { click1(parent,view ,position); } }); listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { click2(parent,view ,position); } }); listView3.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { click3(parent,view ,position); } }); } private int clickposition1 =-1 ,clickposition2 =-1,clickposition3 =-1; private void click1(AdapterView<?> parent, View view, int position){ RadioButton rb = (RadioButton) view.findViewById(R.id.rd); if (rb != null) { rb.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.enlarge_out)); if (clickposition1 == position){ if (rb.isChecked()){ rb.setChecked(false); Toast.makeText(this,"取消第"+position+"项",Toast.LENGTH_SHORT).show(); } else{ rb.setChecked(true); Toast.makeText(this,"选中第"+position+"项",Toast.LENGTH_SHORT).show(); } } else{ clickposition1 = position; //这个相当于listview中checkbox的单选,还比较方便 rb.setChecked(true); Toast.makeText(this,"选中第"+position+"项",Toast.LENGTH_SHORT).show(); for (int i = 0; i < parent.getChildCount(); i++) { if (i != position) { View v = parent.getChildAt(i); if (v != view) { RadioButton iv2 = (RadioButton) v .findViewById(R.id.rd); iv2.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.small_out)); iv2.setChecked(false); }else{ rb.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.enlarge_out)); rb.setChecked(false); } } } } } } private void click2(AdapterView<?> parent, View view, int position){ RadioButton rb = (RadioButton) view.findViewById(R.id.rd); if (rb != null) { rb.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.enlarge_out)); if (clickposition2 == position){ if (rb.isChecked()){ rb.setChecked(false); Toast.makeText(this,"取消第"+position+"项",Toast.LENGTH_SHORT).show(); } else{ rb.setChecked(true); Toast.makeText(this,"选中第"+position+"项",Toast.LENGTH_SHORT).show(); } } else{ clickposition2 = position; rb.setChecked(true); Toast.makeText(this,"选中第"+position+"项",Toast.LENGTH_SHORT).show(); for (int i = 0; i < parent.getChildCount(); i++) { if (i != position) { View v = parent.getChildAt(i); if (v != view) { RadioButton iv2 = (RadioButton) v .findViewById(R.id.rd); iv2.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.small_out)); iv2.setChecked(false); }else{ rb.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.enlarge_out)); rb.setChecked(false); } } } } } } private void click3(AdapterView<?> parent, View view, int position){ RadioButton rb = (RadioButton) view.findViewById(R.id.rd); if (rb != null) { rb.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.enlarge_out)); if (clickposition3 == position){ if (rb.isChecked()){ rb.setChecked(false); Toast.makeText(this,"取消第"+position+"项",Toast.LENGTH_SHORT).show(); } else{ rb.setChecked(true); Toast.makeText(this,"选中第"+position+"项",Toast.LENGTH_SHORT).show(); } } else{ clickposition3 = position; rb.setChecked(true); Toast.makeText(this,"选中第"+position+"项",Toast.LENGTH_SHORT).show(); for (int i = 0; i < parent.getChildCount(); i++) { if (i != position) { View v = parent.getChildAt(i); if (v != view) { RadioButton iv2 = (RadioButton) v .findViewById(R.id.rd); iv2.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.small_out)); iv2.setChecked(false); }else{ rb.startAnimation(AnimationUtils.loadAnimation(MainActivity.this, R.anim.enlarge_out)); rb.setChecked(false); } } } } } } @Override public void onClick(View v) { switch (v.getId()){ case R.id.relative1: getListViewVisiable(listView1 ,img1); setVisiable(listView2 ,img2); setVisiable(listView3 ,img3); break; case R.id.relative2: getListViewVisiable(listView2 ,img2); setVisiable(listView1 ,img1); setVisiable(listView3 ,img3); break; case R.id.relative3: getListViewVisiable(listView3 ,img3); setVisiable(listView2 ,img2); setVisiable(listView1 ,img1); break; } } public void getListViewVisiable(ListView listView ,ImageView img){ if (listView.getVisibility() == View.GONE){ expand(listView ,img); }else if (listView.getVisibility() == View.VISIBLE){ unexpand(listView ,img); } } public void setVisiable(ListView listView ,ImageView img){ if (listView.getVisibility() == View.VISIBLE){ unexpand(listView ,img); } } /** * 展开 */ public void expand(final ListView listView ,ImageView img) { final int targtetHeight = getListViewHeightBasedOnChildren(listView); Log.d("targtetHeight" , targtetHeight+""); listView.setVisibility(View.VISIBLE); listView.getLayoutParams().height = 0; Animation a = new Animation() { //这个方法中根据设置动画的时长逐步绘制listview,然后调用requestLayout()方法,再去调用 //listview的measure方法重新绘制view。 @Override protected void applyTransformation(float interpolatedTime, Transformation t) { listView.getLayoutParams().height = interpolatedTime == 1 ? ViewGroup.LayoutParams.WRAP_CONTENT : (int) (targtetHeight * interpolatedTime); listView.requestLayout(); } @Override public boolean willChangeBounds() { return true; } }; // 1dp/ms a.setDuration(500); listView.startAnimation(a); //这个动画设置图片的旋转,setFillAfter表示动画执行完毕后停留在最后的位置 Animation anim= AnimationUtils.loadAnimation(this,R.anim.rotate); anim.setFillAfter(true); img.startAnimation(anim); } /** * 收起 * @param listView */ public void unexpand(final ListView listView ,ImageView img){ final int initialHeight =listView. getMeasuredHeight(); Animation a = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { if (interpolatedTime == 1) { listView.setVisibility(View.GONE); listView.getLayoutParams().height= initialHeight; } else { listView.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime); listView.requestLayout(); } } @Override public boolean willChangeBounds() { return true; } }; // 1dp/ms a.setDuration(500); listView.startAnimation(a); Animation anim= AnimationUtils.loadAnimation(this,R.anim.roatate1); img.startAnimation(anim); } /* * 动态设置ListView的高度 * * */ public int getListViewHeightBasedOnChildren(ListView listView) { ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { return 0; } int totalHeight = 0; for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); totalHeight += listItem.getMeasuredHeight(); } return totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); }}
然后是listview的adapter
package com.example.exapmples;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.RadioButton;import android.widget.TextView;import java.util.List;/** * Created by yubo on 2016/8/12. */public class MyAdapter extends BaseAdapter { private Context context; private List<String> list; public MyAdapter(Context context , List<String> list){ this.context=context; this.list=list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null){ convertView = LayoutInflater.from(context).inflate(R.layout.listitem ,null); RadioButton rb=(RadioButton) convertView.findViewById(R.id.rd); TextView item_name=(TextView) convertView.findViewById(R.id.item_name); item_name.setText(list.get(position)); } return convertView; }}
布局文件
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:id="@+id/relative1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp"> <TextView android:id="@+id/textview1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:padding="10dp" android:text="@string/text_name1" android:textColor="@color/colorAccent" android:textSize="16sp" /> <ImageView android:id="@+id/img1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="20dp" android:src="@drawable/arrow_bottom_black" /> </RelativeLayout> <View android:layout_width="match_parent" android:layout_height="0.5dp" android:background="@color/gray" /> <ListView android:id="@+id/list1" android:divider="@null" android:scrollbars="none" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone"></ListView> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:id="@+id/relative2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp"> <TextView android:id="@+id/textview2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:padding="10dp" android:text="@string/text_name2" android:textColor="@color/colorAccent" android:textSize="16sp" /> <ImageView android:id="@+id/img2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="20dp" android:src="@drawable/arrow_bottom_black" /> </RelativeLayout> <View android:layout_width="match_parent" android:layout_height="0.5dp" android:background="@color/gray" /> <ListView android:id="@+id/list2" android:divider="@null" android:scrollbars="none" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone"></ListView> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RelativeLayout android:id="@+id/relative3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp"> <TextView android:id="@+id/textview3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:padding="10dp" android:text="@string/text_name3" android:textColor="@color/colorAccent" android:textSize="16sp" /> <ImageView android:id="@+id/img3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="20dp" android:src="@drawable/arrow_bottom_black" /> </RelativeLayout> <View android:layout_width="match_parent" android:layout_height="0.5dp" android:background="@color/gray" /> <ListView android:id="@+id/list3" android:divider="@null" android:scrollbars="none" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone"></ListView> </LinearLayout></LinearLayout>
adapter的item布局
<?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:gravity="center_vertical" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_gravity="center_vertical" android:paddingBottom="10dp"> <RadioButton android:id="@+id/rd" android:layout_width="35dp" android:layout_height="35dp" android:layout_gravity="center" android:background="@drawable/btn_selector" android:button="@null" android:clickable="false" android:focusable="false" /> <TextView android:id="@+id/item_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:singleLine="true" android:textColor="@color/colorAccent" /> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="0.5dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@color/gray" /></LinearLayout>
最后附上github地址
https://github.com/jokeryubo/listtoexpand
0 0
- 使用listview的展开和收起效果
- UITableView 的展开和 收起
- cell的展开和收起
- 文章收起与展开效果的实现
- 展开与收起效果
- js 展开收起效果
- 展开与收起效果
- 收起与展开效果
- Android ListView点击展开收起效果(一)
- 可展开和收起的LinearLayout
- 可展开和收起的LinearLayout
- 可展开和收起的LinearLayout
- 可展开和收起的LinearLayout
- js实现菜单的收起和展开
- webView 收起和展开
- TextView展开和收起
- 纯CSS3实现移动端展开和收起效果
- 带展开更多收起更多的可扩展的ListView
- 欧拉
- 使用 Emmet 生成 HTML 的语法详解
- 对比JAVA学习PHP系列:入门简介
- 支付系统高可用架构设计实战
- ViewFlipper网络图片加载及关联导航按钮
- 使用listview的展开和收起效果
- 书单
- EL表达式详解 转自 Imust_can
- UML--再谈用例图和静态图
- 《构建之法》读书笔记——第5章 团队和流程
- XListView的简单Demo
- 人脸识别-再识(二)
- 序列化二叉树
- 数据结构与算法系列----B树、B+树与B*树简介