Android RecyclerView(超简单)实现可展开列表——单项展开
来源:互联网 发布:pptv网络电视在线直播 编辑:程序博客网 时间:2024/06/06 04:39
之前写过 Android -- RecyclerView(超简单)实现可展开列表 的一篇文章,通过增加、删除的方式来模拟实现展开、收起的功能,思路很简单,也比较实用,最近看到评论里有猿友提出只展开一行的需求,并且还有猿友跟着提问,索性就再专门写一篇。
只展开一行,也就是说当有一行处于展开的情况下再点击另外一行,另外一行展开,原本展开的那一行收起。好了,需求明确了,那我们要如何实现呢?
最简单的方法就是标记展开的item,将当前展开的item标记(也可以说是封装保存起来)。多说无用,上码:
注意:此篇是在之前写过的那篇文章的基础上拓展的,以下代码为根据需求修改的代码,没看过原篇的建议先看这篇
先看效果图:
代码改动不多,首先我们需要再定义一个类:
public class ItemData { public DataBean dataBean;//数据类 public View view;//展开的item,一定要将view一起封装起来,否则会有问题的。 public DataBean getDataBean() { return dataBean; } public void setDataBean(DataBean dataBean) { this.dataBean = dataBean; } public View getView() { return view; } public void setView(View view) { this.view = view; }}封装
import java.util.ArrayList;import java.util.List;/** * Created by hbh on 2017/8/15. * 封装item 及 增删操作 */public class EncapsulationItem { public static List<ItemData> lastBeanList = new ArrayList<>(); //将展开的item添加到list中 public static void addLastBeanData(ItemData beanData){ lastBeanList.add(beanData); } //清空list public static void cleraListBeanData(){ lastBeanList.clear(); }}这里用List作为容器。
import android.animation.ValueAnimator;import android.annotation.TargetApi;import android.content.Context;import android.os.Build;import android.view.View;import android.view.animation.DecelerateInterpolator;import android.widget.ImageView;import android.widget.RelativeLayout;import android.widget.TextView;import com.hbh.cl.expandrecyclerviewdemo.R;import com.hbh.cl.expandrecyclerviewdemo.model.DataBean;import com.hbh.cl.expandrecyclerviewdemo.util.ItemData;import com.hbh.cl.expandrecyclerviewdemo.util.EncapsulationItem;/** * Created by hbh on 2017/4/20. * 父布局ViewHolder */public class ParentViewHolder extends BaseViewHolder { private Context mContext; private View view; private RelativeLayout containerLayout; private TextView parentLeftView; private TextView parentRightView; private ImageView expand; private View parentDashedView; private ItemData itemData; public ParentViewHolder(Context context, View itemView) { super(itemView); this.mContext = context; this.view = itemView; } public void bindView(final DataBean dataBean, final int pos, final ItemClickListener listener){ containerLayout = (RelativeLayout) view.findViewById(R.id.container); parentLeftView = (TextView) view.findViewById(R.id.parent_left_text); parentRightView = (TextView) view.findViewById(R.id.parent_right_text); expand = (ImageView) view.findViewById(R.id.expend); parentDashedView = view.findViewById(R.id.parent_dashed_view); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) expand .getLayoutParams(); expand.setLayoutParams(params); parentLeftView.setText(dataBean.getParentLeftTxt()); parentRightView.setText(dataBean.getParentRightTxt()); if (dataBean.isExpand()) { expand.setRotation(90); parentDashedView.setVisibility(View.INVISIBLE); } else { expand.setRotation(0); parentDashedView.setVisibility(View.VISIBLE); } //父布局OnClick监听 containerLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (listener != null) { itemData = new ItemData(); if (EncapsulationItem.lastBeanList.size() > 0 && !EncapsulationItem.lastBeanList.get(0).getDataBean().getID().equals(dataBean.getID())) { //如果有展开的item,先关闭 listener.onHideChildren(EncapsulationItem.lastBeanList.get(0).getDataBean()); EncapsulationItem.lastBeanList.get(0).getView().findViewById(R.id.parent_dashed_view).setVisibility(View.VISIBLE); EncapsulationItem.lastBeanList.get(0).getDataBean().setExpand(false); rotationExpandIcon(90, 0, EncapsulationItem.lastBeanList.get(0).getView().findViewById(R.id.expend)); EncapsulationItem.cleraListBeanData();//清空集合 } if (dataBean.isExpand()) { listener.onHideChildren(dataBean); parentDashedView.setVisibility(View.VISIBLE); EncapsulationItem.cleraListBeanData(); dataBean.setExpand(false); rotationExpandIcon(90, 0, expand); } else { listener.onExpandChildren(dataBean); itemData.setDataBean(dataBean); itemData.setView(view); EncapsulationItem.addLastBeanData(itemData); parentDashedView.setVisibility(View.INVISIBLE); dataBean.setExpand(true); rotationExpandIcon(0, 90, expand); } } } }); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) private void rotationExpandIcon(float from, float to, final View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { ValueAnimator valueAnimator = ValueAnimator.ofFloat(from, to);//属性动画 valueAnimator.setDuration(500); valueAnimator.setInterpolator(new DecelerateInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { view.setRotation((Float) valueAnimator.getAnimatedValue()); } }); valueAnimator.start(); } }}这段代码中主要就是改动了父布局OnClick监听那一块,当我们点击父布局展开的时候先判断有没有展开状态的item,如果有,则先关闭,并清空List。然后在后面是否展开的判断中对List操作,很简单,就是展开增加、收起清除,一看就明白。
最后建议把滚动监听给去掉,实则没什么卵用,还会因为RecyclerView的复用出现问题,当向上滚动时,底部会闪现当前展开的item,虽然不会出现什么问题。
import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.hbh.cl.expandrecyclerviewdemo.R;import com.hbh.cl.expandrecyclerviewdemo.model.DataBean;import java.util.List;/** * Created by hbh on 2017/4/20. * 适配器 */public class RecyclerAdapter extends RecyclerView.Adapter<BaseViewHolder> { private Context context; private List<DataBean> dataBeanList; private LayoutInflater mInflater; private OnScrollListener mOnScrollListener; public RecyclerAdapter(Context context, List<DataBean> dataBeanList) { this.context = context; this.dataBeanList = dataBeanList; this.mInflater = LayoutInflater.from(context); } @Override public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = null; switch (viewType){ case DataBean.PARENT_ITEM: view = mInflater.inflate(R.layout.recycleview_item_parent, parent, false); return new ParentViewHolder(context, view); case DataBean.CHILD_ITEM: view = mInflater.inflate(R.layout.recycleview_item_child, parent, false); return new ChildViewHolder(context, view); default: view = mInflater.inflate(R.layout.recycleview_item_parent, parent, false); return new ParentViewHolder(context, view); } } /** * 根据不同的类型绑定View * @param holder * @param position */ @Override public void onBindViewHolder(BaseViewHolder holder, int position) { switch (getItemViewType(position)){ case DataBean.PARENT_ITEM: ParentViewHolder parentViewHolder = (ParentViewHolder) holder; parentViewHolder.bindView(dataBeanList.get(position), position, itemClickListener); break; case DataBean.CHILD_ITEM: ChildViewHolder childViewHolder = (ChildViewHolder) holder; childViewHolder.bindView(dataBeanList.get(position), position); break; } } @Override public int getItemCount() { return dataBeanList.size(); } @Override public int getItemViewType(int position) { return dataBeanList.get(position).getType(); } private ItemClickListener itemClickListener = new ItemClickListener() { @Override public void onExpandChildren(DataBean bean) { int position = getCurrentPosition(bean.getID());//确定当前点击的item位置 DataBean children = getChildDataBean(bean);//获取要展示的子布局数据对象,注意区分onHideChildren方法中的getChildBean()。 if (children == null) { return; } add(children, position + 1);//在当前的item下方插入 if (position == dataBeanList.size() - 2 && mOnScrollListener != null) { //如果点击的item为最后一个// mOnScrollListener.scrollTo(position + 1);//向下滚动,使子布局能够完全展示 } } @Override public void onHideChildren(DataBean bean) { int position = getCurrentPosition(bean.getID());//确定当前点击的item位置 DataBean children = bean.getChildBean();//获取子布局对象 if (children == null) { return; } remove(position + 1);//删除 if (mOnScrollListener != null) {// mOnScrollListener.scrollTo(position); } } }; /** * 在父布局下方插入一条数据 * @param bean * @param position */ public void add(DataBean bean, int position) { dataBeanList.add(position, bean); notifyItemInserted(position); } /** *移除子布局数据 * @param position */ protected void remove(int position) { dataBeanList.remove(position); notifyItemRemoved(position); } /** * 确定当前点击的item位置并返回 * @param uuid * @return */ protected int getCurrentPosition(String uuid) { for (int i = 0; i < dataBeanList.size(); i++) { if (uuid.equalsIgnoreCase(dataBeanList.get(i).getID())) { return i; } } return -1; } /** * 封装子布局数据对象并返回 * 注意,此处只是重新封装一个DataBean对象,为了标注Type为子布局数据,进而展开,展示数据 * 要和onHideChildren方法里的getChildBean()区分开来 * @param bean * @return */ private DataBean getChildDataBean(DataBean bean){ DataBean child = new DataBean(); child.setType(1); child.setParentLeftTxt(bean.getParentLeftTxt()); child.setParentRightTxt(bean.getParentRightTxt()); child.setChildLeftTxt(bean.getChildLeftTxt()); child.setChildRightTxt(bean.getChildRightTxt()); return child; } /** * 滚动监听接口 */ public interface OnScrollListener{ void scrollTo(int pos); } public void setOnScrollListener(OnScrollListener onScrollListener){ this.mOnScrollListener = onScrollListener; }}
好了,就那么多,改动很少,代码就不上传了,下载下来之前github上的代码,然后直接拷过去替换掉就可以了。
有问题,欢迎来砸。
收工。
阅读全文
1 0
- Android RecyclerView(超简单)实现可展开列表——单项展开
- Android -- RecyclerView(超简单)实现可展开列表
- Android -- RecyclerView(超简单)实现可展开列表
- 可展开的列表组件——ExpandableListView简单举例
- 使用RecyclerView 简单实现QQ好友列表展开效果
- 可展开列表ExpandableListView—SimpleExpandableListAdpater
- 可展开列表ExpandableListView—BaseExpandableListAdapter
- 使用RecyclerView实现列表展开动画
- 自定义Adapter实现RecyclerView的可展开二级列表expand效果
- Android之可收缩展开列表ExpandableList
- Android 可展开列表组件 ExpandableListView
- 可展开的列表组件——ExpandableListView深入解析
- ExpandableView(可展开的列表组件)
- Android ExpandableListActivity实现可展开的activity
- Android_QQ好友列表实现---ExpandableListView可展开列表视图
- ExpandableListView实现的简单类似QQ好友界面的可展开下拉列表
- Android自定义View——从零开始实现可展开收起的水平菜单栏
- ExpandableListView(似listview中的item可展开)可展开的列表组件
- shell中单引号、双引号、反斜杠简说
- struts2核心过滤器
- 蟒蛇绘制程序
- 室外低功耗GPS定位漂移的解决方法
- kali 首次启动metasploit
- Android RecyclerView(超简单)实现可展开列表——单项展开
- SetWindowsHookExW与SetWinEventHook
- iOS 等待异步线程结束再执行后续代码
- 使用VisualVM分析性能
- 如何把list变成一个字符串
- JQuery DOM
- python Requests详解
- Value '0000-00-00' can not be represented as java.sql.Date
- spring的核心监听器