ScrollView嵌套ListView遇到的问题备忘

最近公司项目要求主页为上方多布局 下方list的形式 当list第一条滚动到顶部时 开始显示title 反之则隐藏title

第一感觉是用ScrollView嵌套ListView 然后判断ScrollView的滚动距离 控制title的显示与隐藏

结果发现ScrollView嵌套ListView之后 ListView只能显示一行数据 需要自定义ListView 重写ListView的onMeasure()方法

@Override
	/**
	 * 重写该方法,达到使ListView适应ScrollView的效果
	 */
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
				MeasureSpec.AT_MOST);
		super.onMeasure(widthMeasureSpec, expandSpec);
	}
使用后发现ListView确实可以正常显示了 但是下拉刷新和上拉加载都没了  而且也失去了ListView的高性能

于是决定使用ScrollView的上拉加载来加载ListView的数据

并且ScrollView好像无法实时获取当前的滚动距离

 百度了一下说需要自定义ScrollView 重写ScrollView的OnScrollChanged()方法结果就成了这样

<pre name="code" class="java">@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		View view = (View) getChildAt(getChildCount() - 1);
		int d = view.getBottom();
		d -= (getHeight() + getScrollY());
		//滚动到底部时
		if (d == 0) {
			// you are at the end of the list in scrollview
			// do what you wanna do here
			scrollChangedListener.onScrollToBottom(l, t, oldl, oldt);
		}
		super.onScrollChanged(l, t, oldl, oldt);
		scrollChangedListener.onScrollChanged(l, t, oldl, oldt);
	}

	public void setOnScrollChangedListener(
			OnScrollChangedListener scrollChangedListener) {
		this.scrollChangedListener = scrollChangedListener;
	}

	public interface OnScrollChangedListener {
		/**
		 * 开始滚动时
		 * 
		 * @param curx
		 * @param cury
		 * @param oldx
		 * @param oldy
		 */
		void onScrollChanged(int curx, int cury, int oldx, int oldy);
		/**
		 * ScrollView滚动到底部
		 * 
		 * @param curx
		 * @param cury
		 * @param oldx
		 * @param oldy
		 */
		void onScrollToBottom(int curx, int cury, int oldx, int oldy);
	}


也就是增加了一个接口, 在onScrollChanged()方法里  调用了接口里的方法传递参数,再到需要调用的类里设置相应的监听即可获取滚动高度

而上面的 t 就是指当前滚动的高度 

然后在MainActivity里调用了上方布局的getHeight()方法获取了上方布局的高度

判断 t 是否大于 上方布局高度 大于则显示title 小于则隐藏

同时上啦加载也实现了

但是又发现一个问题 :listView在上拉加载数据时界面会卡在那里 加载完成后才能恢复 

调试发现问题在于加载数据时listView调用了n次onMeasure()方法来测量子控件高度 

这就尴尬了。。。

不重写onMeasure()方法 ListView只能显示一条

而重写了 上拉加载又卡在那里 

百度了好多地方都没找到解决方法 

又因为催的紧 又解决不了

无奈只能找别的方法,于是又找到一种方法:

将上方的布局与listView分开单独写成一个headerView

通过ListView.addHeaderView(headerView)方法添加到listView的头部

再设置headerView相应的点击事件

这样整个界面就是一个ListView了 高性能又回来了 下拉刷新上拉加载也回来了

不过发现一个问题:ListView好像也没有获取当前滚动距离的方法

无奈继续百度,结果还是要重写ListView里面的onScroll方法

而且又是一大堆算法,本人比较懒 换了个简单的。。。

</pre><pre name="code" class="java"><pre name="code" class="java">@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		this.visibleItemCount = visibleItemCount;
		visibleLastIndex = firstVisibleItem + visibleItemCount - 1;
		// 当前列表中最后一个可见的Item的Position 大于等于页面可显示的Item个数
		if (getLastVisiblePosition() >= visibleItemCount) {
			if (showTitleListener != null) {
				showTitleListener.onShowTitle();
			}
		} else {
			if (showTitleListener != null) {
				showTitleListener.onHideTitle();
			}
		}

	}
public void setOnShowTitleListener(OnShowTitleListener showTitleListener) {
		this.showTitleListener = showTitleListener;
	}
public interface OnShowTitleListener {
		public void onShowTitle();

		public void onHideTitle();
	}


逻辑都很简单就不废话了,测试下来基本能满足要求了,呼~~~终于可以下班了大笑

最近想了下 换了一个方向  问题基本解决了 代码如下:

@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		this.visibleItemCount = visibleItemCount;
		visibleLastIndex = firstVisibleItem + visibleItemCount - 1;
		// 当前列表中第一个可见的Item的Position
		if (firstVisibleItem > 0) {
			if (showTitleListener != null) {
				showTitleListener.onShowTitle();
			}
		} else {
			if (showTitleListener != null) {
				showTitleListener.onHideTitle();
			}
		}

	}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值