Android在开发中的实用技巧之ExpandableListView简单实现商品列表折叠
16lz
2021-01-26
根据已上线的app里总结出来的实用小技巧
一、简介
在日常开发,有可能会遇到需要一些可以展开的列表,比如QQ的好友列表。但是,用Android的该怎么做呢?其实在我没有接触过ExpandableListView
类之前,都是自定义控件继承于ListView
或者ListView
嵌套ListView
来实现的, 当然也不推荐大家这样使用, 这样使用会降低app页面的加载速度和性能. 然后,后来发现了Android
也给我们提供了ExpandableListView
类,完美实现这样类似的需求, 极大的方便了我们开发.
二、使用
- 开发工具:
- Android Studio
- 使用的第三方框架:
- Fresco 图片加载缓存框架
- AndroidAutoLayout 屏幕适配框架
Demo来自某个线上电商app的页面, 使用前先看看效果图
example.gif
-
activity_main.xml
使用AppBarLayout
来作为标题, 是因为有阴影效果, 看着还不错
是一个实现第三方适配的控件
ExpandableListView
里的android:groupIndicator="@null"
功能是去除掉默认的关闭和打开状态的图片(系统默认的不好看)
-
MainActivity.java
初始化数据
elv_collocation.expandGroup(0);
默认展开第一个
public class MainActivity extends AppCompatActivity { private ExpandableListView elv_collocation; private List collocationList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); elv_collocation = (ExpandableListView) findViewById(R.id.elv_collocation); initData(); } private void initData() { collocationList = new ArrayList<>(); CollocationPackageBean collocation_1 = new CollocationPackageBean(); CollocationPackageBean collocation_2 = new CollocationPackageBean(); collocation_1.setTotalPrice(new BigDecimal(897)); collocation_1.setDiscountFee(new BigDecimal(20)); collocation_1.setName("818国货套餐3"); List goodsList_1 = new ArrayList<>(); goodsList_1.add(new CollocationPackageBean.CollocationSkuBean("Meizu/魅族 魅蓝 note3 全网通 手机 银白 16GB", "http://img11.hqbcdn.com/product/07/0a/070ac7abd57c6d9251d89547f3d62501.jpg")); goodsList_1.add(new CollocationPackageBean.CollocationSkuBean("VR PLUS 智能眼镜vr虚拟现实头盔 3D沉浸式 暴风魔镜 vr plus 智能头盔 白色", "http://img15.hqbcdn.com/product/c6/10/c610075082199955a8d5dcf2aa765b17.jpg")); collocation_1.setCollocationSkuDoList(goodsList_1); collocation_2.setTotalPrice(new BigDecimal(1034)); collocation_2.setDiscountFee(new BigDecimal(26)); collocation_2.setName("超值套餐"); List goodsList_2 = new ArrayList<>(); goodsList_2.add(new CollocationPackageBean.CollocationSkuBean("Meizu/魅族 魅蓝 note3 全网通 手机 银白 16GB", "http://img11.hqbcdn.com/product/07/0a/070ac7abd57c6d9251d89547f3d62501.jpg")); goodsList_2.add(new CollocationPackageBean.CollocationSkuBean("Uka/优加 Meizu/魅族 魅蓝 note3全覆盖全屏钢化玻璃膜 白色", "http://img8.hqbcdn.com/product/9c/15/9c15571aa92905ea1edafb0a288f1ebb.jpg")); goodsList_2.add(new CollocationPackageBean.CollocationSkuBean("SanDisk/闪迪 至尊高速MicroSDHC-TF移动存储卡 Class10-48MB/S 升级版 16G", "http://img14.hqbcdn.com/product/29/cd/29cda69f5036b38454b6592f96fde774.jpg")); goodsList_2.add(new CollocationPackageBean.CollocationSkuBean("Huawei/华为 AM116 金属耳机 三键线控耳机 尊爵版", "http://img9.hqbcdn.com/product/0a/90/0a905d9988c91fb0625d9ee44377c8e0.jpg")); goodsList_2.add(new CollocationPackageBean.CollocationSkuBean("Lesimo/梵简 初见系列10000毫安充电宝 手机平板通用 移动电源 黑色", "http://img11.hqbcdn.com/product/67/3a/673ac0343758ce64e97c2d9986cbbef3.jpg")); collocation_2.setCollocationSkuDoList(goodsList_2); collocationList.add(collocation_1); collocationList.add(collocation_2); elv_collocation.setAdapter(new CollocationListAdapter(this, elv_collocation, collocationList)); elv_collocation.expandGroup(0); }}
-
CollocationListAdapter.java
ExpandableListView
的适配器需要继承自该控件特有的适配器BaseExpandableListAdapter
public class CollocationListAdapter extends BaseExpandableListAdapter { private LayoutInflater inflater; private Context context; private ExpandableListView elv_collocation; private List data; public CollocationListAdapter(Context context, ExpandableListView elv_collocation, List data) { this.context = context; this.elv_collocation = elv_collocation; this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.data = data; } @Override public int getGroupCount() { return data.size(); } @Override public int getChildrenCount(int groupPosition) { return data.get(groupPosition).getCollocationSkuDoList().size(); } @Override public Object getGroup(int groupPosition) { return data.get(groupPosition); } @Override public Object getChild(int groupPosition, int childPosition) { return data.get(groupPosition).getCollocationSkuDoList().get(childPosition); } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override public boolean hasStableIds() { return true; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true;//如果子条目需要响应click事件,必需返回true } @Override public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { ParentViewHolder parentViewHolder; if (null == convertView) { convertView = inflater.inflate(R.layout.collocation_list_item_parent, parent, false); parentViewHolder = new ParentViewHolder(convertView); convertView.setTag(parentViewHolder); AutoUtils.auto(convertView); } else { parentViewHolder = (ParentViewHolder) convertView.getTag(); } CollocationPackageBean collocationPackageBean = data.get(groupPosition); parentViewHolder.tv_collocation_name.setText(TextUtils.isEmpty(collocationPackageBean.getName()) ? "优惠套餐" : collocationPackageBean.getName()); parentViewHolder.tv_save_text.setText("立省¥" + collocationPackageBean.getDiscountFee()); parentViewHolder.iv_status.setImageResource(isExpanded ? R.mipmap.icon_top : R.mipmap.icon_bottom); parentViewHolder.v_space.setVisibility(isExpanded ? View.GONE : View.VISIBLE); parentViewHolder.hsv_goods_list.setVisibility(isExpanded ? View.GONE : View.VISIBLE); parentViewHolder.hsv_goods_list.setFocusable(false);//设置后解决套餐无法正常展开的bug if (!isExpanded) { //设置套餐折叠时显示套餐商品的图片 initGoodsImage(collocationPackageBean, parentViewHolder, groupPosition); } return convertView; } @Override public View getChildView(final int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildViewHolder childViewHolder; if (null == convertView) { convertView = inflater.inflate(R.layout.collocation_list_item_child, parent, false); childViewHolder = new ChildViewHolder(convertView); convertView.setTag(childViewHolder); AutoUtils.auto(convertView); } else { childViewHolder = (ChildViewHolder) convertView.getTag(); } final CollocationPackageBean.CollocationSkuBean collocationSkuBean = data.get(groupPosition).getCollocationSkuDoList().get(childPosition); childViewHolder.sdv_goods_img.setImageURI(Uri.parse(collocationSkuBean.getImageMd5())); childViewHolder.tv_goods_title.setText(collocationSkuBean.getSkuTitle()); childViewHolder.ll_root_view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //进入商品详情页操作 } }); if (childPosition == data.get(groupPosition).getCollocationSkuDoList().size() - 1) { //当前套餐的最后一个商品 childViewHolder.ll_bottom.setVisibility(View.VISIBLE); childViewHolder.tv_collocation_price.setText(data.get(groupPosition).getTotalPrice().toString()); childViewHolder.tv_add_cart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //把套餐商品加入购物车操作 } }); } else { childViewHolder.ll_bottom.setVisibility(View.GONE); } return convertView; } class ParentViewHolder { private View v_space; private ImageView iv_status; private HorizontalScrollView hsv_goods_list; private TextView tv_collocation_name, tv_save_text; private ParentViewHolder (View view) { v_space = view.findViewById(R.id.v_space); iv_status = (ImageView) view.findViewById(R.id.iv_status); hsv_goods_list = (HorizontalScrollView) view.findViewById(R.id.hsv_goods_list); tv_collocation_name = (TextView) view.findViewById(R.id.tv_collocation_name); tv_save_text = (TextView) view.findViewById(R.id.tv_save_text); } } private class ChildViewHolder { private SimpleDraweeView sdv_goods_img; private LinearLayout ll_bottom, ll_root_view; private TextView tv_add_cart, tv_goods_title, tv_collocation_price; private ChildViewHolder (View view) { sdv_goods_img = (SimpleDraweeView) view.findViewById(R.id.sdv_goods_img); ll_bottom = (LinearLayout) view.findViewById(R.id.ll_bottom); ll_root_view = (LinearLayout) view.findViewById(R.id.ll_root_view); tv_add_cart = (TextView) view.findViewById(R.id.tv_add_cart); tv_goods_title = (TextView) view.findViewById(R.id.tv_goods_title); tv_collocation_price = (TextView) view.findViewById(R.id.tv_collocation_price); } } /** * 初始化并设置套餐折叠时的所有商品图片 * @param collocationPackageBean * @param parentViewHolder * @param groupPosition */ private void initGoodsImage(CollocationPackageBean collocationPackageBean, ParentViewHolder parentViewHolder, final int groupPosition) { View collocationView; SimpleDraweeView sdv_cart_image; RelativeLayout rl_middle; LinearLayout rootview = new LinearLayout(context); for (int i = 0, len = collocationPackageBean.getCollocationSkuDoList().size(); i < len; i++) { collocationView = inflater.inflate(R.layout.item_gift_img, null); sdv_cart_image = (SimpleDraweeView) collocationView.findViewById(R.id.sdv_cart_image); rl_middle = (RelativeLayout) collocationView.findViewById(R.id.rl_middle); sdv_cart_image.setImageURI(Uri.parse(collocationPackageBean.getCollocationSkuDoList().get(i).getImageMd5())); rl_middle.setVisibility(View.INVISIBLE); collocationView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //手动实现展开操作 elv_collocation.expandGroup(groupPosition); } }); AutoUtils.auto(collocationView); rootview.addView(collocationView); } parentViewHolder.hsv_goods_list.removeAllViews(); parentViewHolder.hsv_goods_list.addView(rootview); }}
-
collocation_list_item_child.xml
套餐子布局
-
collocation_list_item_parent.xml
套餐父布局
-
item_gift_img.xml
图片item布局
SimpleDraweeView
是Fresco
里的控件, 显示网络图片
-
CollocationPackageBean.java
存放数据的bean
public class CollocationPackageBean { private BigDecimal totalPrice; private String name; private List collocationSkuDoList; private BigDecimal discountFee; public static class CollocationSkuBean { private String skuTitle; private String imageMd5; public CollocationSkuBean(String skuTitle, String imageMd5) { this.skuTitle = skuTitle; this.imageMd5 = imageMd5; } set... get.. } set... get...}
几个主要的文件就这几个
其他哪些shape, selector文件之类的就没有必要贴上来了
需要要看详细的代码看这里
github源码地址 欢迎star、fork
更多相关文章
- Unity与EasyAR
- Android(安卓)Studio开发学习(一)—— 布局
- Cursor与Adapter结合使用
- Android(安卓)微信分享,无需那么麻烦。
- [置顶] Android图片异步加载之Android-Universal-Image-Loader
- 粗暴快速Android全屏幕适配方案
- android 9PNG图片制作
- Android仿照薄荷appBMI控件实现
- Android(安卓)高仿微信发朋友圈浏览图片效果