为Android HorizontalListView添加Scrollbar

最近由于项目需要,要实现一个横向滚动的列表,打算直接用HorizontalScrollView,但是因为没有视图复用,列表项多了之后会占用较多内存,排除;再想到用Gallery,但Gallery有一个自动定位到中央的动画效果,要去除这个效果的工作比较复杂。最后搜了一下找到了这个Android-HorizontalListView,实现了ListView的大部分功能,只是不支持Header、Footer和ScrollBar,项目要求提供Scroolbar的显示,所以就在上面动手吧,添加横向的Scrollbar。

ScrollBar作为一个基础功能被实现在View中,子类需要实现computeXXXScrollRange、computeXXXScrollExtent和computeXXXScrollOffset这三个方法,其中:

1、computeXXXScrollRange,计算滚动条的滚动范围

2、computeXXXScrollExtent,计算滑块显示的大小

3、computeXXXScrollOffset,计算滚动的偏移量,也就是当前滚动的位置

上面这三个方法返回的值都是相对值,也就是计算的时候采用一个统一的度量,具体视图上的显示在View的onDrawScrollbar()方法中已经实现。

有了这三个方法之后,还需要调用在滚动的过程中调用awakenScrollbars(),因为Scrollbar在停止滚动后会自动隐藏,所以就需要在滚动的时候不断唤起scrollbar让它显示出来,也就是这个方法。

HorizontalListView通过监听滚动手势来不断requestLayout,重新布局列表的显示来达到滚动的效果,所以awakenScrollbars这个方法就添加在onLayout中。

protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		super.onLayout(changed, left, top, right, bottom);

		if (mAdapter == null) {
			return;
		}

		// Force the OS to redraw this view
		if (!awakenScrollBars()) {
			postInvalidate();
		}

		...
}

下面添加scrollbar相关的计算

@Override
	protected int computeHorizontalScrollRange() {
		int count = mAdapter.getCount();
		return Math.max(count * 100, 0);
	}

	@Override
	protected int computeHorizontalScrollExtent() {
		int count = getChildCount();
		if (count > 0) {
			int extent = count * 100;

			View view = getChildAt(0);
			final int left = view.getLeft();
			int width = view.getWidth();
			if (width > 0) {
				extent += (left * 100) / width;
			}

			view = getChildAt(count - 1);
			final int right = view.getRight();
			width = view.getWidth();
			if (width > 0) {
				extent -= ((right - getWidth()) * 100) / width;
			}

			return extent;

		}
		return 0;
	}

	@Override
	protected int computeHorizontalScrollOffset() {
		final int firstPosition = mLeftViewAdapterIndex;
		final int childCount = getChildCount();
		if (firstPosition >= 0 && childCount > 0) {
			final View view = getChildAt(0);
            final int left = view.getLeft();
            int width = view.getWidth();
            if (width > 0) {
            	int result = Math.max(firstPosition * 100 - (left * 100) / width, 0);
                return result;
            }
		}
		return 0;
	}

这里参考了AbsListView中的实现,上面的计算过程比较容易理解,×100是为了保持两位小数的精度。range的值就是总的列表项个数(mAdapter.getCount());滑块的大小extent是当前显示的个数,然后去除左右边界超出的部分来提高精度;offset是显示的第一个列表的索引值。也就是说上面采用了“个数”为度量单位进行计算。

时间: 2024-10-18 04:10:45

为Android HorizontalListView添加Scrollbar的相关文章

【转】为Android应用添加搜索功能

为Android应用添加搜索功能 为Android应用增加搜索功能:增加搜索建议

为android系统添加USB AUDIO设备的放音和录音功能

http://blog.csdn.net/adits/article/details/8242146 开发环境简介 1. 主机系统: Unbuntu10.102. android系统版本: 4.0.3(Linux kernel 3.0.8) 综述 android的音频系统非常庞大复杂:涉及到java应用程序,java框架层,JNI,本地服务(AudioFlinger和AudioPolicyService),硬件抽象层HAL,ALSA-LIB和ALSA-DRIVER.本文将先分析音频系统的启动与模

Android Studio添加Parcelable序列化小工具(快速提高开发效率)

Android Studio添加Parcelable序列化小工具(快速提高开发效率) Android Studio是google专门为开发Android提供的开发工具,在它内部可以直接的添加一些非常好用的开发小工具,这里就讲解怎样添加这些小工具,并且向大家推荐一个非常有用的对象传递时,必须要把对象序列化的接口Parcelable小工具; 这里先介绍下 Android中实现序列化的两个选择:一是实现Serializable接口(是JavaSE本身就支持的),一是实现Parcelable接口(是An

Android学习路线(六)为Android应用添加ActionBar

Action bar 是你可以为你的应用的Activity实现的最为重要的设计元素之一.它提供了集中UI特性,并且通过提供和其他的Android应用的一致性体验让你的应用能够很快被用户熟悉.主要的功能包括: 一个专用的显示应用表示的地方,并且能够指出用户当前在应用中的位置. 用户能够很方便地访问重要的功能(例如搜索). 提供视图切换导航(通过tab,或者下拉列表). 这次的训练课程提供了对action bar基础知识的快速引导.有关action bar的各种特性的更多信息,请查看Action B

Android studio 添加依赖

以前添加依赖总是到github上下载源码,再添加源码到module的依赖当中,其实在studio中,应该使用maven库. 比如在github上看到了sliding-menu这个项目,就应该到maven网站上找对应的库,之后把地址写入build.gradle中,比如以下就是sliding-menu的库, compile 'com.github.itsmechlark.android-sliding-menu:android-sliding-menu:1.0.1' 这样做的好处就是不必再 Andr

Android课程---添加黑名单的练习(课堂讲解)

DBHelper.java package com.hanqi.test3; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; /** * Created by Administrator on 2016/4/15. */ public cla

android如何添加桌面图标和卸载程序后自动删除图标

android如何添加桌面图标和卸载程序后自动删除桌面图标,这是一个应用的安装与卸载过程对桌面图标的操作,下面与大家分享下具体是如何实现的,感兴趣的朋友可以参考下哈 1:创建图标如下 Intent intent = new Intent(); intent.setClass(this, SplashActivity.class); Intent addShortcut = new Intent(ACTION_ADD_SHORTCUT); Parcelable icon = Intent.Shor

使用 Unity* 游戏引擎向 Android* 应用添加 x86 支持

概述 在当前基于 Unity* ARM* 的 Android* SDK 游戏中添加原生 x86 支持非常简单.  本文介绍了如何在最新的 Unity 4 或 Unity 5 项目中生成一个包括 x86 和 ARM 库在内的 FAT APK. 英特尔与 Unity 联手将 x86 Android 功能添加到即将公开发行的 Unity 4.6 和 Unity 5. 版本上线后,我们将在 https://software.intel.com/zh-cn/articles/unity 上进行更新. 如果

Android中添加思源字体/NotoSansCJK/SourceHanSans

系统版本:Android 4.2.2_r1 本文主要是在Android中添加思源字体的过程记录.思源字体是Google和Adobe在2014.07.18发布的中文字体. 1.获取思源字体(Google:Noto Sans CJK; Adobe:Source Han Sans). 2.解压后如下几个才是思源字体. NotoSansHans-Regular.otf    常规 NotoSansHans-Black.otf      黑体 NotoSansHans-DemiLight.otf Noto