美文网首页
2019-01-05

2019-01-05

作者: 遥望星空forward | 来源:发表于2019-01-05 19:24 被阅读0次

自定义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传送门

相关文章

网友评论

      本文标题:2019-01-05

      本文链接:https://www.haomeiwen.com/subject/jjsdrqtx.html