@ -1,3 +1,3 @@
|
||||
<component name="DependencyValidationManager">
|
||||
<scope name="Astrid" pattern="src:*..*&&!src[ActionBarSherlock]:*..*&&!src[android-aac-enc]:*..*&&!src[GreenDroid]:*..*&&!src[ViewPagerIndicator]:*..*&&!src[tests]:*..*&&!src[tests-sync]:*..*" />
|
||||
<scope name="Astrid" pattern="src:*..*&&!src[ActionBarSherlock]:*..*&&!src[android-aac-enc]:*..*&&!src[GreenDroid]:*..*&&!src[tests]:*..*&&!src[tests-sync]:*..*" />
|
||||
</component>
|
@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
** Copyright (c) 2012 Todoroo Inc
|
||||
**
|
||||
** See the file "LICENSE" for the full license governing this code.
|
||||
-->
|
||||
<com.todoroo.astrid.ui.TaskEditMoreControls xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/more_controls"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" >
|
||||
|
||||
</com.todoroo.astrid.ui.TaskEditMoreControls>
|
@ -1,40 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
|
||||
public class TaskEditMoreControls extends LinearLayout {
|
||||
|
||||
public TaskEditMoreControls(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public TaskEditMoreControls(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
}
|
||||
|
||||
public void setViewHeightBasedOnChildren(LayoutParams params) {
|
||||
|
||||
int totalHeight = 0;
|
||||
int desiredWidth = MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST);
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
View listItem = getChildAt(i);
|
||||
listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
|
||||
totalHeight += listItem.getMeasuredHeight();
|
||||
}
|
||||
|
||||
params.height = totalHeight;
|
||||
setLayoutParams(params);
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
Change Log
|
||||
==========
|
||||
|
||||
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.
|
@ -1,152 +0,0 @@
|
||||
Android ViewPagerIndicator
|
||||
==========================
|
||||
|
||||
Port of [Patrik Åkerfeldt][1]'s paging indicators that are compatible with the
|
||||
ViewPager from the [Android Compatibility Library][2] and
|
||||
[ActionBarSherlock][3].
|
||||
|
||||
Try out the sample application [on the Android Market][10].
|
||||
|
||||
![ViewPagerIndicator Sample Screenshots][9]
|
||||
|
||||
|
||||
|
||||
|
||||
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);
|
||||
|
||||
*Note*: If you are using `TitlePageIndicator` your adapter must implement
|
||||
`TitleProvider`.
|
||||
|
||||
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.2.2</version>
|
||||
<type>apklib</type>
|
||||
</dependency>
|
||||
|
||||
You must also include the following repository:
|
||||
|
||||
<repository>
|
||||
<id>com.jakewharton</id>
|
||||
<url>http://r.jakewharton.com/maven/release</url>
|
||||
</repository>
|
||||
|
||||
|
||||
|
||||
This project depends on the `ViewPager` class which is available in the
|
||||
[Android Compatibility 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 2011 Patrik Åkerfeldt
|
||||
Copyright 2011 Francisco Figueiredo Jr.
|
||||
Copyright 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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[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://market.android.com/details?id=com.viewpagerindicator.sample
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.viewpagerindicator"
|
||||
android:versionCode="26"
|
||||
android:versionName="2.2.2">
|
||||
|
||||
<uses-sdk android:minSdkVersion="4" />
|
||||
</manifest>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="LIBRARY_PROJECT" value="true" />
|
||||
<option name="UPDATE_PROPERTY_FILES" value="true" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="android-support-v41" level="project" />
|
||||
<orderEntry type="module" module-name="ActionBarSherlock" />
|
||||
</component>
|
||||
</module>
|
||||
|
@ -1,115 +0,0 @@
|
||||
<?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>
|
@ -1,67 +0,0 @@
|
||||
<?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>
|
||||
|
||||
<groupId>com.viewpagerindicator</groupId>
|
||||
<artifactId>library</artifactId>
|
||||
<name>Android-ViewPagerIndicator</name>
|
||||
<packaging>apklib</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.viewpagerindicator</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>2.2.2</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>android</groupId>
|
||||
<artifactId>android</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>android.support</groupId>
|
||||
<artifactId>compatibility-v4</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||
<artifactId>maven-android-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<configuration>
|
||||
<configLocation>${project.basedir}/checkstyle.xml</configLocation>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>checkstyle</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -1,40 +0,0 @@
|
||||
-optimizationpasses 5
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-dontpreverify
|
||||
-verbose
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
}
|
||||
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
# 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-17
|
||||
android.library.reference.1=../../actionbarsherlock/library
|
@ -1,24 +0,0 @@
|
||||
<?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>
|
@ -1,26 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 147 B |
Before Width: | Height: | Size: 148 B |
Before Width: | Height: | Size: 147 B |
Before Width: | Height: | Size: 146 B |
Before Width: | Height: | Size: 153 B |
Before Width: | Height: | Size: 145 B |
Before Width: | Height: | Size: 148 B |
Before Width: | Height: | Size: 151 B |
Before Width: | Height: | Size: 150 B |
Before Width: | Height: | Size: 150 B |
Before Width: | Height: | Size: 157 B |
Before Width: | Height: | Size: 155 B |
Before Width: | Height: | Size: 147 B |
Before Width: | Height: | Size: 153 B |
Before Width: | Height: | Size: 147 B |
Before Width: | Height: | Size: 148 B |
Before Width: | Height: | Size: 166 B |
Before Width: | Height: | Size: 149 B |
@ -1,34 +0,0 @@
|
||||
<?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>
|
@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<view
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
class="com.viewpagerindicator.TabPageIndicator$TabView"
|
||||
style="?attr/vpiTabPageIndicatorStyle">
|
||||
<TextView
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="?attr/vpiTabTextStyle"
|
||||
android:gravity="center" />
|
||||
</view>
|
@ -1,84 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 Patrik Åkerfeldt
|
||||
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>
|
||||
<declare-styleable name="ViewPagerIndicator">
|
||||
<!-- Style of the circle indicator. -->
|
||||
<attr name="vpiCirclePageIndicatorStyle" format="reference"/>
|
||||
|
||||
<!-- Style of the title indicator. -->
|
||||
<attr name="vpiTitlePageIndicatorStyle" format="reference"/>
|
||||
|
||||
<!-- Style of the tab indicator. -->
|
||||
<attr name="vpiTabPageIndicatorStyle" format="reference"/>
|
||||
<!-- Style of the text in a tab. -->
|
||||
<attr name="vpiTabTextStyle" format="reference"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="CirclePageIndicator">
|
||||
<!-- Whether or not the indicators should be centered. -->
|
||||
<attr name="centered" format="boolean" />
|
||||
<!-- Color of the filled circle that represents the current page. -->
|
||||
<attr name="fillColor" format="color" />
|
||||
<!-- Orientation of the indicator. -->
|
||||
<attr name="orientation">
|
||||
<enum name="horizontal" value="0" />
|
||||
<enum name="vertical" value="1" />
|
||||
</attr>
|
||||
<!-- 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" format="dimension" />
|
||||
</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" />
|
||||
<!-- Color of the selected title. -->
|
||||
<attr name="selectedColor" format="color" />
|
||||
<!-- Whether or not the selected item is displayed as bold. -->
|
||||
<attr name="selectedBold" format="boolean" />
|
||||
<!-- Color of regular titles. -->
|
||||
<attr name="textColor" format="color" />
|
||||
<!-- Size of title text. -->
|
||||
<attr name="textSize" format="dimension" />
|
||||
<!-- 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" />
|
||||
</declare-styleable>
|
||||
</resources>
|
@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 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.
|
||||
-->
|
||||
|
||||
<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>
|
@ -1,39 +0,0 @@
|
||||
<?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>
|
||||
<bool name="default_circle_indicator_centered">true</bool>
|
||||
<color name="default_circle_indicator_fill_color">#FFFFFFFF</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_title_indicator_clip_padding">4dp</dimen>
|
||||
<color name="default_title_indicator_footer_color">#FF6899FF</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>
|
||||
<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">15sp</dimen>
|
||||
<dimen name="default_title_indicator_title_padding">5dp</dimen>
|
||||
<dimen name="default_title_indicator_top_padding">7dp</dimen>
|
||||
</resources>
|
@ -1,72 +0,0 @@
|
||||
<?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="vpiCirclePageIndicatorStyle">@style/Widget.CirclePageIndicator</item>
|
||||
<item name="vpiTitlePageIndicatorStyle">@style/Widget.TitlePageIndicator</item>
|
||||
<item name="vpiTabPageIndicatorStyle">@style/Widget.TabPageIndicator</item>
|
||||
<item name="vpiTabTextStyle">@style/Widget.TabPageIndicator.Text</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget"></style>
|
||||
|
||||
<style name="Widget.CirclePageIndicator" parent="Widget">
|
||||
<item name="centered">@bool/default_circle_indicator_centered</item>
|
||||
<item name="fillColor">@color/default_circle_indicator_fill_color</item>
|
||||
<item name="orientation">@integer/default_circle_indicator_orientation</item>
|
||||
<item name="radius">@dimen/default_circle_indicator_radius</item>
|
||||
<item name="snap">@bool/default_circle_indicator_snap</item>
|
||||
<item name="strokeColor">@color/default_circle_indicator_stroke_color</item>
|
||||
<item name="strokeWidth">@dimen/default_circle_indicator_stroke_width</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.TitlePageIndicator" parent="Widget">
|
||||
<item name="clipPadding">@dimen/default_title_indicator_clip_padding</item>
|
||||
<item name="footerColor">@color/default_title_indicator_footer_color</item>
|
||||
<item name="footerLineHeight">@dimen/default_title_indicator_footer_line_height</item>
|
||||
<item name="footerIndicatorStyle">@integer/default_title_indicator_footer_indicator_style</item>
|
||||
<item name="footerIndicatorHeight">@dimen/default_title_indicator_footer_indicator_height</item>
|
||||
<item name="footerIndicatorUnderlinePadding">@dimen/default_title_indicator_footer_indicator_underline_padding</item>
|
||||
<item name="footerPadding">@dimen/default_title_indicator_footer_padding</item>
|
||||
<item name="selectedColor">@color/default_title_indicator_selected_color</item>
|
||||
<item name="selectedBold">@bool/default_title_indicator_selected_bold</item>
|
||||
<item name="textColor">@color/default_title_indicator_text_color</item>
|
||||
<item name="textSize">@dimen/default_title_indicator_text_size</item>
|
||||
<item name="titlePadding">@dimen/default_title_indicator_title_padding</item>
|
||||
<item name="topPadding">@dimen/default_title_indicator_top_padding</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.TabPageIndicator" parent="Widget">
|
||||
<item name="android:gravity">center_horizontal</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>
|
||||
</style>
|
||||
<style name="Widget.TabPageIndicator.Text" parent="Widget">
|
||||
<item name="android:textAppearance">@style/TextAppearance.TabPageIndicator</item>
|
||||
<item name="android:textColor">@color/vpi__dark_theme</item>
|
||||
<item name="android:textSize">12sp</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
<item name="android:maxLines">1</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.TabPageIndicator" parent="Widget">
|
||||
|
||||
</style>
|
||||
</resources>
|
@ -1,526 +0,0 @@
|
||||
/*
|
||||
* 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.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 circles (one for each view). The current view position is filled and
|
||||
* others are only stroked.
|
||||
*/
|
||||
public class CirclePageIndicator extends View implements PageIndicator {
|
||||
public static final int HORIZONTAL = 0;
|
||||
public static final int VERTICAL = 1;
|
||||
|
||||
private float mRadius;
|
||||
private final Paint mPaintStroke;
|
||||
private final Paint mPaintFill;
|
||||
private ViewPager mViewPager;
|
||||
private ViewPager.OnPageChangeListener mListener;
|
||||
private int mCurrentPage;
|
||||
private int mSnapPage;
|
||||
private int mCurrentOffset;
|
||||
private int mScrollState;
|
||||
private int mPageSize;
|
||||
private int mOrientation;
|
||||
private boolean mCentered;
|
||||
private boolean mSnap;
|
||||
|
||||
private static final int INVALID_POINTER = -1;
|
||||
|
||||
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);
|
||||
|
||||
//Load defaults from resources
|
||||
final Resources res = getResources();
|
||||
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, R.style.Widget_CirclePageIndicator);
|
||||
|
||||
mCentered = a.getBoolean(R.styleable.CirclePageIndicator_centered, defaultCentered);
|
||||
mOrientation = a.getInt(R.styleable.CirclePageIndicator_orientation, defaultOrientation);
|
||||
mPaintStroke = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mPaintStroke.setStyle(Style.STROKE);
|
||||
mPaintStroke.setColor(a.getColor(R.styleable.CirclePageIndicator_strokeColor, defaultStrokeColor));
|
||||
mPaintStroke.setStrokeWidth(a.getDimension(R.styleable.CirclePageIndicator_strokeWidth, defaultStrokeWidth));
|
||||
mPaintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
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);
|
||||
|
||||
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 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;
|
||||
updatePageSize();
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* (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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
//Draw the filled circle according to the current scroll
|
||||
float cx = (mSnap ? mSnapPage : mCurrentPage) * threeRadius;
|
||||
if (!mSnap && (mPageSize != 0)) {
|
||||
cx += (mCurrentOffset * 1.0f / mPageSize) * threeRadius;
|
||||
}
|
||||
if (mOrientation == HORIZONTAL) {
|
||||
dX = longOffset + cx;
|
||||
dY = shortOffset;
|
||||
} else {
|
||||
dX = shortOffset;
|
||||
dY = longOffset + cx;
|
||||
}
|
||||
canvas.drawCircle(dX, dY, mRadius - getResources().getDimension(R.dimen.default_circle_indicator_stroke_width)/2
|
||||
, mPaintFill);
|
||||
|
||||
//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;
|
||||
}
|
||||
canvas.drawCircle(dX, dY, mRadius, mPaintStroke);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(android.view.MotionEvent ev) {
|
||||
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int action = ev.getAction();
|
||||
|
||||
switch (action & MotionEventCompat.ACTION_MASK) {
|
||||
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) {
|
||||
if (!mViewPager.isFakeDragging()) {
|
||||
mViewPager.beginFakeDrag();
|
||||
}
|
||||
|
||||
mLastMotionX = x;
|
||||
|
||||
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)) {
|
||||
mViewPager.setCurrentItem(mCurrentPage - 1);
|
||||
return true;
|
||||
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
|
||||
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);
|
||||
final float x = MotionEventCompat.getX(ev, index);
|
||||
mLastMotionX = x;
|
||||
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 (view.getAdapter() == null) {
|
||||
throw new IllegalStateException("ViewPager does not have adapter instance.");
|
||||
}
|
||||
mViewPager = view;
|
||||
mViewPager.setOnPageChangeListener(this);
|
||||
updatePageSize();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void updatePageSize() {
|
||||
if (mViewPager != null) {
|
||||
mPageSize = (mOrientation == HORIZONTAL) ? mViewPager.getWidth() : mViewPager.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
mCurrentOffset = positionOffsetPixels;
|
||||
updatePageSize();
|
||||
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 = 0;
|
||||
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 = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
public void setViewPager(ViewPager view);
|
||||
|
||||
/**
|
||||
* Bind the indicator to a ViewPager.
|
||||
*
|
||||
* @param view
|
||||
* @param initialPosition
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
public void setCurrentItem(int item);
|
||||
|
||||
/**
|
||||
* Set a page change listener which will receive forwarded events.
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
|
||||
|
||||
/**
|
||||
* Notify the indicator that the fragment list has changed.
|
||||
*/
|
||||
public void notifyDataSetChanged();
|
||||
}
|
@ -1,245 +0,0 @@
|
||||
/*
|
||||
* 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.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* This widget implements the dynamic action bar tab behavior that can change
|
||||
* across different configurations or circumstances.
|
||||
*/
|
||||
public class TabPageIndicator extends HorizontalScrollView implements PageIndicator {
|
||||
Runnable mTabSelector;
|
||||
|
||||
private OnClickListener mTabClickListener = new OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
TabView tabView = (TabView)view;
|
||||
mViewPager.setCurrentItem(tabView.getIndex());
|
||||
}
|
||||
};
|
||||
|
||||
private LinearLayout mTabLayout;
|
||||
private ViewPager mViewPager;
|
||||
private ViewPager.OnPageChangeListener mListener;
|
||||
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
int mMaxTabWidth;
|
||||
private int mSelectedTabIndex;
|
||||
|
||||
public TabPageIndicator(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public TabPageIndicator(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setHorizontalScrollBarEnabled(false);
|
||||
|
||||
mInflater = LayoutInflater.from(context);
|
||||
|
||||
mTabLayout = new LinearLayout(getContext());
|
||||
addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.FILL_PARENT));
|
||||
}
|
||||
|
||||
@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(String text, int index) {
|
||||
//Workaround for not being able to pass a defStyle on pre-3.0
|
||||
final TabView tabView = (TabView)mInflater.inflate(R.layout.vpi__tab, null);
|
||||
tabView.init(this, text, index);
|
||||
tabView.setFocusable(true);
|
||||
tabView.setOnClickListener(mTabClickListener);
|
||||
mTabLayout.addView(tabView, new LinearLayout.LayoutParams(0, LayoutParams.FILL_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) {
|
||||
final PagerAdapter adapter = view.getAdapter();
|
||||
if (adapter == null) {
|
||||
throw new IllegalStateException("ViewPager does not have adapter instance.");
|
||||
}
|
||||
if (!(adapter instanceof TitleProvider)) {
|
||||
throw new IllegalStateException("ViewPager adapter must implement TitleProvider to be used with TitlePageIndicator.");
|
||||
}
|
||||
mViewPager = view;
|
||||
view.setOnPageChangeListener(this);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void notifyDataSetChanged() {
|
||||
mTabLayout.removeAllViews();
|
||||
TitleProvider adapter = (TitleProvider)mViewPager.getAdapter();
|
||||
final int count = ((PagerAdapter)adapter).getCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
addTab(adapter.getTitle(i), i);
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
public static class TabView extends LinearLayout {
|
||||
private TabPageIndicator mParent;
|
||||
private int mIndex;
|
||||
|
||||
public TabView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public void init(TabPageIndicator parent, String text, int index) {
|
||||
mParent = parent;
|
||||
mIndex = index;
|
||||
|
||||
TextView textView = (TextView)findViewById(android.R.id.text1);
|
||||
textView.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
// Re-measure if we went beyond our maximum size.
|
||||
if (mParent.mMaxTabWidth > 0 && getMeasuredWidth() > mParent.mMaxTabWidth) {
|
||||
super.onMeasure(MeasureSpec.makeMeasureSpec(mParent.mMaxTabWidth, MeasureSpec.EXACTLY),
|
||||
heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return mIndex;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,776 +0,0 @@
|
||||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
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.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.view.MotionEventCompat;
|
||||
import android.support.v4.view.PagerAdapter;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Interface for a callback when the center item has been clicked.
|
||||
*/
|
||||
public static interface OnCenterItemClickListener {
|
||||
/**
|
||||
* Callback when the center item has been clicked.
|
||||
*
|
||||
* @param position Position of the current center item.
|
||||
*/
|
||||
public 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;
|
||||
}
|
||||
}
|
||||
|
||||
private ViewPager mViewPager;
|
||||
private ViewPager.OnPageChangeListener mListener;
|
||||
private TitleProvider mTitleProvider;
|
||||
private int mCurrentPage;
|
||||
private int mCurrentOffset;
|
||||
private int mScrollState;
|
||||
private final Paint mPaintText = new Paint();
|
||||
private boolean mBoldText;
|
||||
private int mColorText;
|
||||
private int mColorSelected;
|
||||
private Path mPath;
|
||||
private final Paint mPaintFooterLine = new Paint();
|
||||
private IndicatorStyle mFooterIndicatorStyle;
|
||||
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);
|
||||
|
||||
//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 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, R.style.Widget_TitlePageIndicator);
|
||||
|
||||
//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);
|
||||
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_textColor, defaultTextColor);
|
||||
mBoldText = a.getBoolean(R.styleable.TitlePageIndicator_selectedBold, defaultSelectedBold);
|
||||
|
||||
final float textSize = a.getDimension(R.styleable.TitlePageIndicator_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);
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
//Calculate views bounds
|
||||
ArrayList<RectF> bounds = calculateAllBounds(mPaintText);
|
||||
|
||||
//Make sure we're on a page that still exists
|
||||
if (mCurrentPage >= bounds.size()) {
|
||||
setCurrentItem(bounds.size()-1);
|
||||
}
|
||||
|
||||
final int countMinusOne = count - 1;
|
||||
final float halfWidth = getWidth() / 2f;
|
||||
final int left = getLeft();
|
||||
final float leftClip = left + mClipPadding;
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
final int right = left + width;
|
||||
final float rightClip = right - mClipPadding;
|
||||
|
||||
int page = mCurrentPage;
|
||||
float offsetPercent;
|
||||
if (mCurrentOffset <= halfWidth) {
|
||||
offsetPercent = 1.0f * mCurrentOffset / width;
|
||||
} else {
|
||||
page += 1;
|
||||
offsetPercent = 1.0f * (width - mCurrentOffset) / width;
|
||||
}
|
||||
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
|
||||
RectF 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--) {
|
||||
RectF bound = bounds.get(i);
|
||||
//Is left side is outside the screen
|
||||
if (bound.left < leftClip) {
|
||||
float 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
|
||||
RectF rightBound = bounds.get(i + 1);
|
||||
//Intersection
|
||||
if (bound.right + mTitlePadding > rightBound.left) {
|
||||
bound.left = 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++) {
|
||||
RectF bound = bounds.get(i);
|
||||
//If right side is outside the screen
|
||||
if (bound.right > rightClip) {
|
||||
float 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
|
||||
RectF leftBound = bounds.get(i - 1);
|
||||
//Intersection
|
||||
if (bound.left - mTitlePadding < leftBound.right) {
|
||||
bound.left = leftBound.right + mTitlePadding;
|
||||
bound.right = bound.left + w;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Now draw views
|
||||
for (int i = 0; i < count; i++) {
|
||||
//Get the title
|
||||
RectF 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);
|
||||
//Only set bold if we are within bounds
|
||||
mPaintText.setFakeBoldText(currentPage && currentBold && mBoldText);
|
||||
|
||||
//Draw text as unselected
|
||||
mPaintText.setColor(mColorText);
|
||||
canvas.drawText(mTitleProvider.getTitle(i), 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(mTitleProvider.getTitle(i), bound.left, bound.bottom + mTopPadding, mPaintText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Draw the footer line
|
||||
mPath = new Path();
|
||||
mPath.moveTo(0, height - mFooterLineHeight / 2f);
|
||||
mPath.lineTo(width, height - mFooterLineHeight / 2f);
|
||||
mPath.close();
|
||||
canvas.drawPath(mPath, mPaintFooterLine);
|
||||
|
||||
switch (mFooterIndicatorStyle) {
|
||||
case Triangle:
|
||||
mPath = new Path();
|
||||
mPath.moveTo(halfWidth, height - mFooterLineHeight - mFooterIndicatorHeight);
|
||||
mPath.lineTo(halfWidth + mFooterIndicatorHeight, height - mFooterLineHeight);
|
||||
mPath.lineTo(halfWidth - mFooterIndicatorHeight, height - mFooterLineHeight);
|
||||
mPath.close();
|
||||
canvas.drawPath(mPath, mPaintFooterIndicator);
|
||||
break;
|
||||
|
||||
case Underline:
|
||||
if (!currentSelected) {
|
||||
break;
|
||||
}
|
||||
|
||||
RectF underlineBounds = bounds.get(page);
|
||||
mPath = new Path();
|
||||
mPath.moveTo(underlineBounds.left - mFooterIndicatorUnderlinePadding, height - mFooterLineHeight);
|
||||
mPath.lineTo(underlineBounds.right + mFooterIndicatorUnderlinePadding, height - mFooterLineHeight);
|
||||
mPath.lineTo(underlineBounds.right + mFooterIndicatorUnderlinePadding, height - mFooterLineHeight - mFooterIndicatorHeight);
|
||||
mPath.lineTo(underlineBounds.left - mFooterIndicatorUnderlinePadding, height - mFooterLineHeight - mFooterIndicatorHeight);
|
||||
mPath.close();
|
||||
|
||||
mPaintFooterIndicator.setAlpha((int)(0xFF * selectedPercent));
|
||||
canvas.drawPath(mPath, mPaintFooterIndicator);
|
||||
mPaintFooterIndicator.setAlpha(0xFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(android.view.MotionEvent ev) {
|
||||
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int action = ev.getAction();
|
||||
|
||||
switch (action & MotionEventCompat.ACTION_MASK) {
|
||||
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) {
|
||||
if (!mViewPager.isFakeDragging()) {
|
||||
mViewPager.beginFakeDrag();
|
||||
}
|
||||
|
||||
mLastMotionX = x;
|
||||
|
||||
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) {
|
||||
mViewPager.setCurrentItem(mCurrentPage - 1);
|
||||
return true;
|
||||
}
|
||||
} else if (eventX > rightThird) {
|
||||
if (mCurrentPage < count - 1) {
|
||||
mViewPager.setCurrentItem(mCurrentPage + 1);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
//Middle third
|
||||
if (mCenterItemClickListener != null) {
|
||||
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);
|
||||
final float x = MotionEventCompat.getX(ev, index);
|
||||
mLastMotionX = x;
|
||||
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(RectF curViewBound, float curViewWidth, int right) {
|
||||
curViewBound.right = right - mClipPadding;
|
||||
curViewBound.left = 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(RectF curViewBound, float curViewWidth, int left) {
|
||||
curViewBound.left = left + mClipPadding;
|
||||
curViewBound.right = mClipPadding + curViewWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate views bounds and scroll them according to the current index
|
||||
*
|
||||
* @param paint
|
||||
* @param currentIndex
|
||||
* @return
|
||||
*/
|
||||
private ArrayList<RectF> calculateAllBounds(Paint paint) {
|
||||
ArrayList<RectF> list = new ArrayList<RectF>();
|
||||
//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++) {
|
||||
RectF bounds = calcBounds(i, paint);
|
||||
float w = (bounds.right - bounds.left);
|
||||
float h = (bounds.bottom - bounds.top);
|
||||
bounds.left = (halfWidth) - (w / 2) - mCurrentOffset + ((i - mCurrentPage) * 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 RectF calcBounds(int index, Paint paint) {
|
||||
//Calculate the text bounds
|
||||
RectF bounds = new RectF();
|
||||
bounds.right = paint.measureText(mTitleProvider.getTitle(index));
|
||||
bounds.bottom = paint.descent() - paint.ascent();
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewPager(ViewPager view) {
|
||||
final PagerAdapter adapter = view.getAdapter();
|
||||
if (adapter == null) {
|
||||
throw new IllegalStateException("ViewPager does not have adapter instance.");
|
||||
}
|
||||
if (!(adapter instanceof TitleProvider)) {
|
||||
throw new IllegalStateException("ViewPager adapter must implement TitleProvider to be used with TitlePageIndicator.");
|
||||
}
|
||||
mViewPager = view;
|
||||
mViewPager.setOnPageChangeListener(this);
|
||||
mTitleProvider = (TitleProvider)adapter;
|
||||
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;
|
||||
mCurrentOffset = positionOffsetPixels;
|
||||
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 = 0;
|
||||
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
|
||||
RectF bounds = new RectF();
|
||||
bounds.bottom = mPaintText.descent()-mPaintText.ascent();
|
||||
height = bounds.bottom - bounds.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);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Patrik Akerfeldt
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A TitleProvider provides the title to display according to a view.
|
||||
*/
|
||||
public interface TitleProvider {
|
||||
/**
|
||||
* Returns the title of the view at position
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
public String getTitle(int position);
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
<?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>
|
||||
|
||||
<groupId>com.viewpagerindicator</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>2.2.2</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>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>personal-repository</id>
|
||||
<name>JakeWharton.com Maven Repository</name>
|
||||
<url>scp://r.jakewharton.com/home/jakewharton_repository/r.jakewharton.com/maven/release/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>personal-repository</id>
|
||||
<name>JakeWharton.com Maven Repository</name>
|
||||
<url>scp://r.jakewharton.com/home/jakewharton_repository/r.jakewharton.com/maven/snapshot/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<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>1.6_r3</android.version>
|
||||
<android.platform>4</android.platform>
|
||||
<android.support.version>r6</android.support.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>android</groupId>
|
||||
<artifactId>android</artifactId>
|
||||
<version>${android.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>android.support</groupId>
|
||||
<artifactId>compatibility-v4</artifactId>
|
||||
<version>${android.support.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>com.jakewharton</id>
|
||||
<url>http://r.jakewharton.com/maven/release</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<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>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.8</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<version>3.0.0-alpha-13</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-deploy-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.wagon</groupId>
|
||||
<artifactId>wagon-ssh</artifactId>
|
||||
<version>1.0-beta-7</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|