Android 以编程方式自定义滚动条
我的要求是每当视图的总高度大于列表允许的高度时,用滚动条显示视图的垂直列表 此外,我需要以编程方式自定义滚动条的外观(背景和拇指)。(在运行时,“我的活动”将接收进行渲染的所有数据:用作滚动条背景的位图、滚动条宽度和用作滚动条拇指的位图。) A似乎是一个很好的选择,除了我找不到一种方法来以编程方式自定义滚动条。 我读了这个问题,但是,它使用了一个主题,而且很抱歉,它不可能以编程方式创建一个新的主题 因此,我的问题是:Android 以编程方式自定义滚动条,android,scrollbar,Android,Scrollbar,我的要求是每当视图的总高度大于列表允许的高度时,用滚动条显示视图的垂直列表 此外,我需要以编程方式自定义滚动条的外观(背景和拇指)。(在运行时,“我的活动”将接收进行渲染的所有数据:用作滚动条背景的位图、滚动条宽度和用作滚动条拇指的位图。) A似乎是一个很好的选择,除了我找不到一种方法来以编程方式自定义滚动条。 我读了这个问题,但是,它使用了一个主题,而且很抱歉,它不可能以编程方式创建一个新的主题 因此,我的问题是: 有没有办法通过编程自定义滚动条(在ListView中)的外观 [只有在第一个问
我发现了这个隐藏的类 ;
android.widget.ScrollBarDrawable
。可能是构建解决方案的良好起点(现在没有时间进行研究)。只需更改android:scrollbarThumbVertical=“@drawable/scrollbar\u vertical\u 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>
我想这就是你想要的
有没有办法以编程方式自定义滚动条(在ListView中)的外观
从字面上看,它看起来不像它,只是因为没有用于操纵它的设置器
可以想象,您可以创建自己的BenView
子类View
,该子类将隐藏的ScrollBarDrawable
替换为处理动态更改的BenScrollBarDrawable
。但是,您需要创建BenViewGroup
、BenAbsListView
和BenListView
,克隆它们的无本对等源代码,使它们链接到BenView
,以继承此行为。而且,由于ViewGroup
、AbsListView
或ListView
中的一个在任何Android版本中都会发生变化,因此您实际上需要这些类的N个副本,并在运行时根据API级别选择正确的副本。然后,你的应用程序可能在一些设备上仍会表现异常,制造商在这些设备上修改了ViewGroup
、AbsListView
或ListView
,你将无法使用他们的代码
我怀疑这是否值得,特别是因为滚动条在默认情况下是不可见的,除非在滚动时
您是否看到了实现这些要求的其他方法(以及实现这些要求的一些工作示例)
处理您自己的触摸事件以进行您自己的滚动和滚动条操作。这是否比上述解决方案的工作量少,还有待讨论。您可以使用jquery插件(jquery.nicesroll.js)来实现这一点。更多详情请访问
我刚刚为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);
}
}
这些方法是在视图类中定义的,因此相同的原则应该适用于其他视图,如ScrollView和ListView。如果您只需要支持API 24或更高版本,则可以使用自定义绘图来完成此任务。您需要决定如何允许drawable与活动进行通信。这里有一个可能的解决方案 res/drawable/my_custom_scrollbar_thumb.xml res/drawable/my\u custom\u scrollbar\u track.xml 在布局文件的某个地方
抱歉,但我认为您不理解这个问题:我需要以编程方式完成,而不是使用静态xml。抱歉,不是寻找浏览器解决方案。它正在拉伸滚动条以匹配父项。您的意思是滚动条与父项一样宽还是什么?
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);
}
}
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;
}
}
}