2012-05-08 13 views
15

Sto provando a impostare la posizione della vista orizzontale a scorrimento in modo che corrisponda al pulsante premuto. Ho provato a utilizzare questo per impostarlo senza successo:Posizione di impostazione Android di scrollview orizzontale

HorizontalScrollView hsv = (HorizontalScrollView)findViewById(R.id.ScrollView); 
int x, y; 
x = hsv.getLeft(); 
y = hsv.getTop(); 
hsv.scrollTo(x, y); 

Questo non produce nulla, la visualizzazione di scorrimento non è interessata. Il xml:

<HorizontalScrollView 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/ScrollView" 
     android:layout_width="fill_parent" 
     android:layout_height="50dp" 
     android:layout_alignParentBottom="true" 
     android:background="@null" 
     android:scrollbars="none" > 

     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:orientation="horizontal" > 

      <Button 
       android:layout_width="100dp" 
       android:layout_height="fill_parent" 
       android:layout_marginBottom="-5dp" 
       android:text="btn0" 
       android:id="@+id/btn0" 
       android:background="@drawable/yellow_btn" /> 

      <Button 
       android:layout_width="100dp" 
       android:layout_height="fill_parent" 
       android:layout_marginBottom="-5dp" 
       android:background="@drawable/yellow_btn" 
       android:text="bnt1" 
       android:id="@+id/btn1" /> 

      <Button 
       android:layout_width="100dp" 
       android:layout_height="fill_parent" 
       android:layout_marginBottom="-5dp" 
       android:background="@drawable/yellow_btn" 
       android:text="btn2" 
       android:id="@+id/btn2" /> 

      <Button 
       android:layout_width="100dp" 
       android:layout_height="fill_parent" 
       android:layout_marginBottom="-5dp" 
       android:background="@drawable/yellow_btn" 
       android:text="btn3" 
       android:id="@+id/btn3" /> 

     <Button 
       android:layout_width="100dp" 
       android:layout_height="fill_parent" 
       android:layout_marginBottom="-5dp" 
       android:background="@drawable/yellow_btn" 
       android:text="btn4" 
       android:id="@+id/btn4" /> 

     <Button 
       android:layout_width="100dp" 
       android:layout_height="fill_parent" 
       android:layout_marginBottom="-5dp" 
       android:background="@drawable/yellow_btn" 
       android:text="btn5" 
       android:id="@+id/btn5" /> 

     </LinearLayout> 
    </HorizontalScrollView> 

Quindi, se il tasto 5 ° è spinto (che è fuori schermo), quando la nuova attività che inizia voglio impostare la nuova vista in modo che lo ScrollView orizzontale è completamente a destra rispetto agli inizi tutto a sinistra.

Come si imposta la posizione dello scrollview orizzontale?

risposta

31

In questo momento si sta tentando di scorrere fino all'angolo superiore sinistro di HorizontalScrollView anziché alla posizione del pulsante. Prova di scorrimento alla posizione (x, y) del pulsante in questo modo:

HorizontalScrollView hsv = (HorizontalScrollView) findViewById(R.id.ScrollView); 
Button button = (Button) findViewById(R.id.btn5); 
int x, y; 
x = button.getLeft(); 
y = button.getTop(); 
hsv.scrollTo(x, y); 

EDIT:

Questo codice non si comporterà come ci si aspetterebbe se è posto in onCreate(). Anche se hai chiamato setContentView(), il layout non è stato ancora misurato e inizializzato. Ciò significa che i metodi getLeft() e getTop()will both return 0. Cercare di impostare la posizione di scorrimento prima che il layout sia completamente inizializzato non ha alcun effetto, quindi è necessario chiamare hsv.scrollTo() qualche volta dopo onCreate().

Una possibilità che sembra funzionare è l'inserimento del codice in onWindowFocusChanged():

@Override 
public void onWindowFocusChanged(boolean hasFocus) { 
    super.onWindowFocusChanged(hasFocus); 

    HorizontalScrollView hsv = (HorizontalScrollView) findViewById(R.id.ScrollView); 
    Button button = (Button) findViewById(R.id.btn5); 
    int x, y; 
    x = button.getLeft(); 
    y = button.getTop(); 
    hsv.scrollTo(x, y); 
} 

Tuttavia, questa funzione viene chiamata ogni volta che i guadagni di attività o perde l'attivazione, per cui si potrebbe finire per aggiornare la posizione di scorrimento più spesso di quanto volevi.

Una soluzione più elegante sarebbe la sottoclasse di HorizontalScrollView e impostare la posizione di scorrimento in onMeasure(), dopo aver saputo che la vista è stata inizializzata. Per fare questo, ho diviso il layout in due file e ha aggiunto una nuova classe denominata MyHorizontalScrollView:

package com.theisenp.test; 

import android.content.Context; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.HorizontalScrollView; 

public class MyHorizontalScrollView extends HorizontalScrollView { 

    public MyHorizontalScrollView(Context context) { 
     super(context); 
     addButtons(context); 
    } 

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

    /** 
    * Inflates the layout containing the buttons and adds them to the ScrollView 
    * @param context 
    */ 
    private void addButtons(Context context) { 
     View buttons = inflate(context, R.layout.buttons, null); 
     addView(buttons); 

    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

     //Find button 5 and scroll to its location 
     View button = findViewById(R.id.btn5); 
     scrollTo(button.getLeft(), button.getTop()); 
    } 
} 

Quando viene creato MyHorizontalScrollView, si gonfia e aggiunge la disposizione dei pulsanti automaticamente. Quindi, dopo aver chiamato il super onMeasure() (in modo che sappia che il layout ha terminato l'inizializzazione), imposta la posizione di scorrimento.

Questo è il nuovo main.xml. Contiene solo il nuovo MyHorizontalScrollView, sebbene sia possibile inserirlo facilmente in un layout lineare o relativo e aggiungere altri elementi di visualizzazione. (Si potrebbe sostituire com.theisenp.test con il nome del pacchetto in cui si trova MyHorizontalScrollView):

<?xml version="1.0" encoding="utf-8"?> 
<com.theisenp.test.MyHorizontalScrollView 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/ScrollView" 
android:layout_width="fill_parent" 
android:layout_height="50dp" 
android:layout_alignParentBottom="true" 
android:background="@null" 
android:scrollbars="none" /> 

e questo è il pulsanti.layout di XML che viene gonfiato automaticamente MyHorizontalScrollView:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="wrap_content" 
android:layout_height="fill_parent" 
android:orientation="horizontal" > 

    <Button 
    android:id="@+id/btn0" 
    android:layout_width="100dp" 
    android:layout_height="fill_parent" 
    android:layout_marginBottom="-5dp" 
    android:text="btn0" /> 

    <Button 
    android:id="@+id/btn1" 
    android:layout_width="100dp" 
    android:layout_height="fill_parent" 
    android:layout_marginBottom="-5dp" 
    android:text="bnt1" /> 

    <Button 
    android:id="@+id/btn2" 
    android:layout_width="100dp" 
    android:layout_height="fill_parent" 
    android:layout_marginBottom="-5dp" 
    android:text="btn2" /> 

    <Button 
    android:id="@+id/btn3" 
    android:layout_width="100dp" 
    android:layout_height="fill_parent" 
    android:layout_marginBottom="-5dp" 
    android:text="btn3" /> 

    <Button 
    android:id="@+id/btn4" 
    android:layout_width="100dp" 
    android:layout_height="fill_parent" 
    android:layout_marginBottom="-5dp" 
    android:text="btn4" /> 

    <Button 
    android:id="@+id/btn5" 
    android:layout_width="100dp" 
    android:layout_height="fill_parent" 
    android:layout_marginBottom="-5dp" 
    android:text="btn5" /> 

</LinearLayout> 
+0

ho provato questo mettendo nella giusta OnCreate dopo ho impostato il layout, ma non succede nulla. Altre idee? – Nick

+0

Ho modificato la mia risposta e ho aggiunto una spiegazione completa della soluzione. – theisenp

+1

Genio! Grazie per l'eccellente risposta. – Nick

6

Anche se, questa è una vecchia questione, di recente ho incontrato lo stesso problema e ha trovato ancora un altro, ma un po 'meno complessa soluzione.

Supponiamo il file di layout indicato nella domanda originale e supponiamo che se un'attività è iniziata con il layout data, lo ScrollView orizzontale deve essere selezionato un tasto 5.

Per raggiungere lo scorrimento al tasto 5, inserire il seguente codice nel metodo dell'attività onCreate():

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

     // Some code such as layout inflation. 

     final HorizontalScrollView hsv = (HorizontalScrollView) findViewById(R.id.ScrollView); 

     // Scrolling to button 5. 
     hsv.post(new Runnable() { 
      @Override 
      public void run() { 
       // Get the button. 
       View button = findViewById(R.id.btn5); 

       // Locate the button. 
       int x, y; 
       x = button.getLeft(); 
       y = button.getTop(); 

       // Scroll to the button. 
       hsv.scrollTo(x, y); 
      } 
     }); 
    } 
} 
+0

Questa è una soluzione molto più semplice. – lintmachine

Problemi correlati