webentwicklung-frage-antwort-db.com.de

SwipeRefreshLayout + WebView, wenn sich die Bildlaufposition oben befindet

Ich versuche, SwipeRefreshLayout mit WebView zu verwenden.

Ich bin mit dem Problem konfrontiert, dass in der Mitte der Seite, wenn der Benutzer nach unten blättert, unerwünschte Aktualisierungen auftreten.

Wie kann ich das Aktualisierungsereignis nur ausführen, wenn sich die Bildlaufposition von webview oben befindet. (dh er schaut sich den oberen Teil der Seite an)?

24
eugene

Ich habe es geschafft, es zu lösen, ohne etwas erweitern zu müssen. Schauen Sie sich diesen Ausschnitt an (fragmentspezifisch):

private ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener;

@Override
public void onStart() {
    super.onStart();

    swipeLayout.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener =
            new ViewTreeObserver.OnScrollChangedListener() {
                @Override
                public void onScrollChanged() {
                    if (mWebView.getScrollY() == 0)
                        swipeLayout.setEnabled(true);
                    else
                        swipeLayout.setEnabled(false);

                }
            });
}

@Override
public void onStop() {
    swipeLayout.getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener);
    super.onStop();
}

Für einen umfassenderen Kontext sehen Sie sich meine Antwort auf Android - SwipeRefreshLayout mit leerer Textansicht an.

22
vizZ

Ich denke, der empfohlene Weg, dies zu tun, ist die Erweiterung der SwipeRefreshLayout und die Überschreibung von canChildScrollUp() - https://developer.Android.com/reference/Android/support/v4/widget/SwipeRefreshLayout.html#canChildScrollUp ()

So wird es in der Google IO 2014 Schedule App gemacht - https://github.com/google/iosched/blob/master/Android/src/main/Java/com/google/samples/apps /iosched/ui/widget/MultiSwipeRefreshLayout.Java#L76

Die CustomSwipeRefreshLayout wird wahrscheinlich so aussehen:

public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {

    private CanChildScrollUpCallback mCanChildScrollUpCallback;

    public interface CanChildScrollUpCallback {
        boolean canSwipeRefreshChildScrollUp();
    }

    public void setCanChildScrollUpCallback(CanChildScrollUpCallback canChildScrollUpCallback) {
        mCanChildScrollUpCallback = canChildScrollUpCallback;
    }

    @Override
    public boolean canChildScrollUp() {
        if (mCanChildScrollUpCallback != null) {
            return mCanChildScrollUpCallback.canSwipeRefreshChildScrollUp();
        }
        return super.canChildScrollUp();
    }
}

Und in Ihrer Activity, die die WebView hat,

public class FooActivity
        implements CustomSwipeRefreshLayout.CanChildScrollUpCallback {

    private CustomSwipeRefreshLayout mRefreshLayout;
    private WebView mWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // after initialization
        mRefreshLayout.setCanChildScrollUpCallback(this);
    }

    @Override
    public boolean canSwipeRefreshChildScrollUp() {
        return mWebview.getScrollY() > 0;
    }
}
19
hiBrianLee

Implementieren Sie einfach Ihre Fragment oder Activity mit ViewTreeObserver.OnScrollChangedListener und setzen Sie den Listener wie webview.getViewTreeObserver().addOnScrollChangedListener(this);.

In onScrollChanged() Methode mache das so

    @Override
    public void onScrollChanged() {
        if (webview.getScrollY() == 0) {
            swipeLayout.setEnabled(true);
        } else {
            swipeLayout.setEnabled(false);
        }
    }
7
Pranav

Sie können dieses Problem lösen, indem Sie SwipeRefreshLayout um ein benutzerdefiniertes SwipeRefreshLayout erweitern, das das WebView verwendet und das WebView zum Überprüfen der ScrollY-Position verwendet.

Hinweis: .__ Dies funktioniert für das Scrollen der gesamten Seite, es kann jedoch nicht mit verschachtelten Scrolls funktionieren. Wenn Sie über einen horizontalen Scroll verfügen, möchten Sie möglicherweise auch die in dieser Antwort enthaltene Logik hinzufügen: https: //stackoverflow.com/a/24453194

public class CustomSwipeToRefresh extends SwipeRefreshLayout {

    private final int yScrollBuffer = 5;
    private WebView mWebView;

    public CustomSwipeToRefresh(Context context, WebView webView) {
        super(context);

        mWebView = webView;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (mWebView.getScrollY() > yScrollBuffer)
            return false;

        return super.onInterceptTouchEvent(event);
    }
}
2
Isaac

Ich war mit einem ähnlichen Problem konfrontiert, aber keine der hier gegebenen Antworten funktioniert für mich. Also bekam ich eine Lösung von this answer.

Schritt 1: Klasse erstellen CustomWebView 

public class CustomWebView extends WebView{

private OnScrollChangedCallback mOnScrollChangedCallback;

public CustomWebView(final Context context)
{
    super(context);
}

public CustomWebView(final Context context, final AttributeSet attrs)
{
    super(context, attrs);
}

public CustomWebView(final Context context, final AttributeSet attrs, final int defStyle)
{
    super(context, attrs, defStyle);
}

@Override
protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt)
{
    super.onScrollChanged(l, t, oldl, oldt);
    if(mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t);
}

public OnScrollChangedCallback getOnScrollChangedCallback()
{
    return mOnScrollChangedCallback;
}

public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback)
{
    mOnScrollChangedCallback = onScrollChangedCallback;
}

/**
 * Impliment in the activity/fragment/view that you want to listen to the webview
 */
public static interface OnScrollChangedCallback
{
    public void onScroll(int horizontal, int vertical);
}}

Schritt 2: In xml -Datei verwenden Sie webview wie folgt:

 <com.yourpackagename.CustomWebView
        Android:id="@+id/webview"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>

Schritt 3: In Ihrer MainActivity verwenden Sie setOnScrollChangedCallback -

  mWebView.setOnScrollChangedCallback(new CustomWebView.OnScrollChangedCallback(){
        public void onScroll(int horizontal, int vertical){
            System.out.println("=="+horizontal+"---"+vertical);
   //this is to check webview scroll behaviour
            if (vertical<50){
                swipeRefreshLayout.setEnabled(true);
            }else{
                swipeRefreshLayout.setEnabled(false);
            }
        }
    });
}

Die Antwort von hiBrianLee fast hat für mich funktioniert, aber wie John Shelley schrieb, gab getScrollY in meinem Fall immer 0 zurück (ich habe eine ListView als verschachteltes scrollendes Kind verwendet). Was jedoch sofort funktionierte, war die Verwendung von canScrollVertically (eine View-Methode, die sowohl für ListViews und WebViews als auch für jede andere Art von scrollendem Kind verfügbar ist). 

Meine Layoutklasse sieht wie folgt aus:

public class NestedScrollSwipeLayout extends SwipeRefreshLayout {

    private ListView scrollChild;

    public NestedScrollSwipeLayout(Context context) {
        super(context);
    }

    public NestedScrollSwipeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setScrollChild(ListView child) {
        this.scrollChild = child;
    }

    @Override
    public boolean canChildScrollUp() {
        return (scrollChild != null && scrollChild.canScrollVertically(-1)) ||
            super.canChildScrollUp();
    }
}

(Wie bereits erwähnt, ist canScrollVertically eine View-Methode, daher kann die ListView sicher durch eine allgemeine View oder eine andere spezialisierte Ansichtsklasse ersetzt werden.)

0
doertsch

Ich beantworte dieselbe Frage, benutze aber Kotlin. Durch Aktivieren von swipeRefreshLayout, wenn das scrollY von webView0 erhält:

Machen Sie diese Variable in Ihrem Fragment oder Ihrer Aktivität:

private val onScrollChangedListener = ViewTreeObserver.OnScrollChangedListener{ swipeRefreshLayout.isEnabled = webView.scrollY == 0 }

Dann onViewCreated:

swipeRefreshLayout.viewTreeObserver.addOnScrollChangedListener(onScrollChangedListener)

Dann onStop:

swipeRefreshLayout.viewTreeObserver.removeOnScrollChangedListener(onScrollChangedListener)

Von hier aus wird alles gut funktionieren. Wenn die von Ihnen verwendete Webseite jedoch einen festen Header hat, der nicht scrollt, ist scrollY immer gleich 0. Diese Lösung zusammen mit anderen Lösungen auf dieser Seite funktioniert möglicherweise nicht.

0
Xenolion

Die neuesten Versionen der Unterstützungsbibliothek haben die SwipeRefreshLayout#setOnChildScrollUpCallback-Methode, mit der Sie die Unterklasse SwipeRefreshLayout vermeiden können.

mBinding.swipeRefreshLayout.setOnChildScrollUpCallback((parent, child) -> 
            mBinding.webView.getScrollY() > 10);
0
Alexey