Android webview-Android listView反弹效果实现,遇到params.bottomMargin遮盖了listview内容的问题

发布于 2017-01-18 11:00:00 字数 7773 浏览 1456 评论 1

当我下拉的时候,改变params.topMargin的值来进行滚动没有问题。 但是在滑到最下面,然后上啦的时候, 通过params.bottomMargin来改变,发生了listview 被遮盖的问题。 想要的结果是 listview 整体向上移动。
上图:

请输入图片描述

请输入图片描述

代码如下:

package com.scroll;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.Scroller;

public class ScrollLinearLayout extends LinearLayout
{

public static final int DETEN = 200;

private float preY;
private float delayY;
private Scroller mScroller;
private AdapterView<?> childView;
private LayoutParams params;

private int childTopMargin;
private int childBottomMargin;
private int childTop;
private int childBottom;
private int childPaddingTop;
private int childHeight;

private int parentTop;
private int parentButtom;
private int parentHeight;

private View lastView;
private int lastViewBottom;
private int lastVisiblePosition;

private int offsetTop;
private int offsetBottom;

private View firstView;
private int firstViewTop;

public ScrollLinearLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
mScroller = new Scroller(getContext());
}

@Override
protected void onFinishInflate()
{
super.onFinishInflate();
childView = (AdapterView<?>) getChildAt(0);
params = (LayoutParams) childView.getLayoutParams();
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event)
{
int action = event.getAction();
float x = event.getX();
float y = event.getY();

updateParameter();

switch (action)
{
case MotionEvent.ACTION_DOWN:
preY = y;
break;
case MotionEvent.ACTION_MOVE:
delayY = y - preY;
preY = y;
if (isUpPrepareState())
{
return true;
}
if (isUpState())
{
return true;
}
if (isDownPrepareState())
{
return true;
}
if (isDownState())
{
return true;
}

case MotionEvent.ACTION_UP:
break;
}
return false;
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
float x = event.getX();
float y = event.getY();

updateParameter();

switch (action)
{
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
if (!mScroller.isFinished())
{
mScroller.abortAnimation();
return true;
}
delayY = y - preY;
preY = y;
if (isUpPrepareState())
{
updateTopMargin(delayY);
}
if (isUpState())
{
updateTopMargin(delayY);
}
if (isDownPrepareState())
{
updateBottomMargin(-delayY);
}
if (isDownState())
{
updateBottomMargin(-delayY);
}
childView.setLayoutParams(params);
postInvalidate();
break;
case MotionEvent.ACTION_UP:

if (isUpState())
{
mScroller.startScroll(0, (int) y, 0, -(int) (offsetTop),
DETEN);
postInvalidate();
}
if (isDownState())
{
mScroller.startScroll(0, (int) y, 0, -(int) (offsetBottom),
DETEN);
postInvalidate();
}
break;
}

return super.onTouchEvent(event);
}

public void computeScroll()
{

updateParameter();

super.computeScroll();
if (mScroller.computeScrollOffset())
{
float x = mScroller.getCurrX();
float y = mScroller.getCurrY();
delayY = y - preY;
preY = y;
if (isUpState())
{
updateTopMargin(delayY);

}
if (isDownState())
{
updateBottomMargin(-delayY);
}
childView.setLayoutParams(params);
postInvalidate();
}
}

private void updateParameter()
{
childTopMargin = params.topMargin;
childBottomMargin = params.bottomMargin;

childTop = childView.getTop();
childBottom = childView.getBottom();
childPaddingTop = childView.getPaddingTop();
childHeight = childView.getHeight();

parentTop = this.getTop();
parentButtom = this.getBottom();
parentHeight = this.getHeight();

lastView = childView.getChildAt(childView.getChildCount() - 1);
lastViewBottom = lastView.getBottom();
lastVisiblePosition = childView.getLastVisiblePosition();
firstView = childView.getChildAt(0);
firstViewTop = firstView.getTop();

offsetTop = childTop - parentTop;
offsetBottom = childBottom - parentButtom;
}

private int getMaxChildIndex()
{
return childView.getCount() - 1;
}

private boolean isUpPrepareState()
{
return childView.getFirstVisiblePosition() == 0 && childTopMargin == 0
&& delayY > 0;
}

private boolean isUpState()
{
return childView.getFirstVisiblePosition() == 0 && childTopMargin > 0;
}

private boolean isDownPrepareState()
{
return lastViewBottom == parentHeight
&& lastVisiblePosition == getMaxChildIndex() && delayY < 0;
}

private boolean isDownState()
{
return childBottomMargin > 0;
}

private void updateTopMargin(float value)
{
params.topMargin += value;
params.bottomMargin += -value;
if (params.topMargin < 0)
{
params.topMargin = 0;
}
}

private void updateBottomMargin(float value)
{
params.bottomMargin += value;
params.topMargin += -value;
if (params.bottomMargin < 0)
{
params.bottomMargin = 0;
}
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

偏爱自由 2017-05-20 09:45:46

params.topMargin也需要修改,params.topMargin的变化,ListView的高度也跟着改变;
你这个功能,我觉得你可以参考下下拉刷新ListView的实现。百度下很多。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文