risposta

46

esempio:

mView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT); 
+26

è anche possibile tramite XML: android: verticalScrollbarPosition = "left" –

+0

Purtroppo non funziona in [NavigationView] (http://developer.android.com/intl/ru/reference/android/support/design/ widget/NavigationView.html) (API 23). – Luten

3

Come gli altri due risposte hanno già detto, una possibilità è l'utilizzo View.setVerticalScrollbarPosition() con SCROLLBAR_POSITION_LEFT. Tuttavia, un avvertimento enorme è che questo richiede API 11+, che al momento della scrittura rappresenta meno del 10% delle installazioni Android. Per la maggior parte delle applicazioni, non è accettabile.

Una possibilità che ti viene in mente di realizzare ciò che desideri nelle versioni precedenti di Android sarebbe quella di fare qualcosa di molto sfacciato: spegni la barra di scorrimento, rispecchia il tuo layout principale con un layout stretto a sinistra, appena largo abbastanza per adattarsi a una barra di scorrimento e scorrere manualmente la vista sinistra con scrollyBy() mentre la vista principale viene scorsa (ignorando onScrollChanged()).

Detto questo, in realtà non lo consiglierei a meno che non ci sia un motivo molto convincente per spostare la barra di scorrimento a sinistra. Nella maggior parte dei casi, desideri che la tua app si adatti e si comporti come qualsiasi altra app sul dispositivo, semplicemente lasciando che Android segua i suoi valori predefiniti.

1

Prova il mio hack, sembra funzionare almeno sul 2.2 e sopra.

import java.lang.reflect.Field; 

import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.Rect; 
import android.graphics.drawable.Drawable; 
import android.graphics.drawable.LayerDrawable; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.View; 
import android.widget.ListView; 

/** 
* This class fixes the lack of setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT) before API level 11 
* @author Genadz Batsyan 
*/ 

public class ListViewWithLeftScrollBar extends ListView { 
    private static final String LOG_TAG = ListViewWithLeftScrollBar.class.getSimpleName(); 
    private static final boolean DEBUG = true; 

    private boolean patchInvalidate; 

    public ListViewWithLeftScrollBar(Context context) { 
     super(context); 
     moveVerticalScrollbarToTheLeft(); 
    } 

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

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

    @Override 
    public void invalidate(Rect r) { 
     invalidate(r.left, r.top, r.right, r.bottom); 
    } 

    @Override 
    public void invalidate(int left, int top, int right, int bottom) { 
     int width = right - left; 
     if (DEBUG) log("invalidate original w:"+ getWidth() +" h:"+ getHeight()+" rect:"+left+", "+top+", "+right+", "+bottom); 
     if (patchInvalidate && right == getWidth() && top == 0 && bottom == getHeight() && width < 30) { 
      // The above condition should ensure that ListView is VERY likely to be invalidating the scrollbar. 
      // In fact ListView appears to not invalidate anything except the scrollbar, ever. 
      left = 0; 
      right = left + width; 
      if (DEBUG) log("invalidate patched w:"+ getWidth() +" h:"+ getHeight()+" rect:"+left+", "+top+", "+right+", "+bottom); 
     } 
     super.invalidate(left, top, right, bottom); 
    } 

    private void moveVerticalScrollbarToTheLeft() { 
     try { 
      if (DEBUG) log("moveVerticalScrollbarToTheLeft: Trying API Level >=11"); 
      tryApiLevel11(); 
      if (DEBUG) log("moveVerticalScrollbarToTheLeft: API Level >=11 success"); 
     } catch (Throwable t1) { 
      if (DEBUG) { 
       log("moveVerticalScrollbarToTheLeft: API Level >=11 FAILED"); 
       t1.printStackTrace(); 
      } 
      try { 
       if (DEBUG) log("moveVerticalScrollbarToTheLeft: Trying hack for API Level <11"); 
       tryApiLevelPre11(); 
       patchInvalidate = true; 
       if (DEBUG) log("moveVerticalScrollbarToTheLeft: API Level <11 hack success"); 
      } catch (Throwable t2) { 
       if (DEBUG) { 
        log("moveVerticalScrollbarToTheLeft: API Level <11 hack FAILED"); 
        t2.printStackTrace(); 
       } 
      } 
     } 
    } 

    @SuppressLint("NewApi") 
    private void tryApiLevel11() { 
     setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT); 
    } 

    private void tryApiLevelPre11() throws Exception { 
     Class<?> viewClass = View.class; 

     Field scrollCacheField = viewClass.getDeclaredField("mScrollCache"); 
     scrollCacheField.setAccessible(true); 
     Object scrollCache = scrollCacheField.get(this); 
     if (DEBUG) log("scrollCache: "+ scrollCache); 

     Field scrollBarField = scrollCache.getClass().getDeclaredField("scrollBar"); 
     scrollBarField.setAccessible(true); 
     Object scrollBar = scrollBarField.get(scrollCache); 
     if (DEBUG) log("scrollBar: "+ scrollBar); 

     Field verticalThumbField = scrollBar.getClass().getDeclaredField("mVerticalThumb"); 
     verticalThumbField.setAccessible(true); 
     Object verticalThumb = verticalThumbField.get(scrollBar); 
     if (DEBUG) log("verticalThumb: "+ verticalThumb); 

     Drawable verticalThumbDrawable = (Drawable) verticalThumb; 
     Drawable replacementVerticalThumbDrawable = new LayerDrawable(new Drawable[]{ verticalThumbDrawable }) { 
      @Override 
      public void setBounds(int left, int top, int right, int bottom) { 
       if (DEBUG) log("setBounds original: "+left+", "+top+", "+right+", "+bottom); 
       int width = right - left; 
       left = 0; 
       right = left + width; 
       if (DEBUG) log("setBounds patched: "+left+", "+top+", "+right+", "+bottom); 
       super.setBounds(left, top, right, bottom); 
      }  
     }; 
     verticalThumbField.set(scrollBar, replacementVerticalThumbDrawable); 
    } 

    private static void log(String msg) { 
     Log.d(LOG_TAG, msg); 
    } 
} 
+0

Ho provato su 2.2.1 e non ha funzionato. –

+0

Bene, funziona se chiamo 'tryApiLevelPre11()' nel corpo di 'if (Build.VERSION.SDK_INT

Problemi correlati