如何自定义ListView上的滚动条?

时间:2015-04-09 13:40:34

标签: android android-listview scrollbar

注意:在您说它是重复的并且其他人已经解决它并且有教程(例如this one)之前,我知道,但由于某种原因,它们不适合我。

背景

我已经创建了一个库(here),它显示了如何模仿Lollipop的Contacts应用程序在左侧显示标题的方式。

我想知道如何在Lollipop上自定义滚动条和快速滚动条(就像我已经完成with RecyclerView那样的联系人应用程序,或者像ListView的默认应用程序一样)

问题

出于某种原因,即使我使用了在所有教程和StackOverflow帖子中讨论的相同属性,它们也不会做任何事情。

这是我创建的风格:

<style name="CustomTheme" >
  <item name="android:scrollbarFadeDuration">250</item>
  <item name="android:scrollbarDefaultDelayBeforeFade">300</item>
  <item name="android:scrollbarSize">10dip</item>
  <item name="android:scrollbarThumbHorizontal">@drawable/scrollbar_handle_material</item>
  <item name="android:scrollbarThumbVertical">@drawable/scrollbar_handle_material</item>
  <item name="android:scrollbarTrackHorizontal">@null</item>
  <item name="android:scrollbarTrackVertical">@null</item>
</style>

RES /抽拉/ scrollbar_handle_material.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:tint="?attr/colorControlNormal"
       android:shape="rectangle">
  <solid android:color="#84ffffff"/>
  <size android:width="4dp"/>
</shape>

当然我将它用于ListView:

style="@style/CustomTheme"

我尝试了什么

好吧,我尝试使用属性,我尝试使用简单的ListView(和GridView,使用示例“DisplayingBitmaps”),我尝试在ListView标记中设置属性(而不是使用样式):

            android:scrollbarFadeDuration="250"
            android:scrollbarDefaultDelayBeforeFade="300"
            android:scrollbarSize="10dp"
            android:scrollbarThumbHorizontal="@drawable/scrollbar_handle_material"
            android:scrollbarThumbVertical="@drawable/scrollbar_handle_material"
            android:scrollbarTrackHorizontal="@null"
            android:scrollbarTrackVertical="@null"

......但什么都没做......

问题

怎么可能?少了什么东西?怎么了?

我也想问一下Android 2.x是否可行。

1 个答案:

答案 0 :(得分:2)

我环顾四周时遇到了你的问题。果然,本周我遇到了同样的问题(涉及自定义滚动条)。我提出了一个解决方案,它不是 丑陋,但另一方面它是高度可定制的,它应该适用于没有布局问题的所有设备,所以这是一个加号。

我制作了一个外部自定义滚动条容器(类似PC,带有轨道背景等):

<FrameLayout //for single-child, absolute placement (margin pixels)
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@+id/listView" //I placed scrollbar aside my container
    android:id="@+id/scrollbarcontainer"
    android:background="@drawable/scrollbg">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/scrollbar"
        android:src="@drawable/scrollbarthumb"
        android:scaleType="fitXY"/> //thumb is stretched to indicate list length
</FrameLayout>

我将它连接到listView上的onScrollListener

    findViewById(R.id.listView).setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view,int scrollState) {
            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)findViewById(R.id.scrollbar).getLayoutParams();

            //proportional math, will match exactly to default scroll thumb
            double scrlboxh = (double)findViewById(R.id.scrollbarcontainer).getHeight();
            double ttllen = (double)***LIST_LENGTH_IN_PIXELS***;
            double scrlpos = (double)view.getScrollY();
            double boxh = (double)findViewById(R.id.listView).getHeight(); //layout height on screen

            double calc = scrlboxh / (ttllen/boxh);

            params.height = (int)Math.round(calc);

            calc = scrlboxh / (ttllen/scrlpos);

            params.topMargin = (int)Math.round(calc);

            findViewById(R.id.scrollbar).setLayoutParams(params);
        }
        @Override
        public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount) {
        }
    });

我在scrollView中使用了此代码,因此无论如何,您都必须以像素 计算 列表长度。

使滚动条可拖动:添加类范围变量private double scrollstore = 0;然后:

    findViewById(R.id.scrollbar).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v,MotionEvent event) {
            switch(event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    scrollstore = ((FrameLayout.LayoutParams)v.getLayoutParams()).topMargin - event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)v.getLayoutParams();
                    double thumbpos = event.getRawY()+scrollstore;
                    double scrlboxh = findViewById(R.id.scrollbarcontainer).getHeight();
                    if(thumbpos<0) thumbpos = 0;
                    if(thumbpos>scrlboxh-params.height) thumbpos = scrlboxh-params.height;
                    params.topMargin = (int)Math.round(thumbpos);
                    v.setLayoutParams(params);
                    double ttllen = (double)***LIST_LENGTH_IN_PIXELS***;
                    double calc = ttllen * (thumbpos/scrlboxh);
                    findViewById(R.id.scrollView).scrollTo(findViewById(R.id.scrollView).getScrollX(),(int)Math.round(calc));
                    break;
            }
            return true;
        }
    });

快乐编码,