AgentWeb icon indicating copy to clipboard operation
AgentWeb copied to clipboard

配合SmartRefreshLayout使用会有回弹闪动现象

Open Jiang00 opened this issue 3 years ago • 2 comments

https://github.com/scwang90/SmartRefreshLayout

NestedScrollAgentWebView重新写了onTouchEvent方法解决了这个问题却又引发了另一个问题,webview还没滑到顶部就把SmartRefreshLayout的头给滑出来了

Jiang00 avatar Dec 14 '21 06:12 Jiang00

我的下拉刷新也遇到过类似的问题. 我是用了一个状态类去处理的

  • 状态管理类
private static final class RefreshEnableState extends MutableLiveData<RefreshEnableState> {

        private static final int FLAG_WEB_VIEW_SCROLL = 0x1; // WebView滑动锁
        private static final int FLAG_WEB_VIEW_TITLE = 0x2; // 特定标题锁
        private static final int FLAG_ACTION_BAR = 0x4; //ActionBar锁
        private int mLockFlag = 0;

        private void updateWebViewScrollState(boolean release) {
            updateValue(release, FLAG_WEB_VIEW_SCROLL);
        }

        private void updateWebViewTitleState(boolean release) {
            updateValue(release, FLAG_WEB_VIEW_TITLE);
        }

        private void updateActionBarState(boolean release) {
            updateValue(release, FLAG_ACTION_BAR);
        }

        private boolean isEnabled() {
            return mLockFlag == 0; //所有的锁都释放了才允许滑动
        }

        private void updateValue(boolean release, int flag) {
            final int before = mLockFlag;
            if (release) {
                mLockFlag &= ~flag;
            } else {
                mLockFlag |= flag;
            }
            if (mLockFlag != before) postValue(this); //更新锁状态
        }
    }
  • WebView滑动监听
NestedScrollAgentWebView webView = new NestedScrollAgentWebView(this) {
            @Override
            protected void onScrollChanged(int l, int t, int oldl, int oldt) {
                //判断WebView是否滑到顶
                mRefreshEnableState.updateWebViewScrollState(getScrollY() == 0);
                super.onScrollChanged(l, t, oldl, oldt);
            }
        };
  • 特定Title监听(WebChromeClient#onReceivedTitle 回调)
private void updateWebViewTitleState(String title) {
        mRefreshEnableState.updateWebViewTitleState(!(
                title.equalsIgnoreCase(WebConstants.NOT_SUPPORT_TITLE_ERROR)
                        || title.equalsIgnoreCase(WebConstants.DOWNLOADING_TITLE)
        ));
    }
  • ActionBar完全显示监听
((AppBarLayout) findViewById(R.id.appBarLayout))
                .addOnOffsetChangedListener((appBarLayout, verticalOffset) ->
                        mRefreshEnableState.updateActionBarState(verticalOffset == 0));
  • 注册LiveData监听
 mRefreshEnableState.observe(this, state -> refreshLayout.setEnabled(state.isEnabled()));

总之, 你想添加多少控制就在状态管理里面处理多少控制就行.

xiexindev avatar Dec 15 '21 01:12 xiexindev

@xiexindev 感谢,我用其他方法解决了,暂时没发现其他问题。

  • 修改了NestedScrollAgentWebView的onTouchEvent方法

    @Override public boolean onTouchEvent(MotionEvent event) {

      final MotionEvent trackEvent = MotionEvent.obtain(event);
      final int action = event.getActionMasked();
    
      if (action == MotionEvent.ACTION_DOWN) {
          mNestedOffsetY = 0;
      }
    
      final int eventY = (int) trackEvent.getY();
      trackEvent.offsetLocation(0, mNestedOffsetY);
    
      switch (action) {
          case MotionEvent.ACTION_MOVE:
              int deltaY = mLastY - eventY;
    
              if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
                  deltaY -= mScrollConsumed[1];
                  trackEvent.offsetLocation(0, -mScrollOffset[1]);
                  mNestedOffsetY += mScrollOffset[1];
              }
    
              mLastY = eventY - mScrollOffset[1];
    
              int oldY = getScrollY();
              int newScrollY = Math.max(0, oldY + deltaY);
              int dyConsumed = newScrollY - oldY;
              int dyUnconsumed = deltaY - dyConsumed;
    
    
              if (dispatchNestedScroll(0, mScrollOffset[1], 0, dyUnconsumed, mScrollOffset)) {
                  mLastY -= mScrollOffset[1];
                  trackEvent.offsetLocation(0, mScrollOffset[1]);
                  mNestedOffsetY += mScrollOffset[1];
              }
              break;
    
          case MotionEvent.ACTION_DOWN:
              mLastY = eventY;
              startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
              break;
          case MotionEvent.ACTION_POINTER_DOWN:
          case MotionEvent.ACTION_UP:
          case MotionEvent.ACTION_CANCEL:
              stopNestedScroll();
              break;
    
          default:
              // We don't care about other touch events
      }
    
      // Execute event handler from parent class in all cases
      boolean eventHandled = super.onTouchEvent(trackEvent);
    
      // Recycle previously obtained event
      trackEvent.recycle();
    
      return eventHandled;
    

    }

Jiang00 avatar Dec 16 '21 02:12 Jiang00