Showing preview only (236K chars total). Download the full file or copy to clipboard to get everything.
Repository: JakeWharton/ViewPagerIndicator
Branch: master
Commit: 8cd549f23f3d
Files: 86
Total size: 214.4 KB
Directory structure:
gitextract_2dg_mrm5/
├── .gitignore
├── CHANGELOG.md
├── README.md
├── checkstyle.xml
├── library/
│ ├── AndroidManifest.xml
│ ├── libs/
│ │ └── android-support-v4.jar
│ ├── pom.xml
│ ├── project.properties
│ ├── res/
│ │ ├── color/
│ │ │ ├── vpi__dark_theme.xml
│ │ │ └── vpi__light_theme.xml
│ │ ├── drawable/
│ │ │ └── vpi__tab_indicator.xml
│ │ └── values/
│ │ ├── vpi__attrs.xml
│ │ ├── vpi__colors.xml
│ │ ├── vpi__defaults.xml
│ │ └── vpi__styles.xml
│ └── src/
│ └── com/
│ └── viewpagerindicator/
│ ├── CirclePageIndicator.java
│ ├── IconPageIndicator.java
│ ├── IconPagerAdapter.java
│ ├── IcsLinearLayout.java
│ ├── LinePageIndicator.java
│ ├── PageIndicator.java
│ ├── TabPageIndicator.java
│ ├── TitlePageIndicator.java
│ └── UnderlinePageIndicator.java
├── pom.xml
└── sample/
├── AndroidManifest.xml
├── libs/
│ └── android-support-v4.jar
├── pom.xml
├── project.properties
├── psd/
│ ├── icon_hdpi.psd
│ ├── icon_mdpi.psd
│ ├── icon_xhdpi.psd
│ ├── logo.psd
│ └── web.psd
├── res/
│ ├── drawable/
│ │ ├── custom_tab_indicator.xml
│ │ ├── perm_group_calendar.xml
│ │ ├── perm_group_camera.xml
│ │ ├── perm_group_device_alarms.xml
│ │ └── perm_group_location.xml
│ ├── layout/
│ │ ├── simple_circles.xml
│ │ ├── simple_circles_vertical.xml
│ │ ├── simple_icons.xml
│ │ ├── simple_lines.xml
│ │ ├── simple_tabs.xml
│ │ ├── simple_titles.xml
│ │ ├── simple_titles_bottom.xml
│ │ ├── simple_underlines.xml
│ │ ├── themed_circles.xml
│ │ ├── themed_lines.xml
│ │ ├── themed_titles.xml
│ │ └── themed_underlines.xml
│ ├── menu/
│ │ └── menu.xml
│ └── values/
│ └── styles.xml
└── src/
└── com/
└── viewpagerindicator/
└── sample/
├── BaseSampleActivity.java
├── ListSamples.java
├── SampleCirclesDefault.java
├── SampleCirclesInitialPage.java
├── SampleCirclesSnap.java
├── SampleCirclesStyledLayout.java
├── SampleCirclesStyledMethods.java
├── SampleCirclesStyledTheme.java
├── SampleCirclesWithListener.java
├── SampleIconsDefault.java
├── SampleLinesDefault.java
├── SampleLinesStyledLayout.java
├── SampleLinesStyledMethods.java
├── SampleLinesStyledTheme.java
├── SampleTabsDefault.java
├── SampleTabsStyled.java
├── SampleTabsWithIcons.java
├── SampleTitlesBottom.java
├── SampleTitlesCenterClickListener.java
├── SampleTitlesDefault.java
├── SampleTitlesInitialPage.java
├── SampleTitlesStyledLayout.java
├── SampleTitlesStyledMethods.java
├── SampleTitlesStyledTheme.java
├── SampleTitlesTriangle.java
├── SampleTitlesWithListener.java
├── SampleUnderlinesDefault.java
├── SampleUnderlinesNoFade.java
├── SampleUnderlinesStyledLayout.java
├── SampleUnderlinesStyledMethods.java
├── SampleUnderlinesStyledTheme.java
├── TestFragment.java
└── TestFragmentAdapter.java
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
#Android generated
bin
gen
#Eclipse
.project
.classpath
.settings
#IntelliJ IDEA
.idea
*.iml
classes
#Maven
target
release.properties
pom.xml.*
#Command line
local.properties
build.xml
proguard-project.txt
================================================
FILE: CHANGELOG.md
================================================
Change Log
==========
Version 2.4.1 *(2012-09-11)*
----------------------------
* Fix: `TitlePageIndicator`, `LinePageIndicator`, and `UnderlinePageIndicator`
support of `android:background`.
Version 2.4.0 *(2012-09-06)*
----------------------------
* New `IconPageIndicator`! Uses state-list images to represent pages.
* `TabPageIndicator` now supports icons via `IconPagerAdapter` interface.
* Support `android:background` attribute on `Canvas`-based views.
* Title indicator allows for drawing its line, underline, and/or triangle on
top of the titles for placement underneath a `ViewPager`.
* Tab indicator now supports ICS-style dividers (see styled sample).
* Fix: Do not attempt to change the `ViewPager` page when a motion is
cancelled.
* Fix: Long titles no longer overlap when swiping to the right.
Version 2.3.1 *(2012-05-19)*
----------------------------
* Fix: Corrected filename with erroneous lowercase letter.
Version 2.3.0 *(2012-05-19)*
----------------------------
* New `LinePageIndicator`! Draws small indicators lines much like the circle
indicator but much more subtle.
* New `UnderlinePageIndicator`! Acts like the indicator on the Ice Cream
Sandwich application launcher.
* Circle indicator now uses `android:orientation` rather than custom attribute.
* Title indicator adapter callback now uses the standard `getPageTitle(int)`
method introduced in the r6 version of the support library.
* Title indicator now uses `android:textSize` and `android:textColor` in its
styles.
* Fix: Do not create objects in drawing, layout, or measurement steps of each
indicator.
* Fix: Improve offset detection when page margins are in use on the pager.
* Maven: The dependency on the support library is now using an artifact from
central rather than requiring you to deploy your own locally
Version 2.2.3 *(2012-01-26)*
----------------------------
* Correctly handle removing the last page when it is selected.
* Use antialiased text for the title indicators.
* New circle fill color for circle indicators.
Version 2.2.2 *(2011-12-31)*
----------------------------
* Fix incorrect `R.java` imports in all of the sample activities.
Version 2.2.1 *(2011-12-31)*
----------------------------
* New `setTypeface(Typeface)` and `getTypeface()` methods for title indicator.
(Thanks Dimitri Fedorov)
* Added styled tab indicator sample.
* Support for widths other than those that could be measured exactly.
Version 2.2.0 *(2011-12-13)*
----------------------------
* Default title indicator style is now 'underline'.
* Title indicator now allows specifying an `OnCenterItemClickListener` which
will give you callbacks when the current item title has been clicked.
(Thanks Chris Banes)
Version 2.1.0 *(2011-11-30)*
----------------------------
* Indicators now have a `notifyDataSetChanged` method which should be called
when changes are made to the adapter.
* Fix: Avoid `NullPointerException`s when the `ViewPager` is not immediately
bound to the indicator.
Version 2.0.0 *(2011-11-20)*
----------------------------
* New `TabPageIndicator`! Uses the Ice Cream Sandwich-style action bar tabs
which fill the width of the view when there are only a few tabs or provide
horizontal animated scrolling when there are many.
* Update to link against ACLv4r4. This will now be required in all implementing
applications.
* Allow dragging the title and circle indicators to drag the pager.
* Remove orientation example as the DirectionalViewPager library has not been
updated to ACLv4r4.
Version 1.2.1 *(2011-10-20)*
----------------------------
Maven 3 is now required when building from the command line.
* Update to support ADT 14.
Version 1.2.0 *(2011-10-04)*
----------------------------
* Move to `com.viewpagerindicator` package.
* Move maven group and artifact to `com.viewpagerindicator:library`.
Version 1.1.0 *(2011-10-02)*
----------------------------
* Package changed from `com.jakewharton.android.viewpagerindicator` to
`com.jakewharton.android.view`.
* Add vertical orientation support to the circle indicator.
* Fix: Corrected drawing bug where a single frame would be drawn as if the
pager had completed its scroll when in fact it was still scrolling.
(Thanks SimonVT!)
Version 1.0.1 *(2011-09-15)*
----------------------------
* Fade selected title color to normal text color during the swipe to and from
the center position.
* Fix: Ensure both the indicator and footer line are updated when changing the
footer color via the `setFooterColor` method.
Version 1.0.0 *(2011-08-07)*
----------------------------
Initial release.
================================================
FILE: README.md
================================================
Android ViewPagerIndicator
==========================
Paging indicator widgets that are compatible with the `ViewPager` from the
[Android Support Library][2] to improve discoverability of content.
Try out the sample application [on the Android Market][10].
![ViewPagerIndicator Sample Screenshots][9]
These widgets can also be used in conjunction with [ActionBarSherlock][3]!
Usage
=====
*For a working implementation of this project see the `sample/` folder.*
1. Include one of the widgets in your view. This should usually be placed
adjacent to the `ViewPager` it represents.
<com.viewpagerindicator.TitlePageIndicator
android:id="@+id/titles"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
2. In your `onCreate` method (or `onCreateView` for a fragment), bind the
indicator to the `ViewPager`.
//Set the pager with an adapter
ViewPager pager = (ViewPager)findViewById(R.id.pager);
pager.setAdapter(new TestAdapter(getSupportFragmentManager()));
//Bind the title indicator to the adapter
TitlePageIndicator titleIndicator = (TitlePageIndicator)findViewById(R.id.titles);
titleIndicator.setViewPager(pager);
3. *(Optional)* If you use an `OnPageChangeListener` with your view pager
you should set it in the indicator rather than on the pager directly.
//continued from above
titleIndicator.setOnPageChangeListener(mPageChangeListener);
Theming
-------
There are three ways to style the look of the indicators.
1. **Theme XML**. An attribute for each type of indicator is provided in which
you can specify a custom style.
2. **Layout XML**. Through the use of a custom namespace you can include any
desired styles.
3. **Object methods**. Both styles have getters and setters for each style
attribute which can be changed at any point.
Each indicator has a demo which creates the same look using each of these
methods.
Including In Your Project
-------------------------
Android-ViewPagerIndicator is presented as an [Android library project][7]. A
standalone JAR is not possible due to the theming capabilities offered by the
indicator widgets.
You can include this project by [referencing it as a library project][8] in
Eclipse or ant.
If you are a Maven user you can easily include the library by specifying it as
a dependency:
<dependency>
<groupId>com.viewpagerindicator</groupId>
<artifactId>library</artifactId>
<version>2.4.1</version>
<type>apklib</type>
</dependency>
This project depends on the `ViewPager` class which is available in the
[Android Support Library][2] or [ActionBarSherlock][3]. Details for
including one of those libraries is available on their respecitve web sites.
Developed By
============
* Jake Wharton - <jakewharton@gmail.com>
Credits
-------
* [Patrik Åkerfeldt][1] - Author of [ViewFlow][4], a precursor to the ViewPager,
which supports paged views and is the original source of both the title
and circle indicators.
* [Francisco Figueiredo Jr.][5] - Idea and [first implementation][6] for
fragment support via ViewPager.
License
=======
Copyright 2012 Jake Wharton
Copyright 2011 Patrik Åkerfeldt
Copyright 2011 Francisco Figueiredo Jr.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
[1]: https://github.com/pakerfeldt
[2]: http://developer.android.com/sdk/compatibility-library.html
[3]: http://actionbarsherlock.com
[4]: https://github.com/pakerfeldt/android-viewflow
[5]: https://github.com/franciscojunior
[6]: https://gist.github.com/1122947
[7]: http://developer.android.com/guide/developing/projects/projects-eclipse.html
[8]: http://developer.android.com/guide/developing/projects/projects-eclipse.html#ReferencingLibraryProject
[9]: https://raw.github.com/JakeWharton/Android-ViewPagerIndicator/master/sample/screens.png
[10]: https://play.google.com/store/apps/details?id=com.viewpagerindicator.sample
================================================
FILE: checkstyle.xml
================================================
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
<module name="Checker">
<!--module name="NewlineAtEndOfFile"/-->
<module name="FileLength"/>
<module name="FileTabCharacter"/>
<!-- Trailing spaces -->
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<module name="TreeWalker">
<property name="cacheFile" value="${checkstyle.cache.file}"/>
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<!--module name="JavadocMethod"/-->
<!--module name="JavadocType"/-->
<!--module name="JavadocVariable"/-->
<!--module name="JavadocStyle"/-->
<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<module name="ConstantName"/>
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<!--module name="LineLength"/-->
<!--module name="MethodLength"/-->
<!--module name="ParameterNumber"/-->
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<!--module name="EmptyForIteratorPad"/-->
<!--module name="MethodParamPad"/-->
<!--module name="NoWhitespaceAfter"/-->
<!--module name="NoWhitespaceBefore"/-->
<!--module name="OperatorWrap"/-->
<!--module name="ParenPad"/-->
<!--module name="TypecastParenPad"/-->
<!--module name="WhitespaceAfter"/-->
<!--module name="WhitespaceAround"/-->
<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
<!--module name="ModifierOrder"/-->
<!--module name="RedundantModifier"/-->
<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<!--module name="AvoidNestedBlocks"/-->
<!--module name="EmptyBlock"/-->
<!--module name="LeftCurly"/-->
<!--module name="NeedBraces"/-->
<!--module name="RightCurly"/-->
<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<!--module name="AvoidInlineConditionals"/-->
<!--module name="DoubleCheckedLocking"/--> <!-- MY FAVOURITE -->
<!--module name="EmptyStatement"/-->
<!--module name="EqualsHashCode"/-->
<!--module name="HiddenField"/-->
<!--module name="IllegalInstantiation"/-->
<!--module name="InnerAssignment"/-->
<!--module name="MagicNumber"/-->
<!--module name="MissingSwitchDefault"/-->
<!--module name="RedundantThrows"/-->
<!--module name="SimplifyBooleanExpression"/-->
<!--module name="SimplifyBooleanReturn"/-->
<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<!--module name="DesignForExtension"/-->
<!--module name="FinalClass"/-->
<!--module name="HideUtilityClassConstructor"/-->
<!--module name="InterfaceIsType"/-->
<!--module name="VisibilityModifier"/-->
<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<!--module name="ArrayTypeStyle"/-->
<!--module name="FinalParameters"/-->
<!--module name="TodoComment"/-->
<!--module name="UpperEll"/-->
</module>
</module>
================================================
FILE: library/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.viewpagerindicator"
android:versionCode="65"
android:versionName="2.4.1">
<uses-sdk android:minSdkVersion="4" />
</manifest>
================================================
FILE: library/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>library</artifactId>
<name>Android-ViewPagerIndicator</name>
<packaging>apklib</packaging>
<parent>
<groupId>com.viewpagerindicator</groupId>
<artifactId>parent</artifactId>
<version>2.4.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>support-v4</artifactId>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>../checkstyle.xml</configLocation>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>checkstyle</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
================================================
FILE: library/project.properties
================================================
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
android.library=true
# Project target.
target=android-16
================================================
FILE: library/res/color/vpi__dark_theme.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/vpi__bright_foreground_disabled_holo_dark"/>
<item android:state_window_focused="false" android:color="@color/vpi__bright_foreground_holo_dark"/>
<item android:state_pressed="true" android:color="@color/vpi__bright_foreground_holo_dark"/>
<item android:state_selected="true" android:color="@color/vpi__bright_foreground_holo_dark"/>
<!--item android:state_activated="true" android:color="@color/vpi__bright_foreground_holo_dark"/-->
<item android:color="@color/vpi__bright_foreground_holo_dark"/> <!-- not selected -->
</selector>
================================================
FILE: library/res/color/vpi__light_theme.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/vpi__bright_foreground_disabled_holo_light"/>
<item android:state_window_focused="false" android:color="@color/vpi__bright_foreground_holo_light"/>
<item android:state_pressed="true" android:color="@color/vpi__bright_foreground_holo_light"/>
<item android:state_selected="true" android:color="@color/vpi__bright_foreground_holo_light"/>
<!--item android:state_activated="true" android:color="@color/vpi__bright_foreground_holo_light"/-->
<item android:color="@color/vpi__bright_foreground_holo_light"/> <!-- not selected -->
</selector>
================================================
FILE: library/res/drawable/vpi__tab_indicator.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/vpi__tab_unselected_holo" />
<item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/vpi__tab_selected_holo" />
<!-- Focused states -->
<item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/vpi__tab_unselected_focused_holo" />
<item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/vpi__tab_selected_focused_holo" />
<!-- Pressed -->
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/vpi__tab_unselected_pressed_holo" />
<item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/vpi__tab_selected_pressed_holo" />
<!-- Focused states -->
<item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/vpi__tab_unselected_pressed_holo" />
<item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/vpi__tab_selected_pressed_holo" />
</selector>
================================================
FILE: library/res/values/vpi__attrs.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
Copyright (C) 2011 Patrik Åkerfeldt
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<declare-styleable name="ViewPagerIndicator">
<!-- Style of the circle indicator. -->
<attr name="vpiCirclePageIndicatorStyle" format="reference"/>
<!-- Style of the icon indicator's views. -->
<attr name="vpiIconPageIndicatorStyle" format="reference"/>
<!-- Style of the line indicator. -->
<attr name="vpiLinePageIndicatorStyle" format="reference"/>
<!-- Style of the title indicator. -->
<attr name="vpiTitlePageIndicatorStyle" format="reference"/>
<!-- Style of the tab indicator's tabs. -->
<attr name="vpiTabPageIndicatorStyle" format="reference"/>
<!-- Style of the underline indicator. -->
<attr name="vpiUnderlinePageIndicatorStyle" format="reference"/>
</declare-styleable>
<attr name="centered" format="boolean" />
<attr name="selectedColor" format="color" />
<attr name="strokeWidth" format="dimension" />
<attr name="unselectedColor" format="color" />
<declare-styleable name="CirclePageIndicator">
<!-- Whether or not the indicators should be centered. -->
<attr name="centered" />
<!-- Color of the filled circle that represents the current page. -->
<attr name="fillColor" format="color" />
<!-- Color of the filled circles that represents pages. -->
<attr name="pageColor" format="color" />
<!-- Orientation of the indicator. -->
<attr name="android:orientation"/>
<!-- Radius of the circles. This is also the spacing between circles. -->
<attr name="radius" format="dimension" />
<!-- Whether or not the selected indicator snaps to the circles. -->
<attr name="snap" format="boolean" />
<!-- Color of the open circles. -->
<attr name="strokeColor" format="color" />
<!-- Width of the stroke used to draw the circles. -->
<attr name="strokeWidth" />
<!-- View background -->
<attr name="android:background"/>
</declare-styleable>
<declare-styleable name="LinePageIndicator">
<!-- Whether or not the indicators should be centered. -->
<attr name="centered" />
<!-- Color of the unselected lines that represent the pages. -->
<attr name="unselectedColor" />
<!-- Color of the selected line that represents the current page. -->
<attr name="selectedColor" />
<!-- Width of each indicator line. -->
<attr name="lineWidth" format="dimension" />
<!-- Width of each indicator line's stroke. -->
<attr name="strokeWidth" />
<!-- Width of the gap between each indicator line. -->
<attr name="gapWidth" format="dimension" />
<!-- View background -->
<attr name="android:background"/>
</declare-styleable>
<declare-styleable name="TitlePageIndicator">
<!-- Screen edge padding. -->
<attr name="clipPadding" format="dimension" />
<!-- Color of the footer line and indicator. -->
<attr name="footerColor" format="color" />
<!-- Height of the footer line. -->
<attr name="footerLineHeight" format="dimension" />
<!-- Style of the indicator. Default is triangle. -->
<attr name="footerIndicatorStyle">
<enum name="none" value="0" />
<enum name="triangle" value="1" />
<enum name="underline" value="2" />
</attr>
<!-- Height of the indicator above the footer line. -->
<attr name="footerIndicatorHeight" format="dimension" />
<!-- Left and right padding of the underline indicator. -->
<attr name="footerIndicatorUnderlinePadding" format="dimension" />
<!-- Padding between the bottom of the title and the footer. -->
<attr name="footerPadding" format="dimension" />
<!-- Position of the line. -->
<attr name="linePosition">
<enum name="bottom" value="0"/>
<enum name="top" value="1"/>
</attr>
<!-- Color of the selected title. -->
<attr name="selectedColor" />
<!-- Whether or not the selected item is displayed as bold. -->
<attr name="selectedBold" format="boolean" />
<!-- Color of regular titles. -->
<attr name="android:textColor" />
<!-- Size of title text. -->
<attr name="android:textSize" />
<!-- Padding between titles when bumping into each other. -->
<attr name="titlePadding" format="dimension" />
<!-- Padding between titles and the top of the View. -->
<attr name="topPadding" format="dimension" />
<!-- View background -->
<attr name="android:background"/>
</declare-styleable>
<declare-styleable name="UnderlinePageIndicator">
<!-- Whether or not the selected indicator fades. -->
<attr name="fades" format="boolean" />
<!-- Length of the delay to fade the indicator. -->
<attr name="fadeDelay" format="integer" />
<!-- Length of the indicator fade to transparent. -->
<attr name="fadeLength" format="integer" />
<!-- Color of the selected line that represents the current page. -->
<attr name="selectedColor" />
<!-- View background -->
<attr name="android:background"/>
</declare-styleable>
</resources>
================================================
FILE: library/res/values/vpi__colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<color name="vpi__background_holo_dark">#ff000000</color>
<color name="vpi__background_holo_light">#fff3f3f3</color>
<color name="vpi__bright_foreground_holo_dark">@color/vpi__background_holo_light</color>
<color name="vpi__bright_foreground_holo_light">@color/vpi__background_holo_dark</color>
<color name="vpi__bright_foreground_disabled_holo_dark">#ff4c4c4c</color>
<color name="vpi__bright_foreground_disabled_holo_light">#ffb2b2b2</color>
<color name="vpi__bright_foreground_inverse_holo_dark">@color/vpi__bright_foreground_holo_light</color>
<color name="vpi__bright_foreground_inverse_holo_light">@color/vpi__bright_foreground_holo_dark</color>
</resources>
================================================
FILE: library/res/values/vpi__defaults.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<bool name="default_circle_indicator_centered">true</bool>
<color name="default_circle_indicator_fill_color">#FFFFFFFF</color>
<color name="default_circle_indicator_page_color">#00000000</color>
<integer name="default_circle_indicator_orientation">0</integer>
<dimen name="default_circle_indicator_radius">3dp</dimen>
<bool name="default_circle_indicator_snap">false</bool>
<color name="default_circle_indicator_stroke_color">#FFDDDDDD</color>
<dimen name="default_circle_indicator_stroke_width">1dp</dimen>
<dimen name="default_line_indicator_line_width">12dp</dimen>
<dimen name="default_line_indicator_gap_width">4dp</dimen>
<dimen name="default_line_indicator_stroke_width">1dp</dimen>
<color name="default_line_indicator_selected_color">#FF33B5E5</color>
<color name="default_line_indicator_unselected_color">#FFBBBBBB</color>
<bool name="default_line_indicator_centered">true</bool>
<dimen name="default_title_indicator_clip_padding">4dp</dimen>
<color name="default_title_indicator_footer_color">#FF33B5E5</color>
<dimen name="default_title_indicator_footer_line_height">2dp</dimen>
<integer name="default_title_indicator_footer_indicator_style">2</integer>
<dimen name="default_title_indicator_footer_indicator_height">4dp</dimen>
<dimen name="default_title_indicator_footer_indicator_underline_padding">20dp</dimen>
<dimen name="default_title_indicator_footer_padding">7dp</dimen>
<integer name="default_title_indicator_line_position">0</integer>
<color name="default_title_indicator_selected_color">#FFFFFFFF</color>
<bool name="default_title_indicator_selected_bold">true</bool>
<color name="default_title_indicator_text_color">#BBFFFFFF</color>
<dimen name="default_title_indicator_text_size">15dp</dimen>
<dimen name="default_title_indicator_title_padding">5dp</dimen>
<dimen name="default_title_indicator_top_padding">7dp</dimen>
<bool name="default_underline_indicator_fades">true</bool>
<integer name="default_underline_indicator_fade_delay">300</integer>
<integer name="default_underline_indicator_fade_length">400</integer>
<color name="default_underline_indicator_selected_color">#FF33B5E5</color>
</resources>
================================================
FILE: library/res/values/vpi__styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="Theme.PageIndicatorDefaults" parent="android:Theme">
<item name="vpiIconPageIndicatorStyle">@style/Widget.IconPageIndicator</item>
<item name="vpiTabPageIndicatorStyle">@style/Widget.TabPageIndicator</item>
</style>
<style name="Widget">
</style>
<style name="Widget.TabPageIndicator" parent="Widget">
<item name="android:gravity">center</item>
<item name="android:background">@drawable/vpi__tab_indicator</item>
<item name="android:paddingLeft">22dip</item>
<item name="android:paddingRight">22dip</item>
<item name="android:paddingTop">12dp</item>
<item name="android:paddingBottom">12dp</item>
<item name="android:textAppearance">@style/TextAppearance.TabPageIndicator</item>
<item name="android:textSize">12sp</item>
<item name="android:maxLines">1</item>
</style>
<style name="TextAppearance.TabPageIndicator" parent="Widget">
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/vpi__dark_theme</item>
</style>
<style name="Widget.IconPageIndicator" parent="Widget">
<item name="android:layout_marginLeft">6dp</item>
<item name="android:layout_marginRight">6dp</item>
</style>
</resources>
================================================
FILE: library/src/com/viewpagerindicator/CirclePageIndicator.java
================================================
/*
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.viewpagerindicator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import static android.graphics.Paint.ANTI_ALIAS_FLAG;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
/**
* Draws circles (one for each view). The current view position is filled and
* others are only stroked.
*/
public class CirclePageIndicator extends View implements PageIndicator {
private static final int INVALID_POINTER = -1;
private float mRadius;
private final Paint mPaintPageFill = new Paint(ANTI_ALIAS_FLAG);
private final Paint mPaintStroke = new Paint(ANTI_ALIAS_FLAG);
private final Paint mPaintFill = new Paint(ANTI_ALIAS_FLAG);
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mCurrentPage;
private int mSnapPage;
private float mPageOffset;
private int mScrollState;
private int mOrientation;
private boolean mCentered;
private boolean mSnap;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
public CirclePageIndicator(Context context) {
this(context, null);
}
public CirclePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiCirclePageIndicatorStyle);
}
public CirclePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
//Load defaults from resources
final Resources res = getResources();
final int defaultPageColor = res.getColor(R.color.default_circle_indicator_page_color);
final int defaultFillColor = res.getColor(R.color.default_circle_indicator_fill_color);
final int defaultOrientation = res.getInteger(R.integer.default_circle_indicator_orientation);
final int defaultStrokeColor = res.getColor(R.color.default_circle_indicator_stroke_color);
final float defaultStrokeWidth = res.getDimension(R.dimen.default_circle_indicator_stroke_width);
final float defaultRadius = res.getDimension(R.dimen.default_circle_indicator_radius);
final boolean defaultCentered = res.getBoolean(R.bool.default_circle_indicator_centered);
final boolean defaultSnap = res.getBoolean(R.bool.default_circle_indicator_snap);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CirclePageIndicator, defStyle, 0);
mCentered = a.getBoolean(R.styleable.CirclePageIndicator_centered, defaultCentered);
mOrientation = a.getInt(R.styleable.CirclePageIndicator_android_orientation, defaultOrientation);
mPaintPageFill.setStyle(Style.FILL);
mPaintPageFill.setColor(a.getColor(R.styleable.CirclePageIndicator_pageColor, defaultPageColor));
mPaintStroke.setStyle(Style.STROKE);
mPaintStroke.setColor(a.getColor(R.styleable.CirclePageIndicator_strokeColor, defaultStrokeColor));
mPaintStroke.setStrokeWidth(a.getDimension(R.styleable.CirclePageIndicator_strokeWidth, defaultStrokeWidth));
mPaintFill.setStyle(Style.FILL);
mPaintFill.setColor(a.getColor(R.styleable.CirclePageIndicator_fillColor, defaultFillColor));
mRadius = a.getDimension(R.styleable.CirclePageIndicator_radius, defaultRadius);
mSnap = a.getBoolean(R.styleable.CirclePageIndicator_snap, defaultSnap);
Drawable background = a.getDrawable(R.styleable.CirclePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public void setCentered(boolean centered) {
mCentered = centered;
invalidate();
}
public boolean isCentered() {
return mCentered;
}
public void setPageColor(int pageColor) {
mPaintPageFill.setColor(pageColor);
invalidate();
}
public int getPageColor() {
return mPaintPageFill.getColor();
}
public void setFillColor(int fillColor) {
mPaintFill.setColor(fillColor);
invalidate();
}
public int getFillColor() {
return mPaintFill.getColor();
}
public void setOrientation(int orientation) {
switch (orientation) {
case HORIZONTAL:
case VERTICAL:
mOrientation = orientation;
requestLayout();
break;
default:
throw new IllegalArgumentException("Orientation must be either HORIZONTAL or VERTICAL.");
}
}
public int getOrientation() {
return mOrientation;
}
public void setStrokeColor(int strokeColor) {
mPaintStroke.setColor(strokeColor);
invalidate();
}
public int getStrokeColor() {
return mPaintStroke.getColor();
}
public void setStrokeWidth(float strokeWidth) {
mPaintStroke.setStrokeWidth(strokeWidth);
invalidate();
}
public float getStrokeWidth() {
return mPaintStroke.getStrokeWidth();
}
public void setRadius(float radius) {
mRadius = radius;
invalidate();
}
public float getRadius() {
return mRadius;
}
public void setSnap(boolean snap) {
mSnap = snap;
invalidate();
}
public boolean isSnap() {
return mSnap;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
if (mCurrentPage >= count) {
setCurrentItem(count - 1);
return;
}
int longSize;
int longPaddingBefore;
int longPaddingAfter;
int shortPaddingBefore;
if (mOrientation == HORIZONTAL) {
longSize = getWidth();
longPaddingBefore = getPaddingLeft();
longPaddingAfter = getPaddingRight();
shortPaddingBefore = getPaddingTop();
} else {
longSize = getHeight();
longPaddingBefore = getPaddingTop();
longPaddingAfter = getPaddingBottom();
shortPaddingBefore = getPaddingLeft();
}
final float threeRadius = mRadius * 3;
final float shortOffset = shortPaddingBefore + mRadius;
float longOffset = longPaddingBefore + mRadius;
if (mCentered) {
longOffset += ((longSize - longPaddingBefore - longPaddingAfter) / 2.0f) - ((count * threeRadius) / 2.0f);
}
float dX;
float dY;
float pageFillRadius = mRadius;
if (mPaintStroke.getStrokeWidth() > 0) {
pageFillRadius -= mPaintStroke.getStrokeWidth() / 2.0f;
}
//Draw stroked circles
for (int iLoop = 0; iLoop < count; iLoop++) {
float drawLong = longOffset + (iLoop * threeRadius);
if (mOrientation == HORIZONTAL) {
dX = drawLong;
dY = shortOffset;
} else {
dX = shortOffset;
dY = drawLong;
}
// Only paint fill if not completely transparent
if (mPaintPageFill.getAlpha() > 0) {
canvas.drawCircle(dX, dY, pageFillRadius, mPaintPageFill);
}
// Only paint stroke if a stroke width was non-zero
if (pageFillRadius != mRadius) {
canvas.drawCircle(dX, dY, mRadius, mPaintStroke);
}
}
//Draw the filled circle according to the current scroll
float cx = (mSnap ? mSnapPage : mCurrentPage) * threeRadius;
if (!mSnap) {
cx += mPageOffset * threeRadius;
}
if (mOrientation == HORIZONTAL) {
dX = longOffset + cx;
dY = shortOffset;
} else {
dX = shortOffset;
dY = longOffset + cx;
}
canvas.drawCircle(dX, dY, mRadius, mPaintFill);
}
public boolean onTouchEvent(android.view.MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
if (view.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
mViewPager.setOnPageChangeListener(this);
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPage = position;
mPageOffset = positionOffset;
invalidate();
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mSnap || mScrollState == ViewPager.SCROLL_STATE_IDLE) {
mCurrentPage = position;
mSnapPage = position;
invalidate();
}
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
/*
* (non-Javadoc)
*
* @see android.view.View#onMeasure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mOrientation == HORIZONTAL) {
setMeasuredDimension(measureLong(widthMeasureSpec), measureShort(heightMeasureSpec));
} else {
setMeasuredDimension(measureShort(widthMeasureSpec), measureLong(heightMeasureSpec));
}
}
/**
* Determines the width of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureLong(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if ((specMode == MeasureSpec.EXACTLY) || (mViewPager == null)) {
//We were told how big to be
result = specSize;
} else {
//Calculate the width according the views count
final int count = mViewPager.getAdapter().getCount();
result = (int)(getPaddingLeft() + getPaddingRight()
+ (count * 2 * mRadius) + (count - 1) * mRadius + 1);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
/**
* Determines the height of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureShort(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
//We were told how big to be
result = specSize;
} else {
//Measure the height
result = (int)(2 * mRadius + getPaddingTop() + getPaddingBottom() + 1);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
mSnapPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
================================================
FILE: library/src/com/viewpagerindicator/IconPageIndicator.java
================================================
/*
* Copyright (C) 2011 The Android Open Source Project
* Copyright (C) 2012 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.viewpagerindicator;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import static android.view.ViewGroup.LayoutParams.FILL_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
/**
* This widget implements the dynamic action bar tab behavior that can change
* across different configurations or circumstances.
*/
public class IconPageIndicator extends HorizontalScrollView implements PageIndicator {
private final IcsLinearLayout mIconsLayout;
private ViewPager mViewPager;
private OnPageChangeListener mListener;
private Runnable mIconSelector;
private int mSelectedIndex;
public IconPageIndicator(Context context) {
this(context, null);
}
public IconPageIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
setHorizontalScrollBarEnabled(false);
mIconsLayout = new IcsLinearLayout(context, R.attr.vpiIconPageIndicatorStyle);
addView(mIconsLayout, new LayoutParams(WRAP_CONTENT, FILL_PARENT, Gravity.CENTER));
}
private void animateToIcon(final int position) {
final View iconView = mIconsLayout.getChildAt(position);
if (mIconSelector != null) {
removeCallbacks(mIconSelector);
}
mIconSelector = new Runnable() {
public void run() {
final int scrollPos = iconView.getLeft() - (getWidth() - iconView.getWidth()) / 2;
smoothScrollTo(scrollPos, 0);
mIconSelector = null;
}
};
post(mIconSelector);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (mIconSelector != null) {
// Re-post the selector we saved
post(mIconSelector);
}
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mIconSelector != null) {
removeCallbacks(mIconSelector);
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
if (mListener != null) {
mListener.onPageScrollStateChanged(arg0);
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (mListener != null) {
mListener.onPageScrolled(arg0, arg1, arg2);
}
}
@Override
public void onPageSelected(int arg0) {
setCurrentItem(arg0);
if (mListener != null) {
mListener.onPageSelected(arg0);
}
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
PagerAdapter adapter = view.getAdapter();
if (adapter == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
view.setOnPageChangeListener(this);
notifyDataSetChanged();
}
public void notifyDataSetChanged() {
mIconsLayout.removeAllViews();
IconPagerAdapter iconAdapter = (IconPagerAdapter) mViewPager.getAdapter();
int count = iconAdapter.getCount();
for (int i = 0; i < count; i++) {
ImageView view = new ImageView(getContext(), null, R.attr.vpiIconPageIndicatorStyle);
view.setImageResource(iconAdapter.getIconResId(i));
mIconsLayout.addView(view);
}
if (mSelectedIndex > count) {
mSelectedIndex = count - 1;
}
setCurrentItem(mSelectedIndex);
requestLayout();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mSelectedIndex = item;
mViewPager.setCurrentItem(item);
int tabCount = mIconsLayout.getChildCount();
for (int i = 0; i < tabCount; i++) {
View child = mIconsLayout.getChildAt(i);
boolean isSelected = (i == item);
child.setSelected(isSelected);
if (isSelected) {
animateToIcon(item);
}
}
}
@Override
public void setOnPageChangeListener(OnPageChangeListener listener) {
mListener = listener;
}
}
================================================
FILE: library/src/com/viewpagerindicator/IconPagerAdapter.java
================================================
package com.viewpagerindicator;
public interface IconPagerAdapter {
/**
* Get icon representing the page at {@code index} in the adapter.
*/
int getIconResId(int index);
// From PagerAdapter
int getCount();
}
================================================
FILE: library/src/com/viewpagerindicator/IcsLinearLayout.java
================================================
package com.viewpagerindicator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.LinearLayout;
/**
* A simple extension of a regular linear layout that supports the divider API
* of Android 4.0+. The dividers are added adjacent to the children by changing
* their layout params. If you need to rely on the margins which fall in the
* same orientation as the layout you should wrap the child in a simple
* {@link android.widget.FrameLayout} so it can receive the margin.
*/
class IcsLinearLayout extends LinearLayout {
private static final int[] LL = new int[] {
/* 0 */ android.R.attr.divider,
/* 1 */ android.R.attr.showDividers,
/* 2 */ android.R.attr.dividerPadding,
};
private static final int LL_DIVIDER = 0;
private static final int LL_SHOW_DIVIDER = 1;
private static final int LL_DIVIDER_PADDING = 2;
private Drawable mDivider;
private int mDividerWidth;
private int mDividerHeight;
private int mShowDividers;
private int mDividerPadding;
public IcsLinearLayout(Context context, int themeAttr) {
super(context);
TypedArray a = context.obtainStyledAttributes(null, LL, themeAttr, 0);
setDividerDrawable(a.getDrawable(IcsLinearLayout.LL_DIVIDER));
mDividerPadding = a.getDimensionPixelSize(LL_DIVIDER_PADDING, 0);
mShowDividers = a.getInteger(LL_SHOW_DIVIDER, SHOW_DIVIDER_NONE);
a.recycle();
}
public void setDividerDrawable(Drawable divider) {
if (divider == mDivider) {
return;
}
mDivider = divider;
if (divider != null) {
mDividerWidth = divider.getIntrinsicWidth();
mDividerHeight = divider.getIntrinsicHeight();
} else {
mDividerWidth = 0;
mDividerHeight = 0;
}
setWillNotDraw(divider == null);
requestLayout();
}
@Override
protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
final int index = indexOfChild(child);
final int orientation = getOrientation();
final LayoutParams params = (LayoutParams) child.getLayoutParams();
if (hasDividerBeforeChildAt(index)) {
if (orientation == VERTICAL) {
//Account for the divider by pushing everything up
params.topMargin = mDividerHeight;
} else {
//Account for the divider by pushing everything left
params.leftMargin = mDividerWidth;
}
}
final int count = getChildCount();
if (index == count - 1) {
if (hasDividerBeforeChildAt(count)) {
if (orientation == VERTICAL) {
params.bottomMargin = mDividerHeight;
} else {
params.rightMargin = mDividerWidth;
}
}
}
super.measureChildWithMargins(child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed);
}
@Override
protected void onDraw(Canvas canvas) {
if (mDivider != null) {
if (getOrientation() == VERTICAL) {
drawDividersVertical(canvas);
} else {
drawDividersHorizontal(canvas);
}
}
super.onDraw(canvas);
}
private void drawDividersVertical(Canvas canvas) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
final android.widget.LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) child.getLayoutParams();
final int top = child.getTop() - lp.topMargin/* - mDividerHeight*/;
drawHorizontalDivider(canvas, top);
}
}
}
if (hasDividerBeforeChildAt(count)) {
final View child = getChildAt(count - 1);
int bottom = 0;
if (child == null) {
bottom = getHeight() - getPaddingBottom() - mDividerHeight;
} else {
//final LayoutParams lp = (LayoutParams) child.getLayoutParams();
bottom = child.getBottom()/* + lp.bottomMargin*/;
}
drawHorizontalDivider(canvas, bottom);
}
}
private void drawDividersHorizontal(Canvas canvas) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
final android.widget.LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) child.getLayoutParams();
final int left = child.getLeft() - lp.leftMargin/* - mDividerWidth*/;
drawVerticalDivider(canvas, left);
}
}
}
if (hasDividerBeforeChildAt(count)) {
final View child = getChildAt(count - 1);
int right = 0;
if (child == null) {
right = getWidth() - getPaddingRight() - mDividerWidth;
} else {
//final LayoutParams lp = (LayoutParams) child.getLayoutParams();
right = child.getRight()/* + lp.rightMargin*/;
}
drawVerticalDivider(canvas, right);
}
}
private void drawHorizontalDivider(Canvas canvas, int top) {
mDivider.setBounds(getPaddingLeft() + mDividerPadding, top,
getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight);
mDivider.draw(canvas);
}
private void drawVerticalDivider(Canvas canvas, int left) {
mDivider.setBounds(left, getPaddingTop() + mDividerPadding,
left + mDividerWidth, getHeight() - getPaddingBottom() - mDividerPadding);
mDivider.draw(canvas);
}
private boolean hasDividerBeforeChildAt(int childIndex) {
if (childIndex == 0 || childIndex == getChildCount()) {
return false;
}
if ((mShowDividers & SHOW_DIVIDER_MIDDLE) != 0) {
boolean hasVisibleViewBefore = false;
for (int i = childIndex - 1; i >= 0; i--) {
if (getChildAt(i).getVisibility() != GONE) {
hasVisibleViewBefore = true;
break;
}
}
return hasVisibleViewBefore;
}
return false;
}
}
================================================
FILE: library/src/com/viewpagerindicator/LinePageIndicator.java
================================================
/*
* Copyright (C) 2012 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.viewpagerindicator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
/**
* Draws a line for each page. The current page line is colored differently
* than the unselected page lines.
*/
public class LinePageIndicator extends View implements PageIndicator {
private static final int INVALID_POINTER = -1;
private final Paint mPaintUnselected = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mPaintSelected = new Paint(Paint.ANTI_ALIAS_FLAG);
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mCurrentPage;
private boolean mCentered;
private float mLineWidth;
private float mGapWidth;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
public LinePageIndicator(Context context) {
this(context, null);
}
public LinePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiLinePageIndicatorStyle);
}
public LinePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
final Resources res = getResources();
//Load defaults from resources
final int defaultSelectedColor = res.getColor(R.color.default_line_indicator_selected_color);
final int defaultUnselectedColor = res.getColor(R.color.default_line_indicator_unselected_color);
final float defaultLineWidth = res.getDimension(R.dimen.default_line_indicator_line_width);
final float defaultGapWidth = res.getDimension(R.dimen.default_line_indicator_gap_width);
final float defaultStrokeWidth = res.getDimension(R.dimen.default_line_indicator_stroke_width);
final boolean defaultCentered = res.getBoolean(R.bool.default_line_indicator_centered);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LinePageIndicator, defStyle, 0);
mCentered = a.getBoolean(R.styleable.LinePageIndicator_centered, defaultCentered);
mLineWidth = a.getDimension(R.styleable.LinePageIndicator_lineWidth, defaultLineWidth);
mGapWidth = a.getDimension(R.styleable.LinePageIndicator_gapWidth, defaultGapWidth);
setStrokeWidth(a.getDimension(R.styleable.LinePageIndicator_strokeWidth, defaultStrokeWidth));
mPaintUnselected.setColor(a.getColor(R.styleable.LinePageIndicator_unselectedColor, defaultUnselectedColor));
mPaintSelected.setColor(a.getColor(R.styleable.LinePageIndicator_selectedColor, defaultSelectedColor));
Drawable background = a.getDrawable(R.styleable.LinePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public void setCentered(boolean centered) {
mCentered = centered;
invalidate();
}
public boolean isCentered() {
return mCentered;
}
public void setUnselectedColor(int unselectedColor) {
mPaintUnselected.setColor(unselectedColor);
invalidate();
}
public int getUnselectedColor() {
return mPaintUnselected.getColor();
}
public void setSelectedColor(int selectedColor) {
mPaintSelected.setColor(selectedColor);
invalidate();
}
public int getSelectedColor() {
return mPaintSelected.getColor();
}
public void setLineWidth(float lineWidth) {
mLineWidth = lineWidth;
invalidate();
}
public float getLineWidth() {
return mLineWidth;
}
public void setStrokeWidth(float lineHeight) {
mPaintSelected.setStrokeWidth(lineHeight);
mPaintUnselected.setStrokeWidth(lineHeight);
invalidate();
}
public float getStrokeWidth() {
return mPaintSelected.getStrokeWidth();
}
public void setGapWidth(float gapWidth) {
mGapWidth = gapWidth;
invalidate();
}
public float getGapWidth() {
return mGapWidth;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
if (mCurrentPage >= count) {
setCurrentItem(count - 1);
return;
}
final float lineWidthAndGap = mLineWidth + mGapWidth;
final float indicatorWidth = (count * lineWidthAndGap) - mGapWidth;
final float paddingTop = getPaddingTop();
final float paddingLeft = getPaddingLeft();
final float paddingRight = getPaddingRight();
float verticalOffset = paddingTop + ((getHeight() - paddingTop - getPaddingBottom()) / 2.0f);
float horizontalOffset = paddingLeft;
if (mCentered) {
horizontalOffset += ((getWidth() - paddingLeft - paddingRight) / 2.0f) - (indicatorWidth / 2.0f);
}
//Draw stroked circles
for (int i = 0; i < count; i++) {
float dx1 = horizontalOffset + (i * lineWidthAndGap);
float dx2 = dx1 + mLineWidth;
canvas.drawLine(dx1, verticalOffset, dx2, verticalOffset, (i == mCurrentPage) ? mPaintSelected : mPaintUnselected);
}
}
public boolean onTouchEvent(android.view.MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
@Override
public void setViewPager(ViewPager viewPager) {
if (mViewPager == viewPager) {
return;
}
if (mViewPager != null) {
//Clear us from the old pager.
mViewPager.setOnPageChangeListener(null);
}
if (viewPager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = viewPager;
mViewPager.setOnPageChangeListener(this);
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
mCurrentPage = position;
invalidate();
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
/**
* Determines the width of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureWidth(int measureSpec) {
float result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if ((specMode == MeasureSpec.EXACTLY) || (mViewPager == null)) {
//We were told how big to be
result = specSize;
} else {
//Calculate the width according the views count
final int count = mViewPager.getAdapter().getCount();
result = getPaddingLeft() + getPaddingRight() + (count * mLineWidth) + ((count - 1) * mGapWidth);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return (int)FloatMath.ceil(result);
}
/**
* Determines the height of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureHeight(int measureSpec) {
float result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
//We were told how big to be
result = specSize;
} else {
//Measure the height
result = mPaintSelected.getStrokeWidth() + getPaddingTop() + getPaddingBottom();
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return (int)FloatMath.ceil(result);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
================================================
FILE: library/src/com/viewpagerindicator/PageIndicator.java
================================================
/*
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.viewpagerindicator;
import android.support.v4.view.ViewPager;
/**
* A PageIndicator is responsible to show an visual indicator on the total views
* number and the current visible view.
*/
public interface PageIndicator extends ViewPager.OnPageChangeListener {
/**
* Bind the indicator to a ViewPager.
*
* @param view
*/
void setViewPager(ViewPager view);
/**
* Bind the indicator to a ViewPager.
*
* @param view
* @param initialPosition
*/
void setViewPager(ViewPager view, int initialPosition);
/**
* <p>Set the current page of both the ViewPager and indicator.</p>
*
* <p>This <strong>must</strong> be used if you need to set the page before
* the views are drawn on screen (e.g., default start page).</p>
*
* @param item
*/
void setCurrentItem(int item);
/**
* Set a page change listener which will receive forwarded events.
*
* @param listener
*/
void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
/**
* Notify the indicator that the fragment list has changed.
*/
void notifyDataSetChanged();
}
================================================
FILE: library/src/com/viewpagerindicator/TabPageIndicator.java
================================================
/*
* Copyright (C) 2011 The Android Open Source Project
* Copyright (C) 2011 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.viewpagerindicator;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
/**
* This widget implements the dynamic action bar tab behavior that can change
* across different configurations or circumstances.
*/
public class TabPageIndicator extends HorizontalScrollView implements PageIndicator {
/** Title text used when no title is provided by the adapter. */
private static final CharSequence EMPTY_TITLE = "";
/**
* Interface for a callback when the selected tab has been reselected.
*/
public interface OnTabReselectedListener {
/**
* Callback when the selected tab has been reselected.
*
* @param position Position of the current center item.
*/
void onTabReselected(int position);
}
private Runnable mTabSelector;
private final OnClickListener mTabClickListener = new OnClickListener() {
public void onClick(View view) {
TabView tabView = (TabView)view;
final int oldSelected = mViewPager.getCurrentItem();
final int newSelected = tabView.getIndex();
mViewPager.setCurrentItem(newSelected);
if (oldSelected == newSelected && mTabReselectedListener != null) {
mTabReselectedListener.onTabReselected(newSelected);
}
}
};
private final IcsLinearLayout mTabLayout;
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mMaxTabWidth;
private int mSelectedTabIndex;
private OnTabReselectedListener mTabReselectedListener;
public TabPageIndicator(Context context) {
this(context, null);
}
public TabPageIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
setHorizontalScrollBarEnabled(false);
mTabLayout = new IcsLinearLayout(context, R.attr.vpiTabPageIndicatorStyle);
addView(mTabLayout, new ViewGroup.LayoutParams(WRAP_CONTENT, MATCH_PARENT));
}
public void setOnTabReselectedListener(OnTabReselectedListener listener) {
mTabReselectedListener = listener;
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final boolean lockedExpanded = widthMode == MeasureSpec.EXACTLY;
setFillViewport(lockedExpanded);
final int childCount = mTabLayout.getChildCount();
if (childCount > 1 && (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) {
if (childCount > 2) {
mMaxTabWidth = (int)(MeasureSpec.getSize(widthMeasureSpec) * 0.4f);
} else {
mMaxTabWidth = MeasureSpec.getSize(widthMeasureSpec) / 2;
}
} else {
mMaxTabWidth = -1;
}
final int oldWidth = getMeasuredWidth();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int newWidth = getMeasuredWidth();
if (lockedExpanded && oldWidth != newWidth) {
// Recenter the tab display if we're at a new (scrollable) size.
setCurrentItem(mSelectedTabIndex);
}
}
private void animateToTab(final int position) {
final View tabView = mTabLayout.getChildAt(position);
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
mTabSelector = new Runnable() {
public void run() {
final int scrollPos = tabView.getLeft() - (getWidth() - tabView.getWidth()) / 2;
smoothScrollTo(scrollPos, 0);
mTabSelector = null;
}
};
post(mTabSelector);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (mTabSelector != null) {
// Re-post the selector we saved
post(mTabSelector);
}
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
}
private void addTab(int index, CharSequence text, int iconResId) {
final TabView tabView = new TabView(getContext());
tabView.mIndex = index;
tabView.setFocusable(true);
tabView.setOnClickListener(mTabClickListener);
tabView.setText(text);
if (iconResId != 0) {
tabView.setCompoundDrawablesWithIntrinsicBounds(iconResId, 0, 0, 0);
}
mTabLayout.addView(tabView, new LinearLayout.LayoutParams(0, MATCH_PARENT, 1));
}
@Override
public void onPageScrollStateChanged(int arg0) {
if (mListener != null) {
mListener.onPageScrollStateChanged(arg0);
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (mListener != null) {
mListener.onPageScrolled(arg0, arg1, arg2);
}
}
@Override
public void onPageSelected(int arg0) {
setCurrentItem(arg0);
if (mListener != null) {
mListener.onPageSelected(arg0);
}
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
final PagerAdapter adapter = view.getAdapter();
if (adapter == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
view.setOnPageChangeListener(this);
notifyDataSetChanged();
}
public void notifyDataSetChanged() {
mTabLayout.removeAllViews();
PagerAdapter adapter = mViewPager.getAdapter();
IconPagerAdapter iconAdapter = null;
if (adapter instanceof IconPagerAdapter) {
iconAdapter = (IconPagerAdapter)adapter;
}
final int count = adapter.getCount();
for (int i = 0; i < count; i++) {
CharSequence title = adapter.getPageTitle(i);
if (title == null) {
title = EMPTY_TITLE;
}
int iconResId = 0;
if (iconAdapter != null) {
iconResId = iconAdapter.getIconResId(i);
}
addTab(i, title, iconResId);
}
if (mSelectedTabIndex > count) {
mSelectedTabIndex = count - 1;
}
setCurrentItem(mSelectedTabIndex);
requestLayout();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mSelectedTabIndex = item;
mViewPager.setCurrentItem(item);
final int tabCount = mTabLayout.getChildCount();
for (int i = 0; i < tabCount; i++) {
final View child = mTabLayout.getChildAt(i);
final boolean isSelected = (i == item);
child.setSelected(isSelected);
if (isSelected) {
animateToTab(item);
}
}
}
@Override
public void setOnPageChangeListener(OnPageChangeListener listener) {
mListener = listener;
}
private class TabView extends TextView {
private int mIndex;
public TabView(Context context) {
super(context, null, R.attr.vpiTabPageIndicatorStyle);
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Re-measure if we went beyond our maximum size.
if (mMaxTabWidth > 0 && getMeasuredWidth() > mMaxTabWidth) {
super.onMeasure(MeasureSpec.makeMeasureSpec(mMaxTabWidth, MeasureSpec.EXACTLY),
heightMeasureSpec);
}
}
public int getIndex() {
return mIndex;
}
}
}
================================================
FILE: library/src/com/viewpagerindicator/TitlePageIndicator.java
================================================
/*
* Copyright (C) 2011 Jake Wharton
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Francisco Figueiredo Jr.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.viewpagerindicator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import java.util.ArrayList;
/**
* A TitlePageIndicator is a PageIndicator which displays the title of left view
* (if exist), the title of the current select view (centered) and the title of
* the right view (if exist). When the user scrolls the ViewPager then titles are
* also scrolled.
*/
public class TitlePageIndicator extends View implements PageIndicator {
/**
* Percentage indicating what percentage of the screen width away from
* center should the underline be fully faded. A value of 0.25 means that
* halfway between the center of the screen and an edge.
*/
private static final float SELECTION_FADE_PERCENTAGE = 0.25f;
/**
* Percentage indicating what percentage of the screen width away from
* center should the selected text bold turn off. A value of 0.05 means
* that 10% between the center and an edge.
*/
private static final float BOLD_FADE_PERCENTAGE = 0.05f;
/**
* Title text used when no title is provided by the adapter.
*/
private static final String EMPTY_TITLE = "";
/**
* Interface for a callback when the center item has been clicked.
*/
public interface OnCenterItemClickListener {
/**
* Callback when the center item has been clicked.
*
* @param position Position of the current center item.
*/
void onCenterItemClick(int position);
}
public enum IndicatorStyle {
None(0), Triangle(1), Underline(2);
public final int value;
private IndicatorStyle(int value) {
this.value = value;
}
public static IndicatorStyle fromValue(int value) {
for (IndicatorStyle style : IndicatorStyle.values()) {
if (style.value == value) {
return style;
}
}
return null;
}
}
public enum LinePosition {
Bottom(0), Top(1);
public final int value;
private LinePosition(int value) {
this.value = value;
}
public static LinePosition fromValue(int value) {
for (LinePosition position : LinePosition.values()) {
if (position.value == value) {
return position;
}
}
return null;
}
}
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mCurrentPage = -1;
private float mPageOffset;
private int mScrollState;
private final Paint mPaintText = new Paint();
private boolean mBoldText;
private int mColorText;
private int mColorSelected;
private Path mPath = new Path();
private final Rect mBounds = new Rect();
private final Paint mPaintFooterLine = new Paint();
private IndicatorStyle mFooterIndicatorStyle;
private LinePosition mLinePosition;
private final Paint mPaintFooterIndicator = new Paint();
private float mFooterIndicatorHeight;
private float mFooterIndicatorUnderlinePadding;
private float mFooterPadding;
private float mTitlePadding;
private float mTopPadding;
/** Left and right side padding for not active view titles. */
private float mClipPadding;
private float mFooterLineHeight;
private static final int INVALID_POINTER = -1;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
private OnCenterItemClickListener mCenterItemClickListener;
public TitlePageIndicator(Context context) {
this(context, null);
}
public TitlePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiTitlePageIndicatorStyle);
}
public TitlePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
//Load defaults from resources
final Resources res = getResources();
final int defaultFooterColor = res.getColor(R.color.default_title_indicator_footer_color);
final float defaultFooterLineHeight = res.getDimension(R.dimen.default_title_indicator_footer_line_height);
final int defaultFooterIndicatorStyle = res.getInteger(R.integer.default_title_indicator_footer_indicator_style);
final float defaultFooterIndicatorHeight = res.getDimension(R.dimen.default_title_indicator_footer_indicator_height);
final float defaultFooterIndicatorUnderlinePadding = res.getDimension(R.dimen.default_title_indicator_footer_indicator_underline_padding);
final float defaultFooterPadding = res.getDimension(R.dimen.default_title_indicator_footer_padding);
final int defaultLinePosition = res.getInteger(R.integer.default_title_indicator_line_position);
final int defaultSelectedColor = res.getColor(R.color.default_title_indicator_selected_color);
final boolean defaultSelectedBold = res.getBoolean(R.bool.default_title_indicator_selected_bold);
final int defaultTextColor = res.getColor(R.color.default_title_indicator_text_color);
final float defaultTextSize = res.getDimension(R.dimen.default_title_indicator_text_size);
final float defaultTitlePadding = res.getDimension(R.dimen.default_title_indicator_title_padding);
final float defaultClipPadding = res.getDimension(R.dimen.default_title_indicator_clip_padding);
final float defaultTopPadding = res.getDimension(R.dimen.default_title_indicator_top_padding);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitlePageIndicator, defStyle, 0);
//Retrieve the colors to be used for this view and apply them.
mFooterLineHeight = a.getDimension(R.styleable.TitlePageIndicator_footerLineHeight, defaultFooterLineHeight);
mFooterIndicatorStyle = IndicatorStyle.fromValue(a.getInteger(R.styleable.TitlePageIndicator_footerIndicatorStyle, defaultFooterIndicatorStyle));
mFooterIndicatorHeight = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorHeight, defaultFooterIndicatorHeight);
mFooterIndicatorUnderlinePadding = a.getDimension(R.styleable.TitlePageIndicator_footerIndicatorUnderlinePadding, defaultFooterIndicatorUnderlinePadding);
mFooterPadding = a.getDimension(R.styleable.TitlePageIndicator_footerPadding, defaultFooterPadding);
mLinePosition = LinePosition.fromValue(a.getInteger(R.styleable.TitlePageIndicator_linePosition, defaultLinePosition));
mTopPadding = a.getDimension(R.styleable.TitlePageIndicator_topPadding, defaultTopPadding);
mTitlePadding = a.getDimension(R.styleable.TitlePageIndicator_titlePadding, defaultTitlePadding);
mClipPadding = a.getDimension(R.styleable.TitlePageIndicator_clipPadding, defaultClipPadding);
mColorSelected = a.getColor(R.styleable.TitlePageIndicator_selectedColor, defaultSelectedColor);
mColorText = a.getColor(R.styleable.TitlePageIndicator_android_textColor, defaultTextColor);
mBoldText = a.getBoolean(R.styleable.TitlePageIndicator_selectedBold, defaultSelectedBold);
final float textSize = a.getDimension(R.styleable.TitlePageIndicator_android_textSize, defaultTextSize);
final int footerColor = a.getColor(R.styleable.TitlePageIndicator_footerColor, defaultFooterColor);
mPaintText.setTextSize(textSize);
mPaintText.setAntiAlias(true);
mPaintFooterLine.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintFooterLine.setStrokeWidth(mFooterLineHeight);
mPaintFooterLine.setColor(footerColor);
mPaintFooterIndicator.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintFooterIndicator.setColor(footerColor);
Drawable background = a.getDrawable(R.styleable.TitlePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public int getFooterColor() {
return mPaintFooterLine.getColor();
}
public void setFooterColor(int footerColor) {
mPaintFooterLine.setColor(footerColor);
mPaintFooterIndicator.setColor(footerColor);
invalidate();
}
public float getFooterLineHeight() {
return mFooterLineHeight;
}
public void setFooterLineHeight(float footerLineHeight) {
mFooterLineHeight = footerLineHeight;
mPaintFooterLine.setStrokeWidth(mFooterLineHeight);
invalidate();
}
public float getFooterIndicatorHeight() {
return mFooterIndicatorHeight;
}
public void setFooterIndicatorHeight(float footerTriangleHeight) {
mFooterIndicatorHeight = footerTriangleHeight;
invalidate();
}
public float getFooterIndicatorPadding() {
return mFooterPadding;
}
public void setFooterIndicatorPadding(float footerIndicatorPadding) {
mFooterPadding = footerIndicatorPadding;
invalidate();
}
public IndicatorStyle getFooterIndicatorStyle() {
return mFooterIndicatorStyle;
}
public void setFooterIndicatorStyle(IndicatorStyle indicatorStyle) {
mFooterIndicatorStyle = indicatorStyle;
invalidate();
}
public LinePosition getLinePosition() {
return mLinePosition;
}
public void setLinePosition(LinePosition linePosition) {
mLinePosition = linePosition;
invalidate();
}
public int getSelectedColor() {
return mColorSelected;
}
public void setSelectedColor(int selectedColor) {
mColorSelected = selectedColor;
invalidate();
}
public boolean isSelectedBold() {
return mBoldText;
}
public void setSelectedBold(boolean selectedBold) {
mBoldText = selectedBold;
invalidate();
}
public int getTextColor() {
return mColorText;
}
public void setTextColor(int textColor) {
mPaintText.setColor(textColor);
mColorText = textColor;
invalidate();
}
public float getTextSize() {
return mPaintText.getTextSize();
}
public void setTextSize(float textSize) {
mPaintText.setTextSize(textSize);
invalidate();
}
public float getTitlePadding() {
return this.mTitlePadding;
}
public void setTitlePadding(float titlePadding) {
mTitlePadding = titlePadding;
invalidate();
}
public float getTopPadding() {
return this.mTopPadding;
}
public void setTopPadding(float topPadding) {
mTopPadding = topPadding;
invalidate();
}
public float getClipPadding() {
return this.mClipPadding;
}
public void setClipPadding(float clipPadding) {
mClipPadding = clipPadding;
invalidate();
}
public void setTypeface(Typeface typeface) {
mPaintText.setTypeface(typeface);
invalidate();
}
public Typeface getTypeface() {
return mPaintText.getTypeface();
}
/*
* (non-Javadoc)
*
* @see android.view.View#onDraw(android.graphics.Canvas)
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
// mCurrentPage is -1 on first start and after orientation changed. If so, retrieve the correct index from viewpager.
if (mCurrentPage == -1 && mViewPager != null) {
mCurrentPage = mViewPager.getCurrentItem();
}
//Calculate views bounds
ArrayList<Rect> bounds = calculateAllBounds(mPaintText);
final int boundsSize = bounds.size();
//Make sure we're on a page that still exists
if (mCurrentPage >= boundsSize) {
setCurrentItem(boundsSize - 1);
return;
}
final int countMinusOne = count - 1;
final float halfWidth = getWidth() / 2f;
final int left = getLeft();
final float leftClip = left + mClipPadding;
final int width = getWidth();
int height = getHeight();
final int right = left + width;
final float rightClip = right - mClipPadding;
int page = mCurrentPage;
float offsetPercent;
if (mPageOffset <= 0.5) {
offsetPercent = mPageOffset;
} else {
page += 1;
offsetPercent = 1 - mPageOffset;
}
final boolean currentSelected = (offsetPercent <= SELECTION_FADE_PERCENTAGE);
final boolean currentBold = (offsetPercent <= BOLD_FADE_PERCENTAGE);
final float selectedPercent = (SELECTION_FADE_PERCENTAGE - offsetPercent) / SELECTION_FADE_PERCENTAGE;
//Verify if the current view must be clipped to the screen
Rect curPageBound = bounds.get(mCurrentPage);
float curPageWidth = curPageBound.right - curPageBound.left;
if (curPageBound.left < leftClip) {
//Try to clip to the screen (left side)
clipViewOnTheLeft(curPageBound, curPageWidth, left);
}
if (curPageBound.right > rightClip) {
//Try to clip to the screen (right side)
clipViewOnTheRight(curPageBound, curPageWidth, right);
}
//Left views starting from the current position
if (mCurrentPage > 0) {
for (int i = mCurrentPage - 1; i >= 0; i--) {
Rect bound = bounds.get(i);
//Is left side is outside the screen
if (bound.left < leftClip) {
int w = bound.right - bound.left;
//Try to clip to the screen (left side)
clipViewOnTheLeft(bound, w, left);
//Except if there's an intersection with the right view
Rect rightBound = bounds.get(i + 1);
//Intersection
if (bound.right + mTitlePadding > rightBound.left) {
bound.left = (int) (rightBound.left - w - mTitlePadding);
bound.right = bound.left + w;
}
}
}
}
//Right views starting from the current position
if (mCurrentPage < countMinusOne) {
for (int i = mCurrentPage + 1 ; i < count; i++) {
Rect bound = bounds.get(i);
//If right side is outside the screen
if (bound.right > rightClip) {
int w = bound.right - bound.left;
//Try to clip to the screen (right side)
clipViewOnTheRight(bound, w, right);
//Except if there's an intersection with the left view
Rect leftBound = bounds.get(i - 1);
//Intersection
if (bound.left - mTitlePadding < leftBound.right) {
bound.left = (int) (leftBound.right + mTitlePadding);
bound.right = bound.left + w;
}
}
}
}
//Now draw views
int colorTextAlpha = mColorText >>> 24;
for (int i = 0; i < count; i++) {
//Get the title
Rect bound = bounds.get(i);
//Only if one side is visible
if ((bound.left > left && bound.left < right) || (bound.right > left && bound.right < right)) {
final boolean currentPage = (i == page);
final CharSequence pageTitle = getTitle(i);
//Only set bold if we are within bounds
mPaintText.setFakeBoldText(currentPage && currentBold && mBoldText);
//Draw text as unselected
mPaintText.setColor(mColorText);
if(currentPage && currentSelected) {
//Fade out/in unselected text as the selected text fades in/out
mPaintText.setAlpha(colorTextAlpha - (int)(colorTextAlpha * selectedPercent));
}
//Except if there's an intersection with the right view
if (i < boundsSize - 1) {
Rect rightBound = bounds.get(i + 1);
//Intersection
if (bound.right + mTitlePadding > rightBound.left) {
int w = bound.right - bound.left;
bound.left = (int) (rightBound.left - w - mTitlePadding);
bound.right = bound.left + w;
}
}
canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left, bound.bottom + mTopPadding, mPaintText);
//If we are within the selected bounds draw the selected text
if (currentPage && currentSelected) {
mPaintText.setColor(mColorSelected);
mPaintText.setAlpha((int)((mColorSelected >>> 24) * selectedPercent));
canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left, bound.bottom + mTopPadding, mPaintText);
}
}
}
//If we want the line on the top change height to zero and invert the line height to trick the drawing code
float footerLineHeight = mFooterLineHeight;
float footerIndicatorLineHeight = mFooterIndicatorHeight;
if (mLinePosition == LinePosition.Top) {
height = 0;
footerLineHeight = -footerLineHeight;
footerIndicatorLineHeight = -footerIndicatorLineHeight;
}
//Draw the footer line
mPath.reset();
mPath.moveTo(0, height - footerLineHeight / 2f);
mPath.lineTo(width, height - footerLineHeight / 2f);
mPath.close();
canvas.drawPath(mPath, mPaintFooterLine);
float heightMinusLine = height - footerLineHeight;
switch (mFooterIndicatorStyle) {
case Triangle:
mPath.reset();
mPath.moveTo(halfWidth, heightMinusLine - footerIndicatorLineHeight);
mPath.lineTo(halfWidth + footerIndicatorLineHeight, heightMinusLine);
mPath.lineTo(halfWidth - footerIndicatorLineHeight, heightMinusLine);
mPath.close();
canvas.drawPath(mPath, mPaintFooterIndicator);
break;
case Underline:
if (!currentSelected || page >= boundsSize) {
break;
}
Rect underlineBounds = bounds.get(page);
final float rightPlusPadding = underlineBounds.right + mFooterIndicatorUnderlinePadding;
final float leftMinusPadding = underlineBounds.left - mFooterIndicatorUnderlinePadding;
final float heightMinusLineMinusIndicator = heightMinusLine - footerIndicatorLineHeight;
mPath.reset();
mPath.moveTo(leftMinusPadding, heightMinusLine);
mPath.lineTo(rightPlusPadding, heightMinusLine);
mPath.lineTo(rightPlusPadding, heightMinusLineMinusIndicator);
mPath.lineTo(leftMinusPadding, heightMinusLineMinusIndicator);
mPath.close();
mPaintFooterIndicator.setAlpha((int)(0xFF * selectedPercent));
canvas.drawPath(mPath, mPaintFooterIndicator);
mPaintFooterIndicator.setAlpha(0xFF);
break;
}
}
public boolean onTouchEvent(android.view.MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
final float leftThird = halfWidth - sixthWidth;
final float rightThird = halfWidth + sixthWidth;
final float eventX = ev.getX();
if (eventX < leftThird) {
if (mCurrentPage > 0) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
}
} else if (eventX > rightThird) {
if (mCurrentPage < count - 1) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
} else {
//Middle third
if (mCenterItemClickListener != null && action != MotionEvent.ACTION_CANCEL) {
mCenterItemClickListener.onCenterItemClick(mCurrentPage);
}
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
/**
* Set bounds for the right textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheRight(Rect curViewBound, float curViewWidth, int right) {
curViewBound.right = (int) (right - mClipPadding);
curViewBound.left = (int) (curViewBound.right - curViewWidth);
}
/**
* Set bounds for the left textView including clip padding.
*
* @param curViewBound
* current bounds.
* @param curViewWidth
* width of the view.
*/
private void clipViewOnTheLeft(Rect curViewBound, float curViewWidth, int left) {
curViewBound.left = (int) (left + mClipPadding);
curViewBound.right = (int) (mClipPadding + curViewWidth);
}
/**
* Calculate views bounds and scroll them according to the current index
*
* @param paint
* @return
*/
private ArrayList<Rect> calculateAllBounds(Paint paint) {
ArrayList<Rect> list = new ArrayList<Rect>();
//For each views (If no values then add a fake one)
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final int halfWidth = width / 2;
for (int i = 0; i < count; i++) {
Rect bounds = calcBounds(i, paint);
int w = bounds.right - bounds.left;
int h = bounds.bottom - bounds.top;
bounds.left = (int)(halfWidth - (w / 2f) + ((i - mCurrentPage - mPageOffset) * width));
bounds.right = bounds.left + w;
bounds.top = 0;
bounds.bottom = h;
list.add(bounds);
}
return list;
}
/**
* Calculate the bounds for a view's title
*
* @param index
* @param paint
* @return
*/
private Rect calcBounds(int index, Paint paint) {
//Calculate the text bounds
Rect bounds = new Rect();
CharSequence title = getTitle(index);
bounds.right = (int) paint.measureText(title, 0, title.length());
bounds.bottom = (int) (paint.descent() - paint.ascent());
return bounds;
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
if (view.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
mViewPager.setOnPageChangeListener(this);
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
/**
* Set a callback listener for the center item click.
*
* @param listener Callback instance.
*/
public void setOnCenterItemClickListener(OnCenterItemClickListener listener) {
mCenterItemClickListener = listener;
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPage = position;
mPageOffset = positionOffset;
invalidate();
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
mCurrentPage = position;
invalidate();
}
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//Measure our width in whatever mode specified
final int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
//Determine our height
float height;
final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightSpecMode == MeasureSpec.EXACTLY) {
//We were told how big to be
height = MeasureSpec.getSize(heightMeasureSpec);
} else {
//Calculate the text bounds
mBounds.setEmpty();
mBounds.bottom = (int) (mPaintText.descent() - mPaintText.ascent());
height = mBounds.bottom - mBounds.top + mFooterLineHeight + mFooterPadding + mTopPadding;
if (mFooterIndicatorStyle != IndicatorStyle.None) {
height += mFooterIndicatorHeight;
}
}
final int measuredHeight = (int)height;
setMeasuredDimension(measuredWidth, measuredHeight);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
private CharSequence getTitle(int i) {
CharSequence title = mViewPager.getAdapter().getPageTitle(i);
if (title == null) {
title = EMPTY_TITLE;
}
return title;
}
}
================================================
FILE: library/src/com/viewpagerindicator/UnderlinePageIndicator.java
================================================
/*
* Copyright (C) 2012 Jake Wharton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.viewpagerindicator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
/**
* Draws a line for each page. The current page line is colored differently
* than the unselected page lines.
*/
public class UnderlinePageIndicator extends View implements PageIndicator {
private static final int INVALID_POINTER = -1;
private static final int FADE_FRAME_MS = 30;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private boolean mFades;
private int mFadeDelay;
private int mFadeLength;
private int mFadeBy;
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mScrollState;
private int mCurrentPage;
private float mPositionOffset;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
private final Runnable mFadeRunnable = new Runnable() {
@Override public void run() {
if (!mFades) return;
final int alpha = Math.max(mPaint.getAlpha() - mFadeBy, 0);
mPaint.setAlpha(alpha);
invalidate();
if (alpha > 0) {
postDelayed(this, FADE_FRAME_MS);
}
}
};
public UnderlinePageIndicator(Context context) {
this(context, null);
}
public UnderlinePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiUnderlinePageIndicatorStyle);
}
public UnderlinePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
final Resources res = getResources();
//Load defaults from resources
final boolean defaultFades = res.getBoolean(R.bool.default_underline_indicator_fades);
final int defaultFadeDelay = res.getInteger(R.integer.default_underline_indicator_fade_delay);
final int defaultFadeLength = res.getInteger(R.integer.default_underline_indicator_fade_length);
final int defaultSelectedColor = res.getColor(R.color.default_underline_indicator_selected_color);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UnderlinePageIndicator, defStyle, 0);
setFades(a.getBoolean(R.styleable.UnderlinePageIndicator_fades, defaultFades));
setSelectedColor(a.getColor(R.styleable.UnderlinePageIndicator_selectedColor, defaultSelectedColor));
setFadeDelay(a.getInteger(R.styleable.UnderlinePageIndicator_fadeDelay, defaultFadeDelay));
setFadeLength(a.getInteger(R.styleable.UnderlinePageIndicator_fadeLength, defaultFadeLength));
Drawable background = a.getDrawable(R.styleable.UnderlinePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public boolean getFades() {
return mFades;
}
public void setFades(boolean fades) {
if (fades != mFades) {
mFades = fades;
if (fades) {
post(mFadeRunnable);
} else {
removeCallbacks(mFadeRunnable);
mPaint.setAlpha(0xFF);
invalidate();
}
}
}
public int getFadeDelay() {
return mFadeDelay;
}
public void setFadeDelay(int fadeDelay) {
mFadeDelay = fadeDelay;
}
public int getFadeLength() {
return mFadeLength;
}
public void setFadeLength(int fadeLength) {
mFadeLength = fadeLength;
mFadeBy = 0xFF / (mFadeLength / FADE_FRAME_MS);
}
public int getSelectedColor() {
return mPaint.getColor();
}
public void setSelectedColor(int selectedColor) {
mPaint.setColor(selectedColor);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
if (mCurrentPage >= count) {
setCurrentItem(count - 1);
return;
}
final int paddingLeft = getPaddingLeft();
final float pageWidth = (getWidth() - paddingLeft - getPaddingRight()) / (1f * count);
final float left = paddingLeft + pageWidth * (mCurrentPage + mPositionOffset);
final float right = left + pageWidth;
final float top = getPaddingTop();
final float bottom = getHeight() - getPaddingBottom();
canvas.drawRect(left, top, right, bottom, mPaint);
}
public boolean onTouchEvent(MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
@Override
public void setViewPager(ViewPager viewPager) {
if (mViewPager == viewPager) {
return;
}
if (mViewPager != null) {
//Clear us from the old pager.
mViewPager.setOnPageChangeListener(null);
}
if (viewPager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = viewPager;
mViewPager.setOnPageChangeListener(this);
invalidate();
post(new Runnable() {
@Override public void run() {
if (mFades) {
post(mFadeRunnable);
}
}
});
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPage = position;
mPositionOffset = positionOffset;
if (mFades) {
if (positionOffsetPixels > 0) {
removeCallbacks(mFadeRunnable);
mPaint.setAlpha(0xFF);
} else if (mScrollState != ViewPager.SCROLL_STATE_DRAGGING) {
postDelayed(mFadeRunnable, mFadeDelay);
}
}
invalidate();
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
mCurrentPage = position;
mPositionOffset = 0;
invalidate();
mFadeRunnable.run();
}
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
</parent>
<groupId>com.viewpagerindicator</groupId>
<artifactId>parent</artifactId>
<packaging>pom</packaging>
<version>2.4.1</version>
<name>Android-ViewPagerIndicator (Parent)</name>
<description>Android library for.</description>
<url>https://github.com/JakeWharton/Android-ViewPagerIndicator</url>
<inceptionYear>2011</inceptionYear>
<modules>
<module>library</module>
<module>sample</module>
</modules>
<scm>
<url>http://github.com/JakeWharton/Android-ViewPagerIndicator/</url>
<connection>scm:git:git://github.com/JakeWharton/Android-ViewPagerIndicator.git</connection>
<developerConnection>scm:git:git@github.com:JakeWharton/Android-ViewPagerIndicator.git</developerConnection>
</scm>
<developers>
<developer>
<name>Jake Wharton</name>
<email>jakewharton@gmail.com</email>
<id>jakewharton</id>
<url>http://jakewharton.com</url>
<timezone>-5</timezone>
<roles>
<role>developer</role>
</roles>
</developer>
</developers>
<licenses>
<license>
<name>Apache License Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<organization>
<name>Jake Wharton</name>
<url>http://jakewharton.com</url>
</organization>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/JakeWharton/Android-ViewPagerIndicator/issues</url>
</issueManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.6</java.version>
<android.version>4.1.1.4</android.version>
<android.platform>16</android.platform>
<android.support.version>r7</android.support.version>
<android-maven.version>3.3.0</android-maven.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>${android.version}</version>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>support-v4</artifactId>
<version>${android.support.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>${android-maven.version}</version>
<configuration>
<sdk>
<platform>${android.platform}</platform>
</sdk>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
</configuration>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.6</version>
<configuration>
<failsOnError>true</failsOnError>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.1</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<excludes>
<exclude>android:android</exclude>
<exclude>com.google.android.maps:maps</exclude>
</excludes>
<buildOutputDirectory>bin</buildOutputDirectory>
<classpathContainers>
<classpathContainer>com.android.ide.eclipse.adt.ANDROID_FRAMEWORK</classpathContainer>
</classpathContainers>
<additionalProjectnatures>
<projectnature>com.android.ide.eclipse.adt.AndroidNature</projectnature>
<projectnature>org.eclipse.ajdt.ui.ajnature</projectnature>
</additionalProjectnatures>
<buildcommands>
<buildcommand>com.android.ide.eclipse.adt.ResourceManagerBuilder</buildcommand>
<buildcommand>com.android.ide.eclipse.adt.PreCompilerBuilder</buildcommand>
<buildcommand>org.eclipse.jdt.core.javabuilder</buildcommand>
<buildcommand>com.android.ide.eclipse.adt.ApkBuilder</buildcommand>
</buildcommands>
<useProjectReferences>false</useProjectReferences>
</configuration>
</plugin>
</plugins>
</build>
</project>
================================================
FILE: sample/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.viewpagerindicator.sample"
android:versionCode="65"
android:versionName="2.4.1">
<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="16" />
<application
android:label="ViewPagerIndicator Sample"
android:icon="@drawable/icon">
<activity
android:name=".ListSamples"
android:label="ViewPager Indicator">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- CIRCLE INDICATOR -->
<activity
android:name=".SampleCirclesDefault"
android:label="Circles/Default">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleCirclesInitialPage"
android:label="Circles/Initial Page">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleCirclesSnap"
android:label="Circles/Snap">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleCirclesStyledLayout"
android:label="Circles/Styled (via layout)"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleCirclesStyledMethods"
android:label="Circles/Styled (via methods)"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleCirclesStyledTheme"
android:label="Circles/Styled (via theme)"
android:theme="@style/StyledIndicators">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleCirclesWithListener"
android:label="Circles/With Listener">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<!-- ICON INDICATOR -->
<activity
android:name=".SampleIconsDefault"
android:label="Icons/Default">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<!-- LINE INDICATOR -->
<activity
android:name=".SampleLinesDefault"
android:label="Lines/Default">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleLinesStyledLayout"
android:label="Lines/Styled (via layout)"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleLinesStyledMethods"
android:label="Lines/Styled (via methods)"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleLinesStyledTheme"
android:label="Lines/Styled (via theme)"
android:theme="@style/StyledIndicators">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<!-- TITLE INDICATOR -->
<activity
android:name=".SampleTitlesBottom"
android:label="Titles/Default (Bottom)">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTitlesCenterClickListener"
android:label="Titles/Center Click Listener">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTitlesDefault"
android:label="Titles/Default">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTitlesInitialPage"
android:label="Titles/Initial Page">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTitlesStyledLayout"
android:label="Titles/Styled (via layout)"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTitlesStyledMethods"
android:label="Titles/Styled (via methods)"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTitlesStyledTheme"
android:label="Titles/Styled (via theme)"
android:theme="@style/StyledIndicators">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTitlesTriangle"
android:label="Titles/Triangle Style">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTitlesWithListener"
android:label="Titles/With Listener">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<!-- TAB INDICATOR -->
<activity
android:name=".SampleTabsDefault"
android:label="Tabs/Default"
android:theme="@style/Theme.PageIndicatorDefaults">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTabsStyled"
android:label="Tabs/Styled"
android:theme="@style/StyledIndicators">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleTabsWithIcons"
android:label="Tabs/With Icons"
android:theme="@style/StyledIndicators">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<!-- UNDERLINE INDICATOR -->
<activity
android:name=".SampleUnderlinesDefault"
android:label="Underlines/Default">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleUnderlinesNoFade"
android:label="Underlines/No Fade">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleUnderlinesStyledLayout"
android:label="Underlines/Styled (via layout)"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleUnderlinesStyledMethods"
android:label="Underlines/Styled (via methods)"
android:theme="@android:style/Theme.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
<activity
android:name=".SampleUnderlinesStyledTheme"
android:label="Underlines/Styled (via theme)"
android:theme="@style/StyledIndicators">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.jakewharton.android.viewpagerindicator.sample.SAMPLE" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: sample/pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>sample</artifactId>
<name>Android-ViewPagerIndicator Sample</name>
<packaging>apk</packaging>
<parent>
<groupId>com.viewpagerindicator</groupId>
<artifactId>parent</artifactId>
<version>2.4.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>support-v4</artifactId>
</dependency>
<dependency>
<groupId>com.viewpagerindicator</groupId>
<artifactId>library</artifactId>
<version>${project.version}</version>
<type>apklib</type>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<finalName>${project.artifactId}-unaligned</finalName>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>../checkstyle.xml</configLocation>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>checkstyle</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>${android-maven.version}</version>
<inherited>true</inherited>
<configuration>
<zipalign>
<inputApk>${project.build.directory}/${project.build.finalName}.apk</inputApk>
<outputApk>${project.build.directory}/${project.artifactId}.apk</outputApk>
</zipalign>
</configuration>
<executions>
<execution>
<id>alignApk</id>
<phase>package</phase>
<goals>
<goal>zipalign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
================================================
FILE: sample/project.properties
================================================
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-16
android.library.reference.1=../library
================================================
FILE: sample/res/drawable/custom_tab_indicator.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/custom_tab_indicator_unselected" />
<item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/custom_tab_indicator_selected" />
<!-- Focused states -->
<item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/custom_tab_indicator_unselected_focused" />
<item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/custom_tab_indicator_selected_focused" />
<!-- Pressed -->
<!-- Non focused states -->
<item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/custom_tab_indicator_unselected_pressed" />
<item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/custom_tab_indicator_selected_pressed" />
<!-- Focused states -->
<item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/custom_tab_indicator_unselected_pressed" />
<item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/custom_tab_indicator_selected_pressed" />
</selector>
================================================
FILE: sample/res/drawable/perm_group_calendar.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/perm_group_calendar_selected" />
<item android:drawable="@drawable/perm_group_calendar_normal" />
</selector>
================================================
FILE: sample/res/drawable/perm_group_camera.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/perm_group_camera_selected" />
<item android:drawable="@drawable/perm_group_camera_normal" />
</selector>
================================================
FILE: sample/res/drawable/perm_group_device_alarms.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/perm_group_device_alarms_selected" />
<item android:drawable="@drawable/perm_group_device_alarms_normal" />
</selector>
================================================
FILE: sample/res/drawable/perm_group_location.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/perm_group_location_selected" />
<item android:drawable="@drawable/perm_group_location_normal" />
</selector>
================================================
FILE: sample/res/layout/simple_circles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<com.viewpagerindicator.CirclePageIndicator
android:id="@+id/indicator"
android:padding="10dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/simple_circles_vertical.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.directionalviewpager.DirectionalViewPager
android:id="@+id/pager"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<com.viewpagerindicator.CirclePageIndicator
android:id="@+id/indicator"
android:padding="10dip"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/simple_icons.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<com.viewpagerindicator.IconPageIndicator
android:id="@+id/indicator"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/simple_lines.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<com.viewpagerindicator.LinePageIndicator
android:id="@+id/indicator"
android:padding="5dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/simple_tabs.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.viewpagerindicator.TabPageIndicator
android:id="@+id/indicator"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/simple_titles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.viewpagerindicator.TitlePageIndicator
android:id="@+id/indicator"
android:padding="10dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/simple_titles_bottom.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<com.viewpagerindicator.TitlePageIndicator
android:id="@+id/indicator"
android:padding="10dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
app:linePosition="top"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/simple_underlines.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<com.viewpagerindicator.UnderlinePageIndicator
android:id="@+id/indicator"
android:layout_height="2dp"
android:layout_width="fill_parent"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/themed_circles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<com.viewpagerindicator.CirclePageIndicator
android:id="@+id/indicator"
android:padding="10dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="#FFCCCCCC"
app:radius="10dp"
app:fillColor="#FF888888"
app:pageColor="#88FF0000"
app:strokeColor="#FF000000"
app:strokeWidth="2dp"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/themed_lines.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<com.viewpagerindicator.LinePageIndicator
android:id="@+id/indicator"
android:padding="5dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
app:strokeWidth="4dp"
app:lineWidth="30dp"
app:unselectedColor="#FF888888"
app:selectedColor="#FF880000"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/themed_titles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.viewpagerindicator.TitlePageIndicator
android:id="@+id/indicator"
android:padding="10dip"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="#18FF0000"
android:textColor="#AA000000"
app:footerColor="#FFAA2222"
app:footerLineHeight="1dp"
app:footerIndicatorHeight="3dp"
app:footerIndicatorStyle="underline"
app:selectedColor="#FF000000"
app:selectedBold="true"
/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
</LinearLayout>
================================================
FILE: sample/res/layout/themed_underlines.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<com.viewpagerindicator.UnderlinePageIndicator
android:id="@+id/indicator"
android:layout_height="2dp"
android:layout_width="fill_parent"
android:background="#FFCCCCCC"
app:selectedColor="#FFCC0000"
app:fadeDelay="1000"
app:fadeLength="1000"
/>
</LinearLayout>
================================================
FILE: sample/res/menu/menu.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/random" android:title="Random" />
<item android:id="@+id/add_page" android:title="Add Page" />
<item android:id="@+id/remove_page" android:title="Remove Page" />
</menu>
================================================
FILE: sample/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<style name="StyledIndicators" parent="@android:style/Theme.Light">
<item name="vpiCirclePageIndicatorStyle">@style/CustomCirclePageIndicator</item>
<item name="vpiLinePageIndicatorStyle">@style/CustomLinePageIndicator</item>
<item name="vpiTitlePageIndicatorStyle">@style/CustomTitlePageIndicator</item>
<item name="vpiTabPageIndicatorStyle">@style/CustomTabPageIndicator</item>
<item name="vpiUnderlinePageIndicatorStyle">@style/CustomUnderlinePageIndicator</item>
</style>
<style name="CustomTitlePageIndicator">
<item name="android:background">#18FF0000</item>
<item name="footerColor">#FFAA2222</item>
<item name="footerLineHeight">1dp</item>
<item name="footerIndicatorHeight">3dp</item>
<item name="footerIndicatorStyle">underline</item>
<item name="android:textColor">#AA000000</item>
<item name="selectedColor">#FF000000</item>
<item name="selectedBold">true</item>
</style>
<style name="CustomLinePageIndicator">
<item name="strokeWidth">4dp</item>
<item name="lineWidth">30dp</item>
<item name="unselectedColor">#FF888888</item>
<item name="selectedColor">#FF880000</item>
</style>
<style name="CustomCirclePageIndicator">
<item name="fillColor">#FF888888</item>
<item name="strokeColor">#FF000000</item>
<item name="strokeWidth">2dp</item>
<item name="radius">10dp</item>
<item name="centered">true</item>
</style>
<style name="CustomTabPageIndicator" parent="Widget.TabPageIndicator">
<item name="android:background">@drawable/custom_tab_indicator</item>
<item name="android:textAppearance">@style/CustomTabPageIndicator.Text</item>
<item name="android:textColor">#FF555555</item>
<item name="android:textSize">16sp</item>
<item name="android:divider">@drawable/custom_tab_indicator_divider</item>
<item name="android:dividerPadding">10dp</item>
<item name="android:showDividers">middle</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:fadingEdge">horizontal</item>
<item name="android:fadingEdgeLength">8dp</item>
</style>
<style name="CustomTabPageIndicator.Text" parent="android:TextAppearance.Medium">
<item name="android:typeface">monospace</item>
</style>
<style name="CustomUnderlinePageIndicator">
<item name="selectedColor">#FFCC0000</item>
<item name="android:background">#FFCCCCCC</item>
<item name="fadeLength">1000</item>
<item name="fadeDelay">1000</item>
</style>
</resources>
================================================
FILE: sample/src/com/viewpagerindicator/sample/BaseSampleActivity.java
================================================
package com.viewpagerindicator.sample;
import java.util.Random;
import com.viewpagerindicator.PageIndicator;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public abstract class BaseSampleActivity extends FragmentActivity {
private static final Random RANDOM = new Random();
TestFragmentAdapter mAdapter;
ViewPager mPager;
PageIndicator mIndicator;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.random:
final int page = RANDOM.nextInt(mAdapter.getCount());
Toast.makeText(this, "Changing to page " + page, Toast.LENGTH_SHORT);
mPager.setCurrentItem(page);
return true;
case R.id.add_page:
if (mAdapter.getCount() < 10) {
mAdapter.setCount(mAdapter.getCount() + 1);
mIndicator.notifyDataSetChanged();
}
return true;
case R.id.remove_page:
if (mAdapter.getCount() > 1) {
mAdapter.setCount(mAdapter.getCount() - 1);
mIndicator.notifyDataSetChanged();
}
return true;
}
return super.onOptionsItemSelected(item);
}
}
================================================
FILE: sample/src/com/viewpagerindicator/sample/ListSamples.java
================================================
package com.viewpagerindicator.sample;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.ListActivity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class ListSamples extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String path = intent.getStringExtra("com.jakewharton.android.viewpagerindicator.sample.Path");
if (path == null) {
path = "";
}
setListAdapter(new SimpleAdapter(this, getData(path),
android.R.layout.simple_list_item_1, new String[] { "title" },
new int[] { android.R.id.text1 }));
getListView().setTextFilterEnabled(true);
}
protected List<Map<String, Object>> getData(String prefix) {
List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory("com.jakewharton.android.viewpagerindicator.sample.SAMPLE");
PackageManager pm = getPackageManager();
List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
if (null == list)
return myData;
String[] prefixPath;
String prefixWithSlash = prefix;
if (prefix.equals("")) {
prefixPath = null;
} else {
prefixPath = prefix.split("/");
prefixWithSlash = prefix + "/";
}
int len = list.size();
Map<String, Boolean> entries = new HashMap<String, Boolean>();
for (int i = 0; i < len; i++) {
ResolveInfo info = list.get(i);
CharSequence labelSeq = info.loadLabel(pm);
String label = labelSeq != null
? labelSeq.toString()
: info.activityInfo.name;
if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) {
String[] labelPath = label.split("/");
String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
addItem(myData, nextLabel, activityIntent(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name));
} else {
if (entries.get(nextLabel) == null) {
addItem(myData, nextLabel, browseIntent(prefix.equals("") ? nextLabel : prefix + "/" + nextLabel));
entries.put(nextLabel, true);
}
}
}
}
Collections.sort(myData, NAME_COMPARATOR);
return myData;
}
private final static Comparator<Map<String, Object>> NAME_COMPARATOR =
new Comparator<Map<String, Object>>() {
private final Collator collator = Collator.getInstance();
public int compare(Map<String, Object> map1, Map<String, Object> map2) {
return collator.compare(map1.get("title"), map2.get("title"));
}
};
protected Intent activityIntent(String pkg, String componentName) {
Intent result = new Intent();
result.setClassName(pkg, componentName);
return result;
}
protected Intent browseIntent(String path) {
Intent result = new Intent();
result.setClass(this, ListSamples.class);
result.putExtra("com.jakewharton.android.viewpagerindicator.sample.Path", path);
return result;
}
protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
Map<String, Object> temp = new HashMap<String, Object>();
temp.put("title", name);
temp.put("intent", intent);
data.add(temp);
}
@Override
@SuppressWarnings("unchecked")
protected void onListItemClick(ListView l, View v, int position, long id) {
Map<String, Object> map = (Map<String, Object>)l.getItemAtPosition(position);
Intent intent = (Intent) map.get("intent");
startActivity(intent);
}
}
================================================
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesDefault.java
================================================
package com.viewpagerindicator.sample;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.CirclePageIndicator;
public class SampleCirclesDefault extends BaseSampleActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_circles);
mAdapter = new TestFragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mIndicator = (CirclePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}
}
================================================
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesInitialPage.java
================================================
package com.viewpagerindicator.sample;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.CirclePageIndicator;
public class SampleCirclesInitialPage extends BaseSampleActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_circles);
mAdapter = new TestFragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mIndicator = (CirclePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
mIndicator.setCurrentItem(mAdapter.getCount() - 1);
//You can also do: indicator.setViewPager(pager, initialPage);
}
}
================================================
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesSnap.java
================================================
package com.viewpagerindicator.sample;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.CirclePageIndicator;
public class SampleCirclesSnap extends BaseSampleActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_circles);
mAdapter = new TestFragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
CirclePageIndicator indicator = (CirclePageIndicator)findViewById(R.id.indicator);
mIndicator = indicator;
indicator.setViewPager(mPager);
indicator.setSnap(true);
}
}
================================================
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesStyledLayout.java
================================================
package com.viewpagerindicator.sample;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.CirclePageIndicator;
public class SampleCirclesStyledLayout extends BaseSampleActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.themed_circles);
mAdapter = new TestFragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mIndicator = (CirclePageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
}
}
================================================
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesStyledMethods.java
================================================
package com.viewpagerindicator.sample;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.CirclePageIndicator;
pub
gitextract_2dg_mrm5/
├── .gitignore
├── CHANGELOG.md
├── README.md
├── checkstyle.xml
├── library/
│ ├── AndroidManifest.xml
│ ├── libs/
│ │ └── android-support-v4.jar
│ ├── pom.xml
│ ├── project.properties
│ ├── res/
│ │ ├── color/
│ │ │ ├── vpi__dark_theme.xml
│ │ │ └── vpi__light_theme.xml
│ │ ├── drawable/
│ │ │ └── vpi__tab_indicator.xml
│ │ └── values/
│ │ ├── vpi__attrs.xml
│ │ ├── vpi__colors.xml
│ │ ├── vpi__defaults.xml
│ │ └── vpi__styles.xml
│ └── src/
│ └── com/
│ └── viewpagerindicator/
│ ├── CirclePageIndicator.java
│ ├── IconPageIndicator.java
│ ├── IconPagerAdapter.java
│ ├── IcsLinearLayout.java
│ ├── LinePageIndicator.java
│ ├── PageIndicator.java
│ ├── TabPageIndicator.java
│ ├── TitlePageIndicator.java
│ └── UnderlinePageIndicator.java
├── pom.xml
└── sample/
├── AndroidManifest.xml
├── libs/
│ └── android-support-v4.jar
├── pom.xml
├── project.properties
├── psd/
│ ├── icon_hdpi.psd
│ ├── icon_mdpi.psd
│ ├── icon_xhdpi.psd
│ ├── logo.psd
│ └── web.psd
├── res/
│ ├── drawable/
│ │ ├── custom_tab_indicator.xml
│ │ ├── perm_group_calendar.xml
│ │ ├── perm_group_camera.xml
│ │ ├── perm_group_device_alarms.xml
│ │ └── perm_group_location.xml
│ ├── layout/
│ │ ├── simple_circles.xml
│ │ ├── simple_circles_vertical.xml
│ │ ├── simple_icons.xml
│ │ ├── simple_lines.xml
│ │ ├── simple_tabs.xml
│ │ ├── simple_titles.xml
│ │ ├── simple_titles_bottom.xml
│ │ ├── simple_underlines.xml
│ │ ├── themed_circles.xml
│ │ ├── themed_lines.xml
│ │ ├── themed_titles.xml
│ │ └── themed_underlines.xml
│ ├── menu/
│ │ └── menu.xml
│ └── values/
│ └── styles.xml
└── src/
└── com/
└── viewpagerindicator/
└── sample/
├── BaseSampleActivity.java
├── ListSamples.java
├── SampleCirclesDefault.java
├── SampleCirclesInitialPage.java
├── SampleCirclesSnap.java
├── SampleCirclesStyledLayout.java
├── SampleCirclesStyledMethods.java
├── SampleCirclesStyledTheme.java
├── SampleCirclesWithListener.java
├── SampleIconsDefault.java
├── SampleLinesDefault.java
├── SampleLinesStyledLayout.java
├── SampleLinesStyledMethods.java
├── SampleLinesStyledTheme.java
├── SampleTabsDefault.java
├── SampleTabsStyled.java
├── SampleTabsWithIcons.java
├── SampleTitlesBottom.java
├── SampleTitlesCenterClickListener.java
├── SampleTitlesDefault.java
├── SampleTitlesInitialPage.java
├── SampleTitlesStyledLayout.java
├── SampleTitlesStyledMethods.java
├── SampleTitlesStyledTheme.java
├── SampleTitlesTriangle.java
├── SampleTitlesWithListener.java
├── SampleUnderlinesDefault.java
├── SampleUnderlinesNoFade.java
├── SampleUnderlinesStyledLayout.java
├── SampleUnderlinesStyledMethods.java
├── SampleUnderlinesStyledTheme.java
├── TestFragment.java
└── TestFragmentAdapter.java
SYMBOL INDEX (329 symbols across 42 files)
FILE: library/src/com/viewpagerindicator/CirclePageIndicator.java
class CirclePageIndicator (line 44) | public class CirclePageIndicator extends View implements PageIndicator {
method CirclePageIndicator (line 67) | public CirclePageIndicator(Context context) {
method CirclePageIndicator (line 71) | public CirclePageIndicator(Context context, AttributeSet attrs) {
method CirclePageIndicator (line 75) | public CirclePageIndicator(Context context, AttributeSet attrs, int de...
method setCentered (line 117) | public void setCentered(boolean centered) {
method isCentered (line 122) | public boolean isCentered() {
method setPageColor (line 126) | public void setPageColor(int pageColor) {
method getPageColor (line 131) | public int getPageColor() {
method setFillColor (line 135) | public void setFillColor(int fillColor) {
method getFillColor (line 140) | public int getFillColor() {
method setOrientation (line 144) | public void setOrientation(int orientation) {
method getOrientation (line 157) | public int getOrientation() {
method setStrokeColor (line 161) | public void setStrokeColor(int strokeColor) {
method getStrokeColor (line 166) | public int getStrokeColor() {
method setStrokeWidth (line 170) | public void setStrokeWidth(float strokeWidth) {
method getStrokeWidth (line 175) | public float getStrokeWidth() {
method setRadius (line 179) | public void setRadius(float radius) {
method getRadius (line 184) | public float getRadius() {
method setSnap (line 188) | public void setSnap(boolean snap) {
method isSnap (line 193) | public boolean isSnap() {
method onDraw (line 197) | @Override
method onTouchEvent (line 281) | public boolean onTouchEvent(android.view.MotionEvent ev) {
method setViewPager (line 364) | @Override
method setViewPager (line 380) | @Override
method setCurrentItem (line 386) | @Override
method notifyDataSetChanged (line 396) | @Override
method onPageScrollStateChanged (line 401) | @Override
method onPageScrolled (line 410) | @Override
method onPageSelected (line 421) | @Override
method setOnPageChangeListener (line 434) | @Override
method onMeasure (line 444) | @Override
method measureLong (line 460) | private int measureLong(int measureSpec) {
method measureShort (line 488) | private int measureShort(int measureSpec) {
method onRestoreInstanceState (line 507) | @Override
method onSaveInstanceState (line 516) | @Override
class SavedState (line 524) | static class SavedState extends BaseSavedState {
method SavedState (line 527) | public SavedState(Parcelable superState) {
method SavedState (line 531) | private SavedState(Parcel in) {
method writeToParcel (line 536) | @Override
method createFromParcel (line 544) | @Override
method newArray (line 549) | @Override
FILE: library/src/com/viewpagerindicator/IconPageIndicator.java
class IconPageIndicator (line 36) | public class IconPageIndicator extends HorizontalScrollView implements P...
method IconPageIndicator (line 44) | public IconPageIndicator(Context context) {
method IconPageIndicator (line 48) | public IconPageIndicator(Context context, AttributeSet attrs) {
method animateToIcon (line 56) | private void animateToIcon(final int position) {
method onAttachedToWindow (line 71) | @Override
method onDetachedFromWindow (line 80) | @Override
method onPageScrollStateChanged (line 88) | @Override
method onPageScrolled (line 95) | @Override
method onPageSelected (line 102) | @Override
method setViewPager (line 110) | @Override
method notifyDataSetChanged (line 127) | public void notifyDataSetChanged() {
method setViewPager (line 143) | @Override
method setCurrentItem (line 149) | @Override
method setOnPageChangeListener (line 168) | @Override
FILE: library/src/com/viewpagerindicator/IconPagerAdapter.java
type IconPagerAdapter (line 3) | public interface IconPagerAdapter {
method getIconResId (line 7) | int getIconResId(int index);
method getCount (line 10) | int getCount();
FILE: library/src/com/viewpagerindicator/IcsLinearLayout.java
class IcsLinearLayout (line 17) | class IcsLinearLayout extends LinearLayout {
method IcsLinearLayout (line 34) | public IcsLinearLayout(Context context, int themeAttr) {
method setDividerDrawable (line 44) | public void setDividerDrawable(Drawable divider) {
method measureChildWithMargins (line 60) | @Override
method onDraw (line 88) | @Override
method drawDividersVertical (line 100) | private void drawDividersVertical(Canvas canvas) {
method drawDividersHorizontal (line 127) | private void drawDividersHorizontal(Canvas canvas) {
method drawHorizontalDivider (line 154) | private void drawHorizontalDivider(Canvas canvas, int top) {
method drawVerticalDivider (line 160) | private void drawVerticalDivider(Canvas canvas, int left) {
method hasDividerBeforeChildAt (line 166) | private boolean hasDividerBeforeChildAt(int childIndex) {
FILE: library/src/com/viewpagerindicator/LinePageIndicator.java
class LinePageIndicator (line 39) | public class LinePageIndicator extends View implements PageIndicator {
method LinePageIndicator (line 57) | public LinePageIndicator(Context context) {
method LinePageIndicator (line 61) | public LinePageIndicator(Context context, AttributeSet attrs) {
method LinePageIndicator (line 65) | public LinePageIndicator(Context context, AttributeSet attrs, int defS...
method setCentered (line 101) | public void setCentered(boolean centered) {
method isCentered (line 106) | public boolean isCentered() {
method setUnselectedColor (line 110) | public void setUnselectedColor(int unselectedColor) {
method getUnselectedColor (line 115) | public int getUnselectedColor() {
method setSelectedColor (line 119) | public void setSelectedColor(int selectedColor) {
method getSelectedColor (line 124) | public int getSelectedColor() {
method setLineWidth (line 128) | public void setLineWidth(float lineWidth) {
method getLineWidth (line 133) | public float getLineWidth() {
method setStrokeWidth (line 137) | public void setStrokeWidth(float lineHeight) {
method getStrokeWidth (line 143) | public float getStrokeWidth() {
method setGapWidth (line 147) | public void setGapWidth(float gapWidth) {
method getGapWidth (line 152) | public float getGapWidth() {
method onDraw (line 156) | @Override
method onTouchEvent (line 193) | public boolean onTouchEvent(android.view.MotionEvent ev) {
method setViewPager (line 276) | @Override
method setViewPager (line 293) | @Override
method setCurrentItem (line 299) | @Override
method notifyDataSetChanged (line 309) | @Override
method onPageScrollStateChanged (line 314) | @Override
method onPageScrolled (line 321) | @Override
method onPageSelected (line 328) | @Override
method setOnPageChangeListener (line 338) | @Override
method onMeasure (line 343) | @Override
method measureWidth (line 355) | private int measureWidth(int measureSpec) {
method measureHeight (line 382) | private int measureHeight(int measureSpec) {
method onRestoreInstanceState (line 401) | @Override
method onSaveInstanceState (line 409) | @Override
class SavedState (line 417) | static class SavedState extends BaseSavedState {
method SavedState (line 420) | public SavedState(Parcelable superState) {
method SavedState (line 424) | private SavedState(Parcel in) {
method writeToParcel (line 429) | @Override
method createFromParcel (line 437) | @Override
method newArray (line 442) | @Override
FILE: library/src/com/viewpagerindicator/PageIndicator.java
type PageIndicator (line 26) | public interface PageIndicator extends ViewPager.OnPageChangeListener {
method setViewPager (line 32) | void setViewPager(ViewPager view);
method setViewPager (line 40) | void setViewPager(ViewPager view, int initialPosition);
method setCurrentItem (line 50) | void setCurrentItem(int item);
method setOnPageChangeListener (line 57) | void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
method notifyDataSetChanged (line 62) | void notifyDataSetChanged();
FILE: library/src/com/viewpagerindicator/TabPageIndicator.java
class TabPageIndicator (line 37) | public class TabPageIndicator extends HorizontalScrollView implements Pa...
type OnTabReselectedListener (line 44) | public interface OnTabReselectedListener {
method onTabReselected (line 50) | void onTabReselected(int position);
method onClick (line 56) | public void onClick(View view) {
method TabPageIndicator (line 77) | public TabPageIndicator(Context context) {
method TabPageIndicator (line 81) | public TabPageIndicator(Context context, AttributeSet attrs) {
method setOnTabReselectedListener (line 89) | public void setOnTabReselectedListener(OnTabReselectedListener listene...
method onMeasure (line 93) | @Override
method animateToTab (line 120) | private void animateToTab(final int position) {
method onAttachedToWindow (line 135) | @Override
method onDetachedFromWindow (line 144) | @Override
method addTab (line 152) | private void addTab(int index, CharSequence text, int iconResId) {
method onPageScrollStateChanged (line 166) | @Override
method onPageScrolled (line 173) | @Override
method onPageSelected (line 180) | @Override
method setViewPager (line 188) | @Override
method notifyDataSetChanged (line 205) | public void notifyDataSetChanged() {
method setViewPager (line 231) | @Override
method setCurrentItem (line 237) | @Override
method setOnPageChangeListener (line 256) | @Override
class TabView (line 261) | private class TabView extends TextView {
method TabView (line 264) | public TabView(Context context) {
method onMeasure (line 268) | @Override
method getIndex (line 279) | public int getIndex() {
FILE: library/src/com/viewpagerindicator/TitlePageIndicator.java
class TitlePageIndicator (line 47) | public class TitlePageIndicator extends View implements PageIndicator {
type OnCenterItemClickListener (line 70) | public interface OnCenterItemClickListener {
method onCenterItemClick (line 76) | void onCenterItemClick(int position);
type IndicatorStyle (line 79) | public enum IndicatorStyle {
method IndicatorStyle (line 84) | private IndicatorStyle(int value) {
method fromValue (line 88) | public static IndicatorStyle fromValue(int value) {
type LinePosition (line 98) | public enum LinePosition {
method LinePosition (line 103) | private LinePosition(int value) {
method fromValue (line 107) | public static LinePosition fromValue(int value) {
method TitlePageIndicator (line 151) | public TitlePageIndicator(Context context) {
method TitlePageIndicator (line 155) | public TitlePageIndicator(Context context, AttributeSet attrs) {
method TitlePageIndicator (line 159) | public TitlePageIndicator(Context context, AttributeSet attrs, int def...
method getFooterColor (line 219) | public int getFooterColor() {
method setFooterColor (line 223) | public void setFooterColor(int footerColor) {
method getFooterLineHeight (line 229) | public float getFooterLineHeight() {
method setFooterLineHeight (line 233) | public void setFooterLineHeight(float footerLineHeight) {
method getFooterIndicatorHeight (line 239) | public float getFooterIndicatorHeight() {
method setFooterIndicatorHeight (line 243) | public void setFooterIndicatorHeight(float footerTriangleHeight) {
method getFooterIndicatorPadding (line 248) | public float getFooterIndicatorPadding() {
method setFooterIndicatorPadding (line 252) | public void setFooterIndicatorPadding(float footerIndicatorPadding) {
method getFooterIndicatorStyle (line 257) | public IndicatorStyle getFooterIndicatorStyle() {
method setFooterIndicatorStyle (line 261) | public void setFooterIndicatorStyle(IndicatorStyle indicatorStyle) {
method getLinePosition (line 266) | public LinePosition getLinePosition() {
method setLinePosition (line 270) | public void setLinePosition(LinePosition linePosition) {
method getSelectedColor (line 275) | public int getSelectedColor() {
method setSelectedColor (line 279) | public void setSelectedColor(int selectedColor) {
method isSelectedBold (line 284) | public boolean isSelectedBold() {
method setSelectedBold (line 288) | public void setSelectedBold(boolean selectedBold) {
method getTextColor (line 293) | public int getTextColor() {
method setTextColor (line 297) | public void setTextColor(int textColor) {
method getTextSize (line 303) | public float getTextSize() {
method setTextSize (line 307) | public void setTextSize(float textSize) {
method getTitlePadding (line 312) | public float getTitlePadding() {
method setTitlePadding (line 316) | public void setTitlePadding(float titlePadding) {
method getTopPadding (line 321) | public float getTopPadding() {
method setTopPadding (line 325) | public void setTopPadding(float topPadding) {
method getClipPadding (line 330) | public float getClipPadding() {
method setClipPadding (line 334) | public void setClipPadding(float clipPadding) {
method setTypeface (line 339) | public void setTypeface(Typeface typeface) {
method getTypeface (line 344) | public Typeface getTypeface() {
method onDraw (line 353) | @Override
method onTouchEvent (line 544) | public boolean onTouchEvent(android.view.MotionEvent ev) {
method clipViewOnTheRight (line 647) | private void clipViewOnTheRight(Rect curViewBound, float curViewWidth,...
method clipViewOnTheLeft (line 660) | private void clipViewOnTheLeft(Rect curViewBound, float curViewWidth, ...
method calculateAllBounds (line 671) | private ArrayList<Rect> calculateAllBounds(Paint paint) {
method calcBounds (line 698) | private Rect calcBounds(int index, Paint paint) {
method setViewPager (line 707) | @Override
method setViewPager (line 723) | @Override
method notifyDataSetChanged (line 729) | @Override
method setOnCenterItemClickListener (line 739) | public void setOnCenterItemClickListener(OnCenterItemClickListener lis...
method setCurrentItem (line 743) | @Override
method onPageScrollStateChanged (line 753) | @Override
method onPageScrolled (line 762) | @Override
method onPageSelected (line 773) | @Override
method setOnPageChangeListener (line 785) | @Override
method onMeasure (line 790) | @Override
method onRestoreInstanceState (line 815) | @Override
method onSaveInstanceState (line 823) | @Override
class SavedState (line 831) | static class SavedState extends BaseSavedState {
method SavedState (line 834) | public SavedState(Parcelable superState) {
method SavedState (line 838) | private SavedState(Parcel in) {
method writeToParcel (line 843) | @Override
method createFromParcel (line 851) | @Override
method newArray (line 856) | @Override
method getTitle (line 863) | private CharSequence getTitle(int i) {
FILE: library/src/com/viewpagerindicator/UnderlinePageIndicator.java
class UnderlinePageIndicator (line 38) | public class UnderlinePageIndicator extends View implements PageIndicator {
method run (line 61) | @Override public void run() {
method UnderlinePageIndicator (line 73) | public UnderlinePageIndicator(Context context) {
method UnderlinePageIndicator (line 77) | public UnderlinePageIndicator(Context context, AttributeSet attrs) {
method UnderlinePageIndicator (line 81) | public UnderlinePageIndicator(Context context, AttributeSet attrs, int...
method getFades (line 112) | public boolean getFades() {
method setFades (line 116) | public void setFades(boolean fades) {
method getFadeDelay (line 129) | public int getFadeDelay() {
method setFadeDelay (line 133) | public void setFadeDelay(int fadeDelay) {
method getFadeLength (line 137) | public int getFadeLength() {
method setFadeLength (line 141) | public void setFadeLength(int fadeLength) {
method getSelectedColor (line 146) | public int getSelectedColor() {
method setSelectedColor (line 150) | public void setSelectedColor(int selectedColor) {
method onDraw (line 155) | @Override
method onTouchEvent (line 181) | public boolean onTouchEvent(MotionEvent ev) {
method setViewPager (line 264) | @Override
method setViewPager (line 288) | @Override
method setCurrentItem (line 294) | @Override
method notifyDataSetChanged (line 304) | @Override
method onPageScrollStateChanged (line 309) | @Override
method onPageScrolled (line 318) | @Override
method onPageSelected (line 337) | @Override
method setOnPageChangeListener (line 350) | @Override
method onRestoreInstanceState (line 355) | @Override
method onSaveInstanceState (line 363) | @Override
class SavedState (line 371) | static class SavedState extends BaseSavedState {
method SavedState (line 374) | public SavedState(Parcelable superState) {
method SavedState (line 378) | private SavedState(Parcel in) {
method writeToParcel (line 383) | @Override
method createFromParcel (line 391) | @Override
method newArray (line 396) | @Override
FILE: sample/src/com/viewpagerindicator/sample/BaseSampleActivity.java
class BaseSampleActivity (line 13) | public abstract class BaseSampleActivity extends FragmentActivity {
method onCreateOptionsMenu (line 20) | @Override
method onOptionsItemSelected (line 26) | @Override
FILE: sample/src/com/viewpagerindicator/sample/ListSamples.java
class ListSamples (line 19) | public class ListSamples extends ListActivity {
method onCreate (line 21) | @Override
method getData (line 38) | protected List<Map<String, Object>> getData(String prefix) {
method compare (line 99) | public int compare(Map<String, Object> map1, Map<String, Object> map2) {
method activityIntent (line 104) | protected Intent activityIntent(String pkg, String componentName) {
method browseIntent (line 110) | protected Intent browseIntent(String path) {
method addItem (line 117) | protected void addItem(List<Map<String, Object>> data, String name, In...
method onListItemClick (line 124) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesDefault.java
class SampleCirclesDefault (line 7) | public class SampleCirclesDefault extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesInitialPage.java
class SampleCirclesInitialPage (line 7) | public class SampleCirclesInitialPage extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesSnap.java
class SampleCirclesSnap (line 7) | public class SampleCirclesSnap extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesStyledLayout.java
class SampleCirclesStyledLayout (line 7) | public class SampleCirclesStyledLayout extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesStyledMethods.java
class SampleCirclesStyledMethods (line 7) | public class SampleCirclesStyledMethods extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesStyledTheme.java
class SampleCirclesStyledTheme (line 7) | public class SampleCirclesStyledTheme extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleCirclesWithListener.java
class SampleCirclesWithListener (line 8) | public class SampleCirclesWithListener extends BaseSampleActivity {
method onCreate (line 9) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleIconsDefault.java
class SampleIconsDefault (line 7) | public class SampleIconsDefault extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleLinesDefault.java
class SampleLinesDefault (line 7) | public class SampleLinesDefault extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleLinesStyledLayout.java
class SampleLinesStyledLayout (line 7) | public class SampleLinesStyledLayout extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleLinesStyledMethods.java
class SampleLinesStyledMethods (line 7) | public class SampleLinesStyledMethods extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleLinesStyledTheme.java
class SampleLinesStyledTheme (line 7) | public class SampleLinesStyledTheme extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTabsDefault.java
class SampleTabsDefault (line 11) | public class SampleTabsDefault extends FragmentActivity {
method onCreate (line 14) | @Override
class GoogleMusicAdapter (line 28) | class GoogleMusicAdapter extends FragmentPagerAdapter {
method GoogleMusicAdapter (line 29) | public GoogleMusicAdapter(FragmentManager fm) {
method getItem (line 33) | @Override
method getPageTitle (line 38) | @Override
method getCount (line 43) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTabsStyled.java
class SampleTabsStyled (line 11) | public class SampleTabsStyled extends FragmentActivity {
method onCreate (line 14) | @Override
class GoogleMusicAdapter (line 28) | class GoogleMusicAdapter extends FragmentPagerAdapter {
method GoogleMusicAdapter (line 29) | public GoogleMusicAdapter(FragmentManager fm) {
method getItem (line 33) | @Override
method getPageTitle (line 38) | @Override
method getCount (line 43) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTabsWithIcons.java
class SampleTabsWithIcons (line 12) | public class SampleTabsWithIcons extends FragmentActivity {
method onCreate (line 21) | @Override
class GoogleMusicAdapter (line 35) | class GoogleMusicAdapter extends FragmentPagerAdapter implements IconP...
method GoogleMusicAdapter (line 36) | public GoogleMusicAdapter(FragmentManager fm) {
method getItem (line 40) | @Override
method getPageTitle (line 45) | @Override
method getIconResId (line 50) | @Override public int getIconResId(int index) {
method getCount (line 54) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTitlesBottom.java
class SampleTitlesBottom (line 7) | public class SampleTitlesBottom extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTitlesCenterClickListener.java
class SampleTitlesCenterClickListener (line 11) | public class SampleTitlesCenterClickListener extends BaseSampleActivity ...
method onCreate (line 12) | @Override
method onCenterItemClick (line 29) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTitlesDefault.java
class SampleTitlesDefault (line 8) | public class SampleTitlesDefault extends BaseSampleActivity {
method onCreate (line 9) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTitlesInitialPage.java
class SampleTitlesInitialPage (line 8) | public class SampleTitlesInitialPage extends BaseSampleActivity {
method onCreate (line 9) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTitlesStyledLayout.java
class SampleTitlesStyledLayout (line 8) | public class SampleTitlesStyledLayout extends BaseSampleActivity {
method onCreate (line 9) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTitlesStyledMethods.java
class SampleTitlesStyledMethods (line 9) | public class SampleTitlesStyledMethods extends BaseSampleActivity {
method onCreate (line 10) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTitlesStyledTheme.java
class SampleTitlesStyledTheme (line 8) | public class SampleTitlesStyledTheme extends BaseSampleActivity {
method onCreate (line 9) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTitlesTriangle.java
class SampleTitlesTriangle (line 9) | public class SampleTitlesTriangle extends BaseSampleActivity {
method onCreate (line 10) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleTitlesWithListener.java
class SampleTitlesWithListener (line 9) | public class SampleTitlesWithListener extends BaseSampleActivity {
method onCreate (line 10) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleUnderlinesDefault.java
class SampleUnderlinesDefault (line 7) | public class SampleUnderlinesDefault extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleUnderlinesNoFade.java
class SampleUnderlinesNoFade (line 7) | public class SampleUnderlinesNoFade extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleUnderlinesStyledLayout.java
class SampleUnderlinesStyledLayout (line 7) | public class SampleUnderlinesStyledLayout extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleUnderlinesStyledMethods.java
class SampleUnderlinesStyledMethods (line 7) | public class SampleUnderlinesStyledMethods extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/SampleUnderlinesStyledTheme.java
class SampleUnderlinesStyledTheme (line 7) | public class SampleUnderlinesStyledTheme extends BaseSampleActivity {
method onCreate (line 8) | @Override
FILE: sample/src/com/viewpagerindicator/sample/TestFragment.java
class TestFragment (line 13) | public final class TestFragment extends Fragment {
method newInstance (line 16) | public static TestFragment newInstance(String content) {
method onCreate (line 31) | @Override
method onCreateView (line 40) | @Override
method onSaveInstanceState (line 56) | @Override
FILE: sample/src/com/viewpagerindicator/sample/TestFragmentAdapter.java
class TestFragmentAdapter (line 8) | class TestFragmentAdapter extends FragmentPagerAdapter implements IconPa...
method TestFragmentAdapter (line 19) | public TestFragmentAdapter(FragmentManager fm) {
method getItem (line 23) | @Override
method getCount (line 28) | @Override
method getPageTitle (line 33) | @Override
method getIconResId (line 38) | @Override
method setCount (line 43) | public void setCount(int count) {
Condensed preview — 86 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (234K chars).
[
{
"path": ".gitignore",
"chars": 210,
"preview": "#Android generated\nbin\ngen\n\n#Eclipse\n.project\n.classpath\n.settings\n\n#IntelliJ IDEA\n.idea\n*.iml\nclasses\n\n#Maven\ntarget\nre"
},
{
"path": "CHANGELOG.md",
"chars": 4694,
"preview": "Change Log\n==========\n\nVersion 2.4.1 *(2012-09-11)*\n----------------------------\n\n * Fix: `TitlePageIndicator`, `LinePag"
},
{
"path": "README.md",
"chars": 4554,
"preview": "Android ViewPagerIndicator\n==========================\n\nPaging indicator widgets that are compatible with the `ViewPager`"
},
{
"path": "checkstyle.xml",
"chars": 4660,
"preview": "<?xml version=\"1.0\"?>\r\n<!DOCTYPE module PUBLIC\r\n \"-//Puppy Crawl//DTD Check Configuration 1.2//EN\"\r\n \"http://www.p"
},
{
"path": "library/AndroidManifest.xml",
"chars": 264,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package"
},
{
"path": "library/pom.xml",
"chars": 1493,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/"
},
{
"path": "library/project.properties",
"chars": 382,
"preview": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# T"
},
{
"path": "library/res/color/vpi__dark_theme.xml",
"chars": 1358,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2010 The Android Open Source Project\n\n Licensed under the "
},
{
"path": "library/res/color/vpi__light_theme.xml",
"chars": 1370,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2010 The Android Open Source Project\n\n Licensed under the "
},
{
"path": "library/res/drawable/vpi__tab_indicator.xml",
"chars": 2203,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2008 The Android Open Source Project\n\n Licensed under the "
},
{
"path": "library/res/values/vpi__attrs.xml",
"chars": 6039,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2012 Jake Wharton\n Copyright (C) 2011 Patrik Åkerfeldt\n\n "
},
{
"path": "library/res/values/vpi__colors.xml",
"chars": 1361,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2012 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "library/res/values/vpi__defaults.xml",
"chars": 2924,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2012 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "library/res/values/vpi__styles.xml",
"chars": 1965,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "library/src/com/viewpagerindicator/CirclePageIndicator.java",
"chars": 18830,
"preview": "/*\n * Copyright (C) 2011 Patrik Akerfeldt\n * Copyright (C) 2011 Jake Wharton\n *\n * Licensed under the Apache License, Ve"
},
{
"path": "library/src/com/viewpagerindicator/IconPageIndicator.java",
"chars": 5486,
"preview": "/*\n * Copyright (C) 2011 The Android Open Source Project\n * Copyright (C) 2012 Jake Wharton\n *\n * Licensed under the Apa"
},
{
"path": "library/src/com/viewpagerindicator/IconPagerAdapter.java",
"chars": 237,
"preview": "package com.viewpagerindicator;\n\npublic interface IconPagerAdapter {\n /**\n * Get icon representing the page at {@"
},
{
"path": "library/src/com/viewpagerindicator/IcsLinearLayout.java",
"chars": 6858,
"preview": "package com.viewpagerindicator;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.g"
},
{
"path": "library/src/com/viewpagerindicator/LinePageIndicator.java",
"chars": 15584,
"preview": "/*\n * Copyright (C) 2012 Jake Wharton\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "library/src/com/viewpagerindicator/PageIndicator.java",
"chars": 1831,
"preview": "/*\n * Copyright (C) 2011 Patrik Akerfeldt\n * Copyright (C) 2011 Jake Wharton\n *\n * Licensed under the Apache License, Ve"
},
{
"path": "library/src/com/viewpagerindicator/TabPageIndicator.java",
"chars": 9318,
"preview": "/*\n * Copyright (C) 2011 The Android Open Source Project\n * Copyright (C) 2011 Jake Wharton\n *\n * Licensed under the Apa"
},
{
"path": "library/src/com/viewpagerindicator/TitlePageIndicator.java",
"chars": 32252,
"preview": "/*\n * Copyright (C) 2011 Jake Wharton\n * Copyright (C) 2011 Patrik Akerfeldt\n * Copyright (C) 2011 Francisco Figueiredo "
},
{
"path": "library/src/com/viewpagerindicator/UnderlinePageIndicator.java",
"chars": 13372,
"preview": "/*\n * Copyright (C) 2012 Jake Wharton\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "pom.xml",
"chars": 6484,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/"
},
{
"path": "sample/AndroidManifest.xml",
"chars": 12541,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "sample/pom.xml",
"chars": 2871,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/"
},
{
"path": "sample/project.properties",
"chars": 400,
"preview": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# T"
},
{
"path": "sample/res/drawable/custom_tab_indicator.xml",
"chars": 2259,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2008 The Android Open Source Project\n\n Licensed under the "
},
{
"path": "sample/res/drawable/perm_group_calendar.xml",
"chars": 292,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item "
},
{
"path": "sample/res/drawable/perm_group_camera.xml",
"chars": 288,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item "
},
{
"path": "sample/res/drawable/perm_group_device_alarms.xml",
"chars": 302,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item "
},
{
"path": "sample/res/drawable/perm_group_location.xml",
"chars": 292,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item "
},
{
"path": "sample/res/layout/simple_circles.xml",
"chars": 1270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/simple_circles_vertical.xml",
"chars": 1284,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/simple_icons.xml",
"chars": 1237,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/simple_lines.xml",
"chars": 1267,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2012 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/simple_tabs.xml",
"chars": 1236,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/simple_titles.xml",
"chars": 1270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/simple_titles_bottom.xml",
"chars": 1357,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/simple_underlines.xml",
"chars": 1232,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2012 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/themed_circles.xml",
"chars": 1526,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/themed_lines.xml",
"chars": 1461,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2012 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/themed_titles.xml",
"chars": 1630,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2011 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/layout/themed_underlines.xml",
"chars": 1425,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2012 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/res/menu/menu.xml",
"chars": 311,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item andr"
},
{
"path": "sample/res/values/styles.xml",
"chars": 3402,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (C) 2012 Jake Wharton\n\n Licensed under the Apache License, Ver"
},
{
"path": "sample/src/com/viewpagerindicator/sample/BaseSampleActivity.java",
"chars": 1579,
"preview": "package com.viewpagerindicator.sample;\n\nimport java.util.Random;\n\nimport com.viewpagerindicator.PageIndicator;\n\nimport a"
},
{
"path": "sample/src/com/viewpagerindicator/sample/ListSamples.java",
"chars": 4661,
"preview": "package com.viewpagerindicator.sample;\r\n\r\nimport java.text.Collator;\r\nimport java.util.ArrayList;\r\nimport java.util.Coll"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleCirclesDefault.java",
"chars": 674,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleCirclesInitialPage.java",
"chars": 810,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleCirclesSnap.java",
"chars": 754,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleCirclesStyledLayout.java",
"chars": 679,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleCirclesStyledMethods.java",
"chars": 1079,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleCirclesStyledTheme.java",
"chars": 748,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleCirclesWithListener.java",
"chars": 1309,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport andro"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleIconsDefault.java",
"chars": 667,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleLinesDefault.java",
"chars": 666,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleLinesStyledLayout.java",
"chars": 671,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleLinesStyledMethods.java",
"chars": 986,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleLinesStyledTheme.java",
"chars": 740,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTabsDefault.java",
"chars": 1576,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTabsStyled.java",
"chars": 1577,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTabsWithIcons.java",
"chars": 1967,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\nimport android"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTitlesBottom.java",
"chars": 676,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTitlesCenterClickListener.java",
"chars": 1223,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport andro"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTitlesDefault.java",
"chars": 671,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\n\nimport com."
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTitlesInitialPage.java",
"chars": 807,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\n\nimport com."
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTitlesStyledLayout.java",
"chars": 676,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\n\nimport com."
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTitlesStyledMethods.java",
"chars": 1285,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\n\nimport com."
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTitlesStyledTheme.java",
"chars": 745,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\n\nimport com."
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTitlesTriangle.java",
"chars": 854,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\n\nimport com."
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleTitlesWithListener.java",
"chars": 1305,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport andro"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleUnderlinesDefault.java",
"chars": 686,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleUnderlinesNoFade.java",
"chars": 773,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleUnderlinesStyledLayout.java",
"chars": 691,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleUnderlinesStyledMethods.java",
"chars": 920,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/SampleUnderlinesStyledTheme.java",
"chars": 760,
"preview": "package com.viewpagerindicator.sample;\n\nimport android.os.Bundle;\nimport android.support.v4.view.ViewPager;\nimport com.v"
},
{
"path": "sample/src/com/viewpagerindicator/sample/TestFragment.java",
"chars": 2055,
"preview": "package com.viewpagerindicator.sample;\r\n\r\nimport android.os.Bundle;\r\nimport android.support.v4.app.Fragment;\r\nimport and"
},
{
"path": "sample/src/com/viewpagerindicator/sample/TestFragmentAdapter.java",
"chars": 1432,
"preview": "package com.viewpagerindicator.sample;\r\n\r\nimport android.support.v4.app.Fragment;\r\nimport android.support.v4.app.Fragmen"
}
]
// ... and 7 more files (download for full content)
About this extraction
This page contains the full source code of the JakeWharton/ViewPagerIndicator GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 86 files (214.4 KB), approximately 49.7k tokens, and a symbol index with 329 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.