2012-06-08 12 views
5

Ho una visualizzazione Web che mostra un file html. Quando l'utente scorre in fondo a questo file in webview, voglio un pulsante precedentemente nascosto da mostrare, che l'utente può quindi premere per fare qualche attivitàAndroid: rendere visibile un pulsante una volta che la visualizzazione è stata fatta scorrere scrolling

Ho fatto qualcosa di simile in iOS, dove ho appena impostato il delegato al ViewController e basta impostare il pulsante come visibile. Come faccio qualcosa di simile su Android? Ho notato che non esiste un metodo di callback come in iOS.

Edit: Al momento, ho un'attività con 2 oggetti: una webview contenente il mio testo e un pulsante che è attualmente invisibile. Voglio che la mia attività di ricevere un messaggio quando il testo scorre WebView verso il basso, e rendere il pulsante visibile

risposta

0

provare questo:

@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); 
} 

Per attuare questo, estendere ScrollView e quindi sovrascrivere il metodo onScrollChanged (ereditato dalla vista).

+0

La visualizzazione Web non ha tuttavia alcun riferimento al pulsante. – Daniel

2

Ho dovuto farlo da solo, al fine di visualizzare un pulsante "Accetto" dopo che l'utente ha spostato in fondo a un EULA. Avvocati, eh?

Infatti, quando si esegue l'override di WebView (anziché ScrollView come nella risposta di @JackTurky) è possibile chiamare getContentHeight() per ottenere l'altezza del contenuto, piuttosto che getBottom() che restituisce il fondo visibile ed è inutile.

Questa è la mia soluzione completa. Per quanto posso vedere, tutto questo è di livello API 1, quindi dovrebbe funzionare ovunque.

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); 
    } 

} 

Io lo uso per visualizzare un pulsante "Accetto" una volta che l'utente ha selezionato un fondo del WebView, dove io lo chiamo così (in una classe che "implementa OnBottomReachedListener":

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); 
} 

Così, quando viene raggiunto il fondo (o in questo caso, quando si arriva a meno di 50 pixel di esso) il "Accetto" appare il pulsante.

+0

Ciao, per favore fammi sapere dove è stato dichiarato 'StaticHelpers'? –

+0

StaticHelpers è una classe interna con alcuni metodi generici, in questo caso per caricare una webview e per leggere un file di testo dal filesystem, niente di particolarmente sorprendente. – karora

-1

soluzioni di cui sopra non ha funzionato per me completamente per il problema simile (nascondi il pulsante mentre è in corso lo scorrimento di WebView, mostra dopo che lo scorrimento è terminato.) La ragione per cui io wante d da nascondere mentre lo scorrimento è perché il pulsante che voglio nascondere è per saltare alla base della webview, e quando ha funzionato solo per me quando la webview è statica, ma non salta in fondo mentre la vista è ancora in scorrimento. Così ho fatto la seguente:

aggiunto un callback onScrollChanged a ignorato WebView, come suggerito vicina:

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); 
} 

e nella mia classe di attività che implementa OnScrollChangedCallback

aggiornamento:

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; 
} 
+0

Scoperto che "web.pageDown (true);" funziona durante lo scorrimento, ma "web.scrollTo (0, scrollTo);" è ignorato – shtolik

+0

Quando si scorre la pagina, si ottengono centinaia di richiami onScrollChanged, che allocano una grande quantità di oggetti Timer :) Un modo sarebbe avere un timer/thread, che verrà eseguito con intervallo fisso (~ 500ms). Quindi registrerai l'ultimo timestamp di scorrimento su onScrollChanged e disabiliterà/abiliterà i pulsanti sul timer in base all'ultimo timestamp di scorrimento. – noxo

+0

Risposta aggiornata di conseguenza – shtolik

0

Pulsante Caricamento/Visibile solo quando la visualizzazione Web è stata raggiunta/scorsa verso il basso.

Crea classe JavaScript:

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

[Non posso commentare una risposta, in modo da lasciare il mio commento qui come una nuova risposta]

La risposta di Karora (la prima) funziona molto bene, tranne che nel

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

metodo, chiamando

getContentHeight() 

è stato selvaggiamente impreciso per me. Ha riportato un valore troppo piccolo, quindi il mio listener è stato chiamato quando l'utente ha eseguito lo scorrimento solo di un terzo della WebView. Ho usato

computeVerticalScrollRange() 

invece, e questo è perfetto. Grazie a this post per quel suggerimento utile.

Problemi correlati