2012-06-08 1 views
5

Ich habe eine Webansicht, die eine HTML-Datei zeigt. Wenn der Benutzer in webview zum Ende dieser Datei scrollt, möchte ich eine Schaltfläche, die zuvor ausgeblendet wurde, die der Benutzer dann drücken kann, um etwas Aktivität zu tunAndroid: Machen Sie eine Schaltfläche sichtbar, sobald Webview Scrollen

Ich habe etwas ähnliches in iOS, wo ich gerade eingestellt Delegieren Sie den ViewController und setzen Sie den Button als sichtbar. Wie mache ich etwas Ähnliches auf Android? Mir ist aufgefallen, dass es keine Callback-Methode wie in iOS gibt.

Bearbeiten: Im Moment habe ich eine Aktivität mit 2 Objekten: ein Webview mit meinem Text und eine Schaltfläche, die derzeit unsichtbar ist. Ich möchte, dass meine Tätigkeit eine Nachricht, wenn die Webansicht Text scrollt nach unten bekommen, und machen Sie die Taste sichtbar

Antwort

0

try this:

@Override 
protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
     View view = (View) getChildAt(getChildCount()-1); 
     int diff = (view.getBottom()-(getHeight()+getScrollY()));// Calculate the scrolldiff 
     if(diff == 0){ // if diff is zero, then the bottom has been reached 
      Log.d(ScrollTest.LOG_TAG, "MyScrollView: Bottom has been reached"); 
      yourButton.setVisible(true); 
     } 
     super.onScrollChanged(l, t, oldl, oldt); 
} 

Um dies zu implementieren, erweitern Scrollview und dann überschreiben die onScrollChanged-Methode (geerbt von Ansicht).

+0

Die Webansicht hat jedoch keinen Verweis auf die Schaltfläche. – Daniel

2

Ich musste dies selbst tun, um eine "Ich stimme zu" -Schaltfläche anzuzeigen, sobald der Benutzer an den unteren Rand eines EULA gescrollt hat. Anwälte, nicht wahr?

In der Tat, wenn Sie die WebView (anstelle der ScrollView wie in der Antwort von @JackTurky) überschreiben, können Sie getContentHeight() aufrufen, um die Höhe des Inhalts zu erhalten, anstatt getBottom(), die den sichtbaren unteren und ist Nicht nützlich.

Dies ist meine umfassende Lösung. Soweit ich das sehen kann, ist dies alles API Level 1 Zeug, also sollte es überall funktionieren.

public class EulaWebView extends WebView { 
    public EulaWebView(Context context) 
    { 
     this(context, null); 
    } 

    public EulaWebView(Context context, AttributeSet attrs) 
    { 
     this(context, attrs, 0); 
    } 

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

    public OnBottomReachedListener mOnBottomReachedListener = null; 
    private int mMinDistance = 0; 

    /** 
    * Set the listener which will be called when the WebView is scrolled to within some 
    * margin of the bottom. 
    * @param bottomReachedListener 
    * @param allowedDifference 
    */ 
    public void setOnBottomReachedListener(OnBottomReachedListener bottomReachedListener, int allowedDifference) { 
     mOnBottomReachedListener = bottomReachedListener; 
     mMinDistance = allowedDifference; 
    } 

    /** 
    * Implement this interface if you want to be notified when the WebView has scrolled to the bottom. 
    */ 
    public interface OnBottomReachedListener { 
     void onBottomReached(View v); 
    } 

    @Override 
    protected void onScrollChanged(int left, int top, int oldLeft, int oldTop) { 
     if (mOnBottomReachedListener != null) { 
      if ((getContentHeight() - (top + getHeight())) <= mMinDistance) 
       mOnBottomReachedListener.onBottomReached(this); 
     } 
     super.onScrollChanged(left, top, oldLeft, oldTop); 
    } 

} 

Ich benutze diese ein, sobald der Benutzer auf dem Boden des WebView gescrollt hat „I Agree“, um anzuzeigen, wo ich es wie folgt aus (in einer Klasse aufrufen, die „OnBottomReachedListener implementiert“:

EulaWebView mEulaContent; 
Button mEulaAgreed; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.eula); 
    mEulaContent = (EulaWebView) findViewById(R.id.eula_content); 
    StaticHelpers.loadWebView(this, mEulaContent, R.raw.stylesheet, StaticHelpers.readRawTextFile(this, R.raw.eula), null); 
    mEulaContent.setVerticalScrollBarEnabled(true); 
    mEulaContent.setOnBottomReachedListener(this, 50); 

    mEulaAgreed = (Button) findViewById(R.id.eula_agreed); 
    mEulaAgreed.setOnClickListener(this); 
    mEulaAgreed.setVisibility(View.GONE); 
} 

@Override 
public void onBottomReached(View v) { 
    mEulaAgreed.setVisibility(View.VISIBLE); 
} 
So

, wenn der Boden erreicht ist (oder in diesem Fall, wenn sie innerhalb von 50 Pixeln davon bekommen) die „I Agree“ Taste erscheint.

+0

Hallo, können Sie mir bitte mitteilen, wo 'StaticHelpers' deklariert wurde? –

+0

StaticHelpers ist eine interne Klasse mit ein paar allgemeinen Methoden - in diesem Fall zum Laden einer Webansicht und zum Lesen einer Textdatei aus dem Dateisystem - nichts besonderes hier. – karora

-1

Lösungen oben nicht vollständig für das ähnliche Problem für mich arbeiten (Verstecken Sie die Taste, während WebView gescrollt wird, zeigen Sie nach dem Scrollen ist vorbei.) Der Grund, warum ich wollte d es beim Scrollen zu verbergen ist, weil die Schaltfläche, die ich ausblenden möchte, zum Sprung an den unteren Rand von webview ist, und wenn es nur für mich funktioniert, wenn webview statisch ist, aber nicht nach unten springt, während die Ansicht noch gescrollt wird. Also habe ich folgendes:

einen onScrollChanged Rückruf hinzugefügt WebView außer Kraft gesetzt, wie in der Nähe vorgeschlagen:

Timer timer2showJumpButton; 
private long lastScrollEventTimestamp; 
public final static int HIDING_JUMP_BUTTON_ON_SCROLL_DELAY = 500; 

    public void onScrollChanged(int l, int t) { 

    // showing button when scrolling starts 
    if (btnJumpToBottom != null) { 
     btnJumpToBottom.setVisibility(View.VISIBLE); 
    } 

    if (btnJumpToTop!= null) { 
     btnJumpToTop.setVisibility(View.VISIBLE); 
    } 


    if (timer2showJumpButton == null) { 

     final Runnable r2 = new Runnable() { 

      @Override 
      public void run() { 
       if (btnJumpToBottom != null) { 
        btnJumpToBottom.setVisibility(View.GONE); 
       } 
       if (btnJumpToTop!= null) { 
        btnJumpToTop.setVisibility(View.GONE); 
       } 

      } 
     }; 

     TimerTask timerTask = new TimerTask() { 
      @Override 
      public void run() { 
       if (btnJumpToTop.getVisibility() == View.VISIBLE || btnJumpToBottom.getVisibility() == View.VISIBLE){ 
        long currentTimestamp = System.currentTimeMillis(); 

        if (currentTimestamp - lastScrollEventTimestamp > HIDING_JUMP_BUTTON_ON_SCROLL_DELAY1){       
         webView.postDelayed(r2, HIDING_JUMP_BUTTON_ON_SCROLL_DELAY); 
        }else{ 
         //too soon 
        } 
       } 
      } 
     }; 

     try { 
      timer2showJumpButton = new Timer(); 
      timer2showJumpButton.schedule(timerTask, 500, 500); 
     } catch (IllegalStateException e) { 
      logger.warn(TAG + "/onScrollChanged/" + e.getMessage()); 

     } 
    } 

    // adding runnable which will hide button back 
    long currentTimestamp = System.currentTimeMillis(); 

    lastScrollEventTimestamp = currentTimestamp; 
} 
:

private OnScrollChangedCallback mOnScrollChangedCallback; 

public OnScrollChangedCallback getOnScrollChangedCallback() { 
    return mOnScrollChangedCallback; 
} 

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

@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.onScrollChanged(l, t); 
    } 
} 

/** 
* Implement in the activity/fragment/view that you want to listen to the 
* webview 
*/ 
public static interface OnScrollChangedCallback { 
    public void onScrollChanged(int l, int t); 
} 

und in meiner Tätigkeit Klasse, die OnScrollChangedCallback

AKTUALISIERT implementiert

+0

herausgefunden, dass "web.pageDown (true);" funktioniert beim Scrollen, aber "web.scrollTo (0, scrollTo);" wird ignoriert. – shtolik

+0

Wenn die Seite gescrollt wird, erhalten Sie Hunderte von onScrollChanged Callbacks, die eine große Menge an Timer-Objekten zuweisen :) Eine Möglichkeit wäre, einen Timer/Thread zu haben, der mit einem festen Intervall (~ 500ms) läuft. Dann notieren Sie den letzten Scroll-Zeitstempel bei onScrollChanged und deaktivieren/aktivieren die Schaltflächen für den Timer, abhängig vom letzten Scroll-Zeitstempel. – noxo

+0

Antwort entsprechend aktualisiert – shtolik

0

Loading/Visible-Schaltfläche nur, wenn das Webview nach unten/scrollt.

erstellen JavaScript-Klasse:

public class JavaScriptInterface { 

    @android.webkit.JavascriptInterface 
    public void didScrollToBottom() { 
    Log.d(TAG, "Scroll to Bottom"); 
    myHandler.post(new Runnable() { 
     @Override 
     public void run() { 
     btnAccept.setVisibility(View.VISIBLE); 

      } 
     }); 
     } 
    } 

In onCreate():

final JavaScriptInterface jsInterface = new JavaScriptInterface(); 
myWebView.addJavascriptInterface(jsInterface, "AndroidFunction"); 
0

[Ich kann nicht auf eine Antwort kommentieren, so dass mein Kommentar hier als eine neue Antwort zu verlassen]

karaas Antwort (die erste) funktioniert sehr gut, außer dass in der

protected void onScrollChanged(int left, int top, int oldLeft, int oldTop) 

Methode war

getContentHeight() 

fordern mich wild ungenau. Es wurde ein viel zu kleiner Wert gemeldet, so dass mein Listener aufgerufen wurde, wenn der Benutzer nur ein Drittel der Strecke im WebView gescrollt hatte. Ich benutzte

computeVerticalScrollRange() 

stattdessen, und das ist perfekt. Danke an this post für diesen hilfreichen Hinweis.