自定义ScrollView实现在底部可滑动消失
效果:这篇博客只是了实现一个小功能,可以根据思路可进行扩展。实现底部弹出列表,然后向上向下滚动可以查看列表内容,当滑动到最上面时,向下滑动评论列表逐渐消失。
实现思路:主要是对ScrollView的滑动事件进行监听,先调用
@Override
protected void onScrollChanged(int scrollX, int scrollY, int oldScrollX, int oldScrollY)
{
super.onScrollChanged(scrollX, scrollY, oldScrollX, oldScrollY);
mScrollY = scrollY;
}
获取滑动时是否是滚动的顶部(mScrollY = 0),如果是则可以对ScrollView的滚动事件进行拦截,详细代码如下:
public class CustomGlideScrollView extends ScrollView
{
private int mScrollY; //滚动的距离,主要是用来判断是否滚动的顶部
private int mScrollViewHeight; //view的高度,主要用来判断松开后是恢复还是消失
private float mInScroolValue; //整体向下滑动的偏移值
private boolean mIsUpScroll = true; //是否view整体向下滑动,并用来帮助获取滑动的起始值
private float mInitScrollValue; //记录整体开始滑动时的初始值
public CustomGlideScrollView(Context context)
{
super(context);
init();
}
public CustomGlideScrollView(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
public CustomGlideScrollView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
init();
}
private void init()
{
// 获取view的高度
post(new Runnable()
{
@Override
public void run()
{
mScrollViewHeight = getHeight();
}
});
setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
return setScrollViewPadding(event);
}
});
}
@Override
protected void onScrollChanged(int scrollX, int scrollY, int oldScrollX, int oldScrollY)
{
super.onScrollChanged(scrollX, scrollY, oldScrollX, oldScrollY);
mScrollY = scrollY;
}
/**
* 处理触摸事件
*
* @param event
* @return
*/
private boolean setScrollViewPadding(MotionEvent event)
{
if(mScrollViewHeight <= 0)
{
return false;
}
// 整体向下偏移
if(mScrollY == 0 && event.getAction() == MotionEvent.ACTION_MOVE)
{
if(mIsUpScroll)
{
// 记录偏移的起始值,并且表示可向上滑动了
mIsUpScroll = false;
mInitScrollValue = event.getRawY();
}
// 计算偏移量
mInScroolValue = event.getRawY() - mInitScrollValue;
if(mInScroolValue <= 0)
{
// 表示只是内容在滑动,无需对view进行偏移
mInScroolValue = 0;
return false;
}
setPadding(0, (int)mInScroolValue, 0, 0);
return false;
}
// 整体向上偏移
if(mInScroolValue != 0 && event.getAction() == MotionEvent.ACTION_MOVE && !mIsUpScroll)
{
// 计算偏移量
mInScroolValue = event.getRawY() - mInitScrollValue;
if(mInitScrollValue < 0)
{
mInitScrollValue = 0;
}
setPadding(0, (int)mInScroolValue, 0, 0);
return true;
}
// 恢复或消失
if(event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL)
{
if(mInScroolValue <= mScrollViewHeight / 2)
{
// 恢复,重置初始值
mInScroolValue = 0;
mIsUpScroll = true;
setPadding(0, 0, 0, 0);
}
else
{
// 整体消失
setPadding(0, mScrollViewHeight, 0, 0);
}
}
return false;
}
}
扩展:对于拥有多个view其中需要使用RecyclerView获取更多加载评论的,比如知乎的点击追加评论,同样可以使用此思路进行实现,只需要判断滑动RecyclerView时判断第一个条目是否已经在最顶部,然后根据手势滑动进行相应的处理。
详细代码和效果可GitHub传送门。
网友评论