13

我的要求是,只要视图的总高度大于列表的允许高度,就显示带有滚动条的垂直视图列表。

此外,我需要以编程方式自定义滚动条外观(背景和拇指)。(在运行时,我的活动将接收所有数据来进行渲染:用作滚动条背景的位图、滚动条宽度和用作滚动条拇指的位图。)

AListView似乎是一个很好的候选者,除了我找不到以编程方式自定义滚动条的方法。我在 listView 中阅读了这个问题滚动条...自定义它。但是,它使用了一个主题,并且 AFAIK 不可能以编程方式创建一个新主题。

所以我的问题:

  1. 有没有办法以编程方式自定义滚动条的外观(在 ListView 中)?

  2. [只有当第一个答案是“绝对不可能”时]您是否看到任何其他方法来满足这些要求(以及一些这样做的工作示例)

谢谢。

编辑(23/12)

我找到了这个隐藏的类android.widget.ScrollBarDrawable。可能是构建解决方案的一个很好的起点(现在没有时间研究它)。

4

5 回答 5

6

有没有办法以编程方式自定义滚动条的外观(在 ListView 中)?

从字面上看,它看起来不像,只是因为没有设置器来操作它。

可以想象,您可以创建自己的BenView子类View来替换隐藏ScrollBarDrawableBenScrollBarDrawable处理动态变化的子类。但是,您需要创建BenViewGroupBenAbsListViewBenListView,克隆它们的无 Ben 对应物的源代码,以使它们链接起来BenView以继承此行为。而且,由于任何 Android 版本中ViewGroupAbsListViewListView中的一个必然会发生变化,因此您实际上将需要这些类的 N 个副本,并在运行时根据 API 级别选择正确的副本。然后,您的应用程序可能仍然在制造商进入并修改 、 或 的某些设备上表现异常ViewGroupAbsListView并且ListView您将不会使用他们的代码。

我怀疑这是值得的,特别是因为滚动条默认情况下是不可见的,除非在滚动时。

您是否看到任何其他方式来实现这些要求(以及一些这样做的工作示例)

处理你自己的触摸事件来做你自己的滚动和你自己的滚动条的事情。这是否比上述解决方案工作量少还有待商榷。

于 2012-12-23T13:16:28.720 回答
3

我刚刚遇到了 RecyclerView 的同样问题并像这样解决了它

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;

/**
 * Created on 22.3.2016.
 *
 * @author Bojan Kseneman
 * @description A recycler view that will draw the scroll bar with a different color
 */
public class CustomScrollBarRecyclerView extends RecyclerView {

    private int scrollBarColor = Color.RED;

    public CustomScrollBarRecyclerView(Context context) {
        super(context);
    }

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

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

    public void setScrollBarColor(@ColorInt int scrollBarColor) {
        this.scrollBarColor = scrollBarColor;
    }

    /**
     * Called by Android {@link android.view.View#onDrawScrollBars(Canvas)}
     **/
    protected void onDrawHorizontalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) {
        scrollBar.setColorFilter(scrollBarColor, PorterDuff.Mode.SRC_ATOP);
        scrollBar.setBounds(l, t, r, b);
        scrollBar.draw(canvas);
    }

    /**
     * Called by Android {@link android.view.View#onDrawScrollBars(Canvas)}
     **/
    protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) {
        scrollBar.setColorFilter(scrollBarColor, PorterDuff.Mode.SRC_ATOP);
        scrollBar.setBounds(l, t, r, b);
        scrollBar.draw(canvas);
    }
}

这些方法是在 View 类中定义的,因此同样的原则应该适用于其他视图,如 ScrollView 和 ListView。

于 2016-03-22T11:31:21.173 回答
0

只需根据您的需要更改android:scrollbarThumbVertical="@drawable/scrollbar_vertical_thumb" 并创建一个drawable。

<ListView android:scrollbarThumbVertical="@drawable/scrollbar_vertical_thumb" /> 

在可绘制对象中:

<shape xmlns:android="http://schemas.android.com/apk/res/android" > 
    <gradient android:angle="0" android:endColor="#6699FF" android:startColor="#3333FF" />
    <corners android:radius="1dp" /> 
    <size android:width="1dp" /> 
</shape>

我想这就是你想要的!

于 2012-12-23T10:13:21.000 回答
0

如果您只需要支持 API 24 或更高版本,则可以使用自定义 drawable 来完成此任务。您需要决定如何允许可绘制对象与活动进行通信。这是一种可能的解决方案。

res/drawable/my_custom_scrollbar_thumb.xml

<com.example.RegisteredMutableDrawable android:id="@+id/scroll_thumb" />

res/drawable/my_custom_scrollbar_track.xml

<com.example.RegisteredMutableDrawable android:id="@+id/scroll_track" />

在你的布局文件中的某个地方

<ListView android:scrollbarTrackVertical="@drawable/my_custom_scrollbar_track" android:scrollbarThumbVertical="@drawable/my_custom_scrollbar_thumb"

可绘制的实现

public class RegisteredMutableDrawable extends DrawableWrapper
{
    public static interface Registrar
    {
        public void register(int _id, RegisteredMutableDrawable _drawable);
    }

    public static Registrar registrar;

    private static int[] ATTRS = new int[] { android.R.attr.id };

    public RegisteredMutableDrawable()
    {
        super(null);
    }

    public void inflate(Resources _res, XmlPullParser _parser, AttributeSet _as, Theme _theme)
        throws XmlPullParserException, IOException
    {
        super.inflate(_res, _parser, _as, _theme);
        final Registrar r = registrar;
        if (r != null)
        {
            final TypedArray ta = _res.obtainAttributes(_as, ATTRS);
            final int id = ta.getResourceId(0, 0);
            ta.recycle();
            r.register(id, this);
        }
    }
}

在你的活动中

public class MyActivity extends Activity implements RegisteredMutableDrawable.Registrar
{
    @Override public void onCreate(Bundle _icicle)
    {
        super.onCreate(_icicle);
        RegisteredMutableDrawable.registrar = this;
        setContentView(R.layout.whatever);
        RegisteredMutableDrawable.registrar = null; // don't leak our activity!
    }

    @Override public void register(int _id, RegisteredMutableDrawable _drawable)
    {
        switch(_id)
        {
            case R.id.scroll_thumb:
                _drawable.setDrawable(myThumbDrawable);
                break;
            case R.id.scroll_track:
                _drawable.setDrawable(myTrackDrawable);
                break;
        }
    }
}
于 2018-09-05T15:46:56.693 回答
-1

您可以使用 jquery 插件(jquery.nicescroll.js)来实现这一点。更多详情请访问 http://areaaperta.com/nicescroll/

于 2012-12-28T06:58:44.020 回答