答えて

46

例:他の2つの答えとして

mView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT); 
+26

これは、XML経由でも可能です:アンドロイド:verticalScrollbarPositionは= –

+0

は悲しい[NavigationView](http://developer.android.com/intl/ru/reference/android/support/design/で働いていない "左"ウィジェット/ NavigationView.html)(API 23)。 – Luten

3

は、一つの可能​​性はSCROLLBAR_POSITION_LEFTView.setVerticalScrollbarPosition()を使用して、言及しています。しかし、巨大な注意点の1つは、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_CDK_INT

関連する問題