My requirements are to display a vertical list of views with a scrollbar whenever the total height of the views is bigger than the allowed height for the list.
Additionally, I need to customize the scrollBar appearance (background and thumb) programmatically. (At runtime, my activity will receive all the data to do the rendering : the bitmap to use as scrollbar background, the scrollbar width and the bitmap to use as scrollbar's thumb.)
A ListView
seems a good candidate for this, except that I can't find a way to customize the scrollBar programmatically.
I read this question scrollBar in a listView...customizing it. but, it's using a theme, and AFAIK it's not possible the create a new theme programmatically.
So my question(s):
Is there a way to customize the appearance of a scrollbar (within a ListView) programmatically ?
[only if the answer to the first one is "definitively not possible"] do you see any other way to achieve those requirements (and some working example of doing it)
Thanks.
EDIT (23/12)
I found this hidden class android.widget.ScrollBarDrawable
. May be a good starting point to build a solution (no time to investigate it right now).
Scrollbar Selectors For webkit browsers, you can use the following pseudo elements to customize the browser's scrollbar: ::-webkit-scrollbar the scrollbar. ::-webkit-scrollbar-button the buttons on the scrollbar (arrows pointing upwards and downwards). ::-webkit-scrollbar-thumb the draggable scrolling handle.
If you want to add a scrollbar to an element like a <div>, you'll have to use the CSS overflow property. Scrollbars can be vertical (Y-axis) or horizontal (X-axis). Implementing a custom scrollbar to elements is the same. In this example, I'll create vertical custom scrollbar on a <div>, which is just 5px wide.
We can use the CSS “::-webkit-scrollbar” property which is responsible for changing the shape, color, size, shade, shadow, etc. of the scroll bar. But, here the property which we will use is the direction property of CSS for changing the position of the scroll bar.
The scrollbar-color property is used to set the color of an element's scrollbar. It can be used to control both the scrollbar track and scrollbar thumb colors separately.
is there a way to customize the appearance of a scrollbar (within a ListView) programmatically ?
Literally, it does not look like it, simply because there are no setters for manipulating it.
It is conceivable that you could create your own BenView
subclass of View
that replaces the hidden ScrollBarDrawable
with BenScrollBarDrawable
that handles dynamic changes. But then you would need to create BenViewGroup
, BenAbsListView
, and BenListView
, cloning their Ben-less counterparts' source code, to have them chain up to BenView
to inherit this behavior. And, since one of ViewGroup
, AbsListView
, or ListView
is bound to change in any Android release, you will actually need N copies of these classes and choose the right copy based on API level at runtime. And then your app may still behave oddly on some devices where the manufacturer went in and tinkered with ViewGroup
, AbsListView
, or ListView
, and you will not be using their code.
I doubt that this is worth it, particularly since scrollbars are not visible by default except while scrolling.
do you see any other way to achieve those requirements (and some working example of doing it)
Handle your own touch events to do your own scrolling and do your own scrollbar stuff. Whether this is less work than the above solution is up for debate.
I just faced the same problem for RecyclerView and solved it like this
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);
}
}
These methods are defined in View class, so the same princible should work of other views like ScrollView and ListView.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With