懒加载的Scrollview
来源:互联网 发布:电子人单片机开发板 编辑:程序博客网 时间:2024/05/21 08:02
要实现一个功能:当Scrollview滑动到最底端的时候需要触发事件加载其他数据。很多人都以为ScrollView可以像ListViev那样setOnScrollListener,其实沒那么简单,因为ScrollView压根就没有该接口,在baidu上兜了一圈没有找到合适的答案,没办法只能google去了,居然一下子解决了这个问题,还是老外比较牛,呵呵,这是我访问的网址:
http://stackoverflow.com/questions/2864563/how-do-i-know-that-the-scrollview-is-already-scrolled-to-the-bottom
注意,如果数据不满一页的话,会执行onBottom方法!通常要使用懒加载的话数据都会超过一页,所以我沒仔细考虑这个问题!
我把ScrollView封装成类了,源码如下:
用的时候也很简单,通常这样使用:
感激我吧,我呕心沥血才出来了这么个类。呵呵。
重写onScrollChanged()的模式
顺便记一下老外使用fullScroll的做法。当然也可以直接fullScroll而不需要放入post()。
只要把fullScroll改成scrollTo就可以做一个书签效果了:
http://yangsongjing.iteye.com/blog/1855063
Android-ObservableScrollView
https://github.com/ksoichiro/Android-ObservableScrollView
在HorizontalScrollView中使用ScrollView相互影响问题的解决办法:
On my ScrollView, I needed to override the onInterceptTouchEvent method to only intercept the touch event if the Y motion is > the X motion. It seems like the default behavior of a ScrollView is to intercept the touch event whenever there is ANY Y motion. So with the fix, the ScrollView will only intercept the event if the user is deliberately scrolling in the Y direction and in that case pass off the ACTION_CANCEL to the children.
Here is the code for my Scroll View class that contains the HorizontalScrollView:
android监听ScrollView滑动停止
在ScrollView中嵌入GridView
http://fariytale.iteye.com/blog/1420254
做android程序开发的都知道,不能在一个拥有Scrollbar的组件中嵌入另一个拥有Scrollbar的组件,因为这不科学,会混淆滑动事件,导致只显示一到两行数据。那么就换一种思路,首先让子控件的内容全部显示出来,禁用了它的滚动。如果超过了父控件的范围则显示父控件的scrollbar滚动显示内容,思路是这样,一下是代码。
具体的方法是自定义GridView组件,继承自GridView。重载onMeasure方法:
其中onMeasure函数决定了组件显示的高度与宽度;
makeMeasureSpec函数中第一个函数决定布局空间的大小,第二个参数是布局模式
MeasureSpec.AT_MOST的意思就是子控件需要多大的控件就扩展到多大的空间
之后在ScrollView中添加这个组件就OK了,同样的道理,ListView也适用。
滚动监听的ScrollView
ScrollView也可以实现OnTouchListener来监听是否滑动到最底部
在滚动的视图观测滚动事件的Android库:Android-ObservableScrollView
http://www.open-open.com/lib/view/open1415854429070.html
网上说的方法乱七八糟,能用的就是自己算高度,其实sdk-9中,ScrollView已经加入了一个方法,能监听到是否已经不能滚动,稍加处理,就可以监听是否滑到底部了。
先上自定义的ScrollView方法:
调用方法:
http://stackoverflow.com/questions/2864563/how-do-i-know-that-the-scrollview-is-already-scrolled-to-the-bottom
注意,如果数据不满一页的话,会执行onBottom方法!通常要使用懒加载的话数据都会超过一页,所以我沒仔细考虑这个问题!
我把ScrollView封装成类了,源码如下:
package com.ql.view;import android.content.Context;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.ScrollView; public class LazyScrollView extends ScrollView{private static final String tag="LazyScrollView";private Handler handler;private View view;public LazyScrollView(Context context) {super(context);// TODO Auto-generated constructor stub}public LazyScrollView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public LazyScrollView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stub}//这个获得总的高度public int computeVerticalScrollRange(){return super.computeHorizontalScrollRange();}public int computeVerticalScrollOffset(){return super.computeVerticalScrollOffset();}private void init(){this.setOnTouchListener(onTouchListener);handler=new Handler(){ @Overridepublic void handleMessage(Message msg) {// process incoming messages heresuper.handleMessage(msg);switch(msg.what){case 1:if(view.getMeasuredHeight() <= getScrollY() + getHeight()) {if(onScrollListener!=null){onScrollListener.onBottom();}}else if(getScrollY()==0){if(onScrollListener!=null){onScrollListener.onTop();}}else{if(onScrollListener!=null){onScrollListener.onScroll();}}break;default:break;}} };} OnTouchListener onTouchListener=new OnTouchListener(){@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubswitch (event.getAction()) {case MotionEvent.ACTION_DOWN:break;case MotionEvent.ACTION_UP:if(view!=null&&onScrollListener!=null){handler.sendMessageDelayed(handler.obtainMessage(1), 200);}break;default:break;}return false;} }; /** * 获得参考的View,主要是为了获得它的MeasuredHeight,然后和滚动条的ScrollY+getHeight作比较。 */ public void getView(){ this.view=getChildAt(0); if(view!=null){ init(); } } /** * 定义接口 * @author admin * */ public interface OnScrollListener{ void onBottom(); void onTop(); void onScroll(); } private OnScrollListener onScrollListener; public void setOnScrollListener(OnScrollListener onScrollListener){ this.onScrollListener=onScrollListener; }}
用的时候也很简单,通常这样使用:
scrollView=(LazyScrollView)findViewById(R.id.scrollView); scrollView.getView(); scrollView.setOnScrollListener(new OnScrollListener() {@Overridepublic void onTop() {// TODO Auto-generated method stubLog.d(tag,"------滚动到最上方------");}@Overridepublic void onScroll() {// TODO Auto-generated method stubLog.d(tag,"没有到最下方,也不是最上方");}@Overridepublic void onBottom() {// TODO Auto-generated method stubLog.d(tag,"------滚动到最下方------");}});
感激我吧,我呕心沥血才出来了这么个类。呵呵。
重写onScrollChanged()的模式
import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.widget.ScrollView;/** * BorderScrollView * <ul> * <li>onTop and onBottom response ScrollView</li> * <li>you can {@link #setOnBorderListener(OnBorderListener)} to set your top and bottom response</li> * </ul> * * @author trinea@trinea.cn 2013-5-21 */public class BorderScrollView extends ScrollView { private OnBorderListener onBorderListener; private View contentView; public BorderScrollView(Context context) { super(context); } public BorderScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public BorderScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); doOnBorderListener(); } public void setOnBorderListener(final OnBorderListener onBorderListener) { this.onBorderListener = onBorderListener; if (onBorderListener == null) { return; } if (contentView == null) { contentView = getChildAt(0); } } /** * OnBorderListener, Called when scroll to top or bottom * * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-22 */ public static interface OnBorderListener { /** * Called when scroll to bottom */ public void onBottom(); /** * Called when scroll to top */ public void onTop(); } private void doOnBorderListener() { if (contentView != null && contentView.getMeasuredHeight() <= getScrollY() + getHeight()) { if (onBorderListener != null) { onBorderListener.onBottom(); } } else if (getScrollY() == 0) { if (onBorderListener != null) { onBorderListener.onTop(); } } }}
顺便记一下老外使用fullScroll的做法。当然也可以直接fullScroll而不需要放入post()。
scrollView.post(new Runnable() { @Override public void run() { scrollView.fullScroll(View.FOCUS_DOWN); } });
只要把fullScroll改成scrollTo就可以做一个书签效果了:
http://yangsongjing.iteye.com/blog/1855063
Android-ObservableScrollView
https://github.com/ksoichiro/Android-ObservableScrollView
在HorizontalScrollView中使用ScrollView相互影响问题的解决办法:
On my ScrollView, I needed to override the onInterceptTouchEvent method to only intercept the touch event if the Y motion is > the X motion. It seems like the default behavior of a ScrollView is to intercept the touch event whenever there is ANY Y motion. So with the fix, the ScrollView will only intercept the event if the user is deliberately scrolling in the Y direction and in that case pass off the ACTION_CANCEL to the children.
Here is the code for my Scroll View class that contains the HorizontalScrollView:
public class CustomScrollView extends ScrollView { private GestureDetector mGestureDetector; View.OnTouchListener mGestureListener; public CustomScrollView(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(new YScrollDetector()); setFadingEdgeLength(0); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev) && mGestureDetector.onTouchEvent(ev); } // Return false if we're scrolling in the x direction class YScrollDetector extends SimpleOnGestureListener { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if(Math.abs(distanceY) > Math.abs(distanceX)) { return true; } return false; } }}
android监听ScrollView滑动停止
在ScrollView中嵌入GridView
http://fariytale.iteye.com/blog/1420254
做android程序开发的都知道,不能在一个拥有Scrollbar的组件中嵌入另一个拥有Scrollbar的组件,因为这不科学,会混淆滑动事件,导致只显示一到两行数据。那么就换一种思路,首先让子控件的内容全部显示出来,禁用了它的滚动。如果超过了父控件的范围则显示父控件的scrollbar滚动显示内容,思路是这样,一下是代码。
具体的方法是自定义GridView组件,继承自GridView。重载onMeasure方法:
public class MyGridView extends GridView{public MyGridView(android.content.Context context,android.util.AttributeSet attrs){super(context, attrs);}/** * 设置不滚动 */public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}}
其中onMeasure函数决定了组件显示的高度与宽度;
makeMeasureSpec函数中第一个函数决定布局空间的大小,第二个参数是布局模式
MeasureSpec.AT_MOST的意思就是子控件需要多大的控件就扩展到多大的空间
之后在ScrollView中添加这个组件就OK了,同样的道理,ListView也适用。
滚动监听的ScrollView
import android.content.Context;import android.util.AttributeSet;import android.widget.ScrollView;public class NotifyingScrollView extends ScrollView { public interface OnScrollChangedListener { void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt); } private OnScrollChangedListener mOnScrollChangedListener; public NotifyingScrollView(Context context) { super(context); } public NotifyingScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public NotifyingScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (mOnScrollChangedListener != null) { mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt); } } public void setOnScrollChangedListener(OnScrollChangedListener listener) { mOnScrollChangedListener = listener; }}
ScrollView也可以实现OnTouchListener来监听是否滑动到最底部
import android.os.Bundle;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;import android.widget.ScrollView;import android.app.Activity;/** * Demo描述: * 监听ScrollView滑动到顶端和底部 * * 注意事项: * 1 mScrollView.getChildAt(0).getMeasuredHeight()表示: * ScrollView所占的高度.即ScrollView内容的高度.常常有一 * 部分内容要滑动后才可见,这部分的高度也包含在了 * mScrollView.getChildAt(0).getMeasuredHeight()中 * * 2 view.getScrollY表示: * ScrollView顶端已经滑出去的高度 * * 3 view.getHeight()表示: * ScrollView的可见高度 * */public class MainActivity extends Activity { private ScrollView mScrollView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } private void init(){ mScrollView=(ScrollView) findViewById(R.id.scrollView); mScrollView.setOnTouchListener(new TouchListenerImpl()); } private class TouchListenerImpl implements OnTouchListener{ @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: int scrollY=view.getScrollY(); int height=view.getHeight(); int scrollViewMeasuredHeight=mScrollView.getChildAt(0).getMeasuredHeight(); if(scrollY==0){ System.out.println("滑动到了顶端 view.getScrollY()="+scrollY); } if((scrollY+height)==scrollViewMeasuredHeight){ System.out.println("滑动到了底部 scrollY="+scrollY); System.out.println("滑动到了底部 height="+height); System.out.println("滑动到了底部 scrollViewMeasuredHeight="+scrollViewMeasuredHeight); } break; default: break; } return false; } };}
在滚动的视图观测滚动事件的Android库:Android-ObservableScrollView
http://www.open-open.com/lib/view/open1415854429070.html
import android.content.Context; import android.util.AttributeSet; import android.widget.ScrollView; public class ObservableScrollView extends ScrollView { private ScrollViewListener scrollViewListener = null; public ObservableScrollView(Context context) { super(context); } public ObservableScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ObservableScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public void setScrollViewListener(ScrollViewListener scrollViewListener) { this.scrollViewListener = scrollViewListener; } @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (scrollViewListener != null) { scrollViewListener.onScrollChanged(this, x, y, oldx, oldy); } } }
网上说的方法乱七八糟,能用的就是自己算高度,其实sdk-9中,ScrollView已经加入了一个方法,能监听到是否已经不能滚动,稍加处理,就可以监听是否滑到底部了。
先上自定义的ScrollView方法:
import android.content.Context; import android.util.AttributeSet; import android.widget.ScrollView; public class BottomScrollView extends ScrollView { private OnScrollToBottomListener onScrollToBottom; public BottomScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public BottomScrollView(Context context) { super(context); } @Override protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) { super.onOverScrolled(scrollX, scrollY, clampedX, clampedY); if(scrollY != 0 && null != onScrollToBottom){ onScrollToBottom.onScrollBottomListener(clampedY); } } public void setOnScrollToBottomLintener(OnScrollToBottomListener listener){ onScrollToBottom = listener; } public interface OnScrollToBottomListener{ public void onScrollBottomListener(boolean isBottom); } }
调用方法:
BottomScrollView scroll = (BottomScrollView)findViewById(R.id.id_scroll); scroll.setOnScrollToBottomLintener(new OnScrollToBottomListener() { @Override public void onScrollBottomListener(boolean isBottom) { // TODO Auto-generated method stub Log.e("SCROLLVIEW", isBottom + ""); } });
0 0
- 懒加载的Scrollview
- 懒加载的Scrollview
- 懒加载的Scrollview
- 懒加载的Scrollview
- 自定义ScrollView的刷新加载
- unity中对于scrollview下拉加载的方法
- 3.大神班 scrollView 与 动画 imageView的加载图片
- scrollview 与 webview的嵌套使用(加载h5页面)
- ScrollView的简单实用并实现下拉加载
- IOS(swift)-scrollView(tableView) ·图片加载逻辑的优化
- android基础知识----scrollview的上拉加载下拉刷新
- ScrollView中加载WebView造成ScrollView滑动
- ScrollView嵌套listview。listview里面的图片加载用glide,解决图片加载不全的问题
- Android ScrollView 自动加载更多
- ScrollView嵌套ListView分页加载
- ScrollView上拉加载实现
- 上拉刷新,下拉加载的靠谱的第三方。支持listview,scrollview,gridview等等
- 由于图片异步加载,造成的被scrollView包裹的listview显示不全
- 使用TableLayout应该注意的地方
- Gradle for Android 第三篇( 依赖管理 )
- File
- 让两个HorizontalScrollView联动
- ScrollView当显示超出当前页面时自动移动到最底端
- 懒加载的Scrollview
- 修改SeekBar样式
- Gradle for Android 第四篇( 构建变体 )
- ListView之setEmptyView的问题
- Gradle sync failed: Failed to update Android plugin to version '2.2.2'
- 使用ListView应该注意的地方
- 重设布局中控件或布局的宽高
- 采用ViewHolder模式提高AdapterView显示的效率
- Gallery默认第一项居左解决方案