为ViewPager添加一个indicator

天は二物を与えず

ViewPager是Android提供的一个良心组件,有了它分分钟就可以实现了一个水平滑动的分页功能,其中用ViewPager来全屏展示图片是一个比较经典的使用场景,先来看一下效果图:

在每个Page的底部中间位置有一排圆圈,实心的圆圈用来指示当前显示的图片,它会随着手指滑动而移动,我们可以称之为 ViewPager 的 indicator

实现这个功能也比较简单,首先定义一个水平方向的LinearLayout用来显示 indicator,然后把这个LinearLayout和ViewPager作为子元素放在一个FrameLayout中,这样 indicator 的 LinearLayout 会在显示在 ViewPager 的上层,初步达到了显示效果,但是滑动效果还没有实现。

首先新建一个LinearLayout的子类 - CirclePageIndicator

public class CirclePageIndicator extends LinearLayout

如果要优雅地实现这个类,可以参考Android中如何优雅地自定义一个View

根据 ViewPager 的 page 数添加 indicator, 这里先定义好这个方法,等到后看再用。

private void addIndicator(int count) {
    for (int i = 0;  i < count; i++) {
        ImageView img = new ImageView(getContext());
        LayoutParams params = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        params.leftMargin = indicatorSpacing;
        params.rightMargin = indicatorSpacing;
        img.setImageResource(R.drawable.circle_indicator_stroke);
        addView(img, params);
    }

    if (count > 0) {
        ((ImageView) getChildAt(0)).setImageResource(R.drawable.circle_indicator_solid);
    }
}

我希望 CirclePageIndicator 的用法足够简单,简单到只需要一条语句就可以把它附加到 ViewPager 上。

CirclePageIndicator indicator = (CirclePageIndicator) findViewById(R.id.indicator);
indicator.setViewPager(pager);

那么我们就为 CirclePageIndicator 添加 setViewPager 方法。

public void setViewPager(ViewPager pager) {
    userDefinedPageChangeListener = getOnPageChangeListener(pager);
    pager.setOnPageChangeListener(this);
    addIndicator(pager.getAdapter().getCount());
}

为了能监听 ViewPager 中 PageChange 时间,让 CirclePageIndicator 实现了 ViewPager.OnPageChangeListener 这个接口,然后在 setViewPager 的时候,为 ViewPager 添加这个 listener。

但是,这样问题又来了,如果 ViewPager 在传入之前已经有了 listener ,这里很显然会把之前的 listener 给覆盖掉,这个也好办,稍微 hack 一下,用反射把之前的 listener 拿到就可以了。

private ViewPager.OnPageChangeListener getOnPageChangeListener(ViewPager pager) {
    try {
        Field f = pager.getClass().getDeclaredField("mOnPageChangeListener");
        f.setAccessible(true);
        return (ViewPager.OnPageChangeListener) f.get(pager);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return null;
}

剩下的把 ViewPager.OnPageChangeListener 中的方法实现一下,根据 page 的变化更新 indicator 就完成了。

猛戳源码

时间: 2024-08-28 10:28:20

为ViewPager添加一个indicator的相关文章

ViewPager添加小圆点

ViewPager添加小圆点很简单,但是如果是网络图片可能就不太好做了,所以我这里给出一种方法,当然你也可以用其他的 1.主界面xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.a

Android系统中添加一个产品----图文详解

本文本着开源的精神介绍如何向一个Android系统中添加一个产品的整个过程,按照以下过程笔者有理由相信每个将要从事本行业的人都可以完成,其实添加一个产品并不难,难的是对其相关硬件的修改,好了废话不多说. 首先我们要创建一个属于自己产品的目录,这里以WY_device为例,以WY作为产品的名字. 首先从已经存在的产品中拷贝一个以产品的名字为名的.mk文件,修改为自己的.mk文件,在这里为WY.mk 对其进行如下的修改: 然后添加AndroidProducts.mk  这是添加产品的配置文件名路径,

python自动化,自动登录并且添加一个门店

''' 本文主要通过以前公司的对外平台,测试自动登录并且自动添加一个门店 ''' # _*_ coding: utf-8 _*_ from selenium import webdriverimport timedriver = webdriver.Chrome()driver.maximize_window()driver.get("http://121.41.42.104:18888")driver.find_element_by_name("UserName"

一主一从的结构,怎么最小影响添加一个从库,变成一主两从

架构故障 1. 一主一从的结构,怎么最小影响添加一个从库,变成一主两从 场景:分别如下2种 (1)由M--〉S1变为M-->S1-->S2 (2)由M--〉S1变为M-->S1&M-->S2 ip 192.168.0.100 3306 ip 192.168.0.100 3307 ip 192.168.0.100 3308(3308为新添加的从库) (1)由M--〉S1变为M-->S1-->S2 在从库3307上面备份:(主库压力大,不影响业务情况下,在从库330

linux下如何添加一个用户并且让用户获得root权限

转自:http://blog.sina.com.cn/s/blog_6fc583e70100n6rm.html 测试环境:CentOS 5.5 1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #adduser tommy //添加一个名为tommy的用户 #passwd tommy //修改密码 Changing password for user tommy. New UNIX password: //在这里输入新密码 Retype new UNIX password: /

如何在RCP程序中添加一个banner栏

前言:这段时间还算比较空闲,我准备把过去做过的有些形形色色,甚至有些奇怪的研究总结一下,也许刚好有人用的着也不一定,不枉为之抓耳挠腮的时光和浪费的电力.以前有个客户提出要在RCP程序中添加一个banner栏,研究了很久才搞定.代码是基于eclipse4.3.2的. 先看一下效果预览: 为了添加一个banner栏,我们必须重写RCP程序最外层的layout类,即TrimmedPartLayout.java.这个layout类是用来控制menu,toolbar等最基本的layout布局的.我们写一个

WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。

问题如下: “/”应用程序中的服务器错误. WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping.请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息. 异常详细信息: System.InvalidOperationException: WebForm

不能因为为了添加一个新功能,影响到旧的功能

涉及到后台的, 一般都是要跟数据库打交道的大型数据量的处理问题.以类 client - server 为基础的架构, 或者变形后的架构. 客户端处理用户的输入和数据, 然后大量的客户端(多个客户端的多种数据) 反馈到服务端统一处理和协调, 然后服务端对客户端发出相应的指令.其中 后台程序 代表的就是服务端的程序. 包含以下几点:1. 网络通信,  要跟远程的client打交道,只能用网络2. 并发 和 并行处理.0.. 多个客户端可能在同一时间同时需要处理同一个类型的数据, 谁先谁后,谁的有效谁

DHTMLX 前端框架 建立你的一个应用程序教程(三)--添加一个菜单

菜单的介绍 这篇我们介绍将菜单组建添加到上节中的布局中: 我们不对菜单做任何处理  只是在这里填充作为界面的一部分. 这里我们介绍的是dhtmlxMenu 组件. 这个组件的数据我们可以从XML或者JSON中加载 它有两种呈现类型: 1.源图片  它放在imgs文件夹中 2.自定义图片  任何你想使用的位置 添加菜单到布局中: 1.用dhtmlx.image_path 属性来设置源图片的全局路径 dhtmlx.image_path = "codebase/imgs/";dhtmlxEv