Android webview-Android listView反弹效果实现,遇到params.bottomMargin遮盖了listview内容的问题
当我下拉的时候,改变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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
params.topMargin也需要修改,params.topMargin的变化,ListView的高度也跟着改变;
你这个功能,我觉得你可以参考下下拉刷新ListView的实现。百度下很多。