嵌套ListView的ScrollView实现上拉和下拉

文章开头先说一下listView和ScrollView相互嵌套的问题,由于需求和UI布局上的要求多样化,自然而然的衍生了ScrollView嵌套listView等的需求,虽然谷歌官方是不建议这样,关于listView嵌套后的滑动冲突,网上有很多方法,在此只说一下自己的方法:

  1. @Override    
  2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    
  3.     // TODO 自动生成的方法存根    
  4.         int expandSpec = MeasureSpec.makeMeasureSpec(     
  5.                 Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);     
  6.         super.onMeasure(widthMeasureSpec, expandSpec);     
  7. }    

这个代码原理是禁用了ListView本身的滑动功能,强制它们的item全部显示,简而言之就是取消listView子控件的滑动,并且强制定义高度,接下来就是我们重点要说明的问题,既然我们为了嵌套取消了listView的滑动,自然也不存在上拉刷新下拉加载的监听,所以为了方便就自定义了ScrollViewBottom。

第一:ScrollViewBottom继承ScrollView

定义了ScrollViewBottom类之后,直接继承ScrollView就好。需要注意的是定义View时必须派生实现基类View的三个构造函数 ,否则当程序运行时会出现布局文件报错异常,例如:

android.view.InflateException: Binary XML file line #22: Binary XML file line #22:

出现此类问题常见的原因和解决方法:

1.自定义View必须使用完整路径名。
2.定义View,必须派生实现基类View的三个构造函数 。  
 View(Context context) //Simple constructor to use when creating a view from code 
 View(Context context, AttributeSet attrs) //Constructor that is called when inflating a view from XML 
 View(Context context, AttributeSet attrs, int defStyle) //Perform inflation from XML and apply a class-specific base style 
3.Rebuild project

4.资源文件引用错误(例如drawable引用为color之类)。

第二定义监听:

/**
 * 描述:定义到达顶部和底部响应事件接口OnBorderListener
 */
public interface OnBorderListener {
    /**
     * Called when scroll to bottom
     */
    public void onBottom();


    /**
     * Called when scroll to top
     */
    public void onTop();
}

第三实现自定义ScrollViewBottom:

  private OnBorderListener onBorderTouchListener;
    /**
     * 初始化滑动监听方法
     */
    private void initListener() {
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_UP:
                        doOnBorderListener(view);
                        break;
                }
                return false;
            }
        });
    }
    private void doOnBorderListener(View contentView) {
        int scrollY = contentView.getScrollY();
        int height = contentView.getHeight();
        int scrollViewMeasuredHeight = getChildAt(0).getMeasuredHeight();
        if (contentView != null && (scrollY + height) == scrollViewMeasuredHeight) {
            // 到达底部,刷新数据
            if (onBorderTouchListener != null) {
                onBorderTouchListener.onBottom();
            }
        } else if (scrollY == 0) {
            if (onBorderTouchListener != null) {
                onBorderTouchListener.onTop();
            }
        }
    }
    public void setOnScrollToBottomLintener(OnBorderListener listener) {
        onBorderTouchListener = listener;

    }

在布局中引用自定义的ScrollViewBottom后,直接在界面中声明

 ScrollViewBottom.setOnScrollToBottomLintener(new OnBorderListener() {
            @Override
            public void onBottom() {
                // 到达底部,加载数据
              
            }
            @Override
            public void onTop() {
                  // 到达顶部,刷新数据

            }

        });

滚动到顶部判断:getScrollY() == 0
滚动到底部判断:
View contentView = getChildAt(0);
contentView.getMeasuredHeight() <= getScrollY() + getHeight();
View contentView = getChildAt(0);
contentView.getMeasuredHeight() <= getScrollY() + getHeight();

其中getChildAt表示得到ScrollView的child View,因为ScrollView只允许一个child view,所以contentView.getMeasuredHeight()表示得到子View的高度, getScrollY()表示得到y轴的滚动距离,getHeight()为scrollView的高度。当getScrollY()达到最大时加上scrollView的高度就的就等于它内容的高度

附上相关类下载:https://download.csdn.net/download/wangyetongsss/10478435

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值