回答

46

例如:

mView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT); 
+26

它也可以通過XML:機器人:verticalScrollbarPosition = 「左」 –

+0

遺憾的是不能在[NavigationView]工作(http://developer.android.com/intl/ru/reference/android/support/design/ widget/NavigationView.html)(API 23)。 – Luten

3

作爲其它兩個答案都提到,一種可能性是使用View.setVerticalScrollbarPosition()SCROLLBAR_POSITION_LEFT用。然而,一個巨大的警告是,這需要API級別11+,在寫入Android安裝的時間不到10%的時候。對於大多數應用程序,這是不可接受的。

我想到的來完成你想要的東西在舊版本的Android的是做一件很缺憾一種可能性:關閉滾動條,用窄佈局鏡像您的主要佈局於它的左側,稍稍偏出足以適合滾動條,並在您的主視圖滾動時通過手動滾動左側視圖scrollyBy()(通過覆蓋 onScrollChanged())。

這就是說,我不會真正推薦,除非有非常令人信服的理由將滾動條移動到左側。在大多數情況下,只要讓Android遵循其默認設置,即可讓您的應用適應設備上的其他應用,並像其他應用一樣運行。

1

試試我的黑客,似乎至少在2.2及以上的工作。

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

我在2.2.1上試過了,它沒有工作。 –

+0

好吧,如果我在'if(Build.VERSION.SDK_INT

相關問題