Trả lời

46

dụ:

mView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_LEFT); 
+26

nó cũng có thể thông qua xml: android: verticalScrollbarPosition = "left" –

+0

Đáng buồn là không làm việc trong [NavigationView] (http://developer.android.com/intl/ru/reference/android/support/design/ widget/NavigationView.html) (API 23). – Luten

3

Bạn có thể di chuyển vị trí thanh cuộn sang bên trái cho bất kỳ Chế độ xem nào bằng cách sử dụng View.SCROLLBAR_POSITION_LEFT.

3

Khi hai câu trả lời khác đã đề cập, một trong những khả năng được sử dụng View.setVerticalScrollbarPosition() với SCROLLBAR_POSITION_LEFT. Tuy nhiên, một báo trước khổng lồ là điều này đòi hỏi cấp API 11+, mà tại thời điểm viết tài khoản cho ít hơn 10% cài đặt Android. Đối với hầu hết các ứng dụng, điều đó không thể chấp nhận được. Một trong những khả năng đến với tâm trí để thực hiện những gì bạn muốn trên các phiên bản Android cũ hơn sẽ làm điều gì đó rất kludgy: tắt thanh cuộn, phản chiếu bố cục chính của bạn với một bố trí hẹp bên trái của nó, chỉ rộng đủ để vừa với thanh cuộn và cuộn theo cách thủ công chế độ xem trái với scrollyBy() khi chế độ xem chính của bạn được cuộn (bằng cách ghi đè onScrollChanged()).

Điều đó nói rằng, tôi sẽ không thực sự khuyên rằng trừ khi có một lý do rất thuyết phục để di chuyển thanh cuộn sang bên trái. Trong hầu hết các trường hợp, bạn muốn ứng dụng của mình phù hợp và hoạt động giống như bất kỳ ứng dụng nào khác trên thiết bị bằng cách chỉ cho phép Android tuân theo các giá trị mặc định của ứng dụng đó.

1

Hãy thử hack của tôi, dường như hoạt động ít nhất là từ 2.2 trở lên.

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

Tôi đã thử nó trên 2.2.1 và nó không hoạt động. –

+0

Vâng, nó hoạt động nếu tôi gọi 'tryApiLevelPre11()' trong cơ thể 'if (Build.VERSION.SDK_INT

Các vấn đề liên quan