带浮动层的ExpandableListView

整理以前的代码,发现一个带浮动层ExpandableListView,(这段代码好像是照着github上的一个开源组件写的,忘了地址了,如有冒犯,请联系本人删除)记录核心代码:

private int tempY = 0;
	
	/**记录listView滚动的距离*/
	private int lastTop = 0;

mListView.setOnScrollListener(new OnScrollListener() {
			
			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				// TODO Auto-generated method stub
				if(scrollState == OnScrollListener.SCROLL_STATE_IDLE){
				    if (mListView.getChildAt(0) != null) {
				    	lastTop = -mListView.getChildAt(0).getTop() + mListView.getFirstVisiblePosition() * mListView.getChildAt(0).getHeight();
				    }
				}
			}
			
			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				// TODO Auto-generated method stub
			    if (mListView.getChildAt(0) != null) {
			    	int currentTop = -mListView.getChildAt(0).getTop() + mListView.getFirstVisiblePosition() * mListView.getChildAt(0).getHeight();
			    	/*以Item的高度为参考来判断当前移动的距离是否触发隐藏或显示底部栏操作*/
				    int offsetTop = currentTop - lastTop;
				    if(null != MainActivity.MainContext && MainActivity.MainContext.isBarShow() && offsetTop > mListView.getChildAt(0).getHeight()){
				    	/*隐藏*/
				    	if(null != MainActivity.lastFragment && MainActivity.lastFragment.equals(CoursesFragment.this)){
				    		MainActivity.MainContext.hideBar();
				    	}
				    }else if(null != MainActivity.MainContext && !MainActivity.MainContext.isBarShow() && offsetTop < -mListView.getChildAt(0).getHeight()){
				    	/*显示*/
				    	MainActivity.MainContext.showBar();
				    }
			    }
				
				if(!mPullToRefreshView.isAnimFinished()){
					return;
				}
				
				/*在下拉状态释放后,对headerView进行最后的隐藏*/
				if(mPullToRefreshView.isReadyForPullDown()){
					headerView.setVisibility(View.GONE);
					return;
				}
				
				/*当前处于上拉或下拉状态,则直接返回*/
				if(mPullToRefreshView.isBeingDragged()){
					return;
				}
				
				int firstPos = view.pointToPosition(0, 0);// 其实就是firstVisibleItem
				if (firstPos == AdapterView.INVALID_POSITION)// 如果第一个位置值无效
					return;

				long firstPackedPos = mListView.getExpandableListPosition(firstPos);
				int firstChildPos = ExpandableListView.getPackedPositionChild(firstPackedPos);// 获取第一行child的id
				int firstGroupPos = ExpandableListView.getPackedPositionGroup(firstPackedPos);// 获取第一行group的id
				if((firstGroupPos == AdapterView.INVALID_POSITION 
						|| !mListView.isGroupExpanded(firstGroupPos))
						&& firstChildPos == AdapterView.INVALID_POSITION){
					/*显示出来的第一个item既不是group也不是child,这时应该是header,隐藏indicatorGroup*/
					headerView.setVisibility(View.GONE);
					return;
				}else if(firstChildPos == AdapterView.INVALID_POSITION){
					/*显示出来的第一个item是group, 取其高度,用来初始化indicatorGroupHeight*/
					headerViewHeight = mListView.getChildAt(0).getHeight();
					headerView.setVisibility(View.VISIBLE);
				}else{
					headerView.setVisibility(View.VISIBLE);
				}
				
				if (headerViewHeight == 0) {
					return;
				}
				
				if(firstGroupPos != AdapterView.INVALID_POSITION){
					if (firstGroupPos != headerViewPos) {// 如果指示器显示的不是当前group
						refreshHeaderViewData(firstGroupPos);
						headerViewPos = firstGroupPos;
					}
				}
				
				/**
				 * calculate point (0,indicatorGroupHeight) 下面是形成往上推出的效果
				 */
				int topOffset = headerViewHeight;
				int secondPos = mListView.pointToPosition(0, headerViewHeight + mListView.getDividerHeight());// 第二个item的位置
				if (secondPos == AdapterView.INVALID_POSITION)//如果无效直接返回
					return;
				long secondPackedPos = mListView.getExpandableListPosition(secondPos);
				int secondGroupPos = ExpandableListView.getPackedPositionGroup(secondPackedPos);//获取第二个group的id
				if (secondGroupPos != AdapterView.INVALID_POSITION && secondGroupPos != headerViewPos) {//如果不等于指示器当前的group
					topOffset = mListView.getChildAt(secondPos - mListView.getFirstVisiblePosition()).getTop();
				}
				tempY = (headerViewHeight - topOffset) + mPullToRefreshView.getScrollY();
				if(tempY < 0){
					tempY = 0;
				}
//				headerView.scrollTo(0, tempY);
				MarginLayoutParams layoutParams = (MarginLayoutParams) headerView
						.getLayoutParams();
				layoutParams.topMargin = -(tempY + mPullToRefreshView.getScrollY());
				headerView.setLayoutParams(layoutParams);
			}
		});
	}

至于布局文件就不贴了,简单说明:浮动层和ExpandableListView同在一个RelativeLayout中,并且浮动层浮在ExpandableListView的上面,(浮动层的顶部和ExpandableListView的顶部在同一位置,且浮动层的布局和ExpandableListView的布局相同);


注:这种实现方式比较简单,但是效率低,滑动流畅度不太好;看到有人是使用Google联系人中的组件实现这种效果,效果要好很多,有兴趣的同学可以找一下看看!

Gradle引用方式:

compile 'com.itz:FloatExpandableListView:1.0.0'

DEMO下载


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值