Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 重新定位listview的滚动条_Android_Xml_Listview_Android Listview_Scrollbar - Fatal编程技术网

Android 重新定位listview的滚动条

Android 重新定位listview的滚动条,android,xml,listview,android-listview,scrollbar,Android,Xml,Listview,Android Listview,Scrollbar,我有一个定制的listview——其中的对象来自一个定制的BaseAdapter。我还为滚动条制作了以下形状: 但是现在滚动条粘在屏幕的右侧,我希望它稍微向左,这样滚动条和屏幕边缘之间就有一个小的填充物。无论我在上面输入了什么值,上面形状的padding属性似乎都不起作用 我的listview,如果有帮助: 我尝试了xml中的scrollbarPositionStyles,但没有达到预期效果-试试这个。 您可以使用View.scrollbar\u position\u left将任何视图

我有一个定制的listview——其中的对象来自一个定制的BaseAdapter。我还为滚动条制作了以下形状:


但是现在滚动条粘在屏幕的右侧,我希望它稍微向左,这样滚动条和屏幕边缘之间就有一个小的填充物。无论我在上面输入了什么值,上面形状的padding属性似乎都不起作用

我的listview,如果有帮助:


我尝试了xml中的scrollbarPositionStyles,但没有达到预期效果-

试试这个。
您可以使用View.scrollbar\u position\u left将任何视图的滚动条位置向左移动。

您也可以尝试此方法,它至少可以在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;


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);
}
}
import java.lang.reflect.Field;
导入android.annotation.SuppressLint;
导入android.content.Context;
导入android.graphics.Rect;
导入android.graphics.drawable.drawable;
导入android.graphics.drawable.LayerDrawable;
导入android.util.AttributeSet;
导入android.util.Log;
导入android.view.view;
导入android.widget.ListView;
公共类ListViewWithLeftScrollBar扩展ListView{
私有静态最终字符串LOG_TAG=ListViewWithLeftScrollBar.class.getSimpleName();
私有静态最终布尔调试=true;
私有布尔补丁失效;
带有左滚动条的公共列表视图(上下文){
超级(上下文);
移动垂直滚动条Bartotheleft();
}
带有左滚动条的公共列表视图(上下文、属性集属性){
超级(上下文,attrs);
移动垂直滚动条Bartotheleft();
}
带有左滚动条的公共列表视图(上下文上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
移动垂直滚动条Bartotheleft();
}
@凌驾
公共无效无效(Rect r){
无效(右左、右上、右右下);
}
@凌驾
公共无效无效(左整数、上整数、右整数、下整数){
整数宽度=右-左;
如果(调试)日志(“使原始w:+getWidth()+”h:+getHeight()+”rect:“+left+”、“+top+”、“+right+”、“+bottom”)无效);
if(patchInvalidate&&right==getWidth()&&top==0&&bottom==getHeight()&&width<30){
//上述条件应确保ListView很可能使滚动条无效。
//事实上,ListView似乎不会使除滚动条之外的任何内容无效。
左=0;
右=左+宽;
如果(调试)日志(“使打补丁的w失效:“+getWidth()+”h:“+getHeight()+”rect:“+left+”、“+top+”、“+right+”、“+bottom”);
}
super.invalidate(左、上、右、下);
}
私有void moveVerticalScrollbarToTheLeft()的{
试一试{
如果(调试)日志(“moveVerticalScrollbarToTheLeft:尝试API级别>=11”);
tryApiLevel11();
if(调试)日志(“moveVerticalScrollbarToTheLeft:API级别>=11成功”);
}捕获(可丢弃t1){
如果(调试){
日志(“moveVerticalScrollbarToTheLeft:API级别>=11失败”);
t1.printStackTrace();
}
试一试{
如果(调试)日志(“moveVerticalScrollbarToTheLeft:正在尝试API级别的hack
 <ListView
    android:id="@+id/mainMenuListView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/textView3"
    android:divider="@color/blue_border"
    android:dividerHeight="1px"
    android:scrollbarThumbVertical="@drawable/scroller"
    >
 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;


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);
}
}