├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── build.gradle
├── demo
├── .gitignore
├── build.gradle
├── proguard-rules.txt
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ ├── nemo.jpg
│ ├── toystory.jpg
│ ├── up.jpg
│ └── wall.jpg
│ ├── java
│ └── com
│ │ └── daimajia
│ │ └── slider
│ │ └── demo
│ │ ├── ChildAnimationExample.java
│ │ ├── MainActivity.java
│ │ └── TransformerAdapter.java
│ └── res
│ ├── drawable-hdpi
│ ├── bigbang.jpg
│ ├── bird.png
│ ├── d1.png
│ ├── game_of_thrones.jpg
│ ├── hannibal.jpg
│ ├── house.jpg
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── layout
│ ├── activity_main.xml
│ └── item.xml
│ ├── menu
│ └── main.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
├── .gitignore
├── build.gradle
├── gradle-mvn-push.gradle
├── gradle.properties
├── proguard-rules.txt
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── daimajia
│ │ └── slider
│ │ └── library
│ │ ├── Animations
│ │ ├── BaseAnimationInterface.java
│ │ └── DescriptionAnimation.java
│ │ ├── Indicators
│ │ └── PagerIndicator.java
│ │ ├── SliderAdapter.java
│ │ ├── SliderLayout.java
│ │ ├── SliderTypes
│ │ ├── BaseSliderView.java
│ │ ├── DefaultSliderView.java
│ │ └── TextSliderView.java
│ │ ├── Transformers
│ │ ├── AccordionTransformer.java
│ │ ├── BackgroundToForegroundTransformer.java
│ │ ├── BaseTransformer.java
│ │ ├── CubeInTransformer.java
│ │ ├── DefaultTransformer.java
│ │ ├── DepthPageTransformer.java
│ │ ├── FadeTransformer.java
│ │ ├── FlipHorizontalTransformer.java
│ │ ├── FlipPageViewTransformer.java
│ │ ├── ForegroundToBackgroundTransformer.java
│ │ ├── RotateDownTransformer.java
│ │ ├── RotateUpTransformer.java
│ │ ├── StackTransformer.java
│ │ ├── TabletTransformer.java
│ │ ├── ZoomInTransformer.java
│ │ ├── ZoomOutSlideTransformer.java
│ │ └── ZoomOutTransformer.java
│ │ └── Tricks
│ │ ├── FixedSpeedScroller.java
│ │ ├── InfinitePagerAdapter.java
│ │ ├── InfiniteViewPager.java
│ │ └── ViewPagerEx.java
│ └── res
│ ├── drawable
│ └── indicator_corner_bg.xml
│ ├── layout
│ ├── indicator_layout.xml
│ ├── render_type_default.xml
│ ├── render_type_text.xml
│ └── slider_layout.xml
│ └── values
│ ├── attrs.xml
│ ├── strings.xml
│ └── styles.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 | .DS_Store
11 |
12 | # generated files
13 | bin/
14 | gen/
15 | Wiki/
16 |
17 | # Local configuration file (sdk path, etc)
18 | local.properties
19 |
20 | # Eclipse project files
21 | .classpath
22 | .project
23 | .settings/
24 |
25 | # Proguard folder generated by Eclipse
26 | proguard/
27 |
28 | #Android Studio
29 | build/
30 |
31 | # Intellij project files
32 | *.iml
33 | *.ipr
34 | *.iws
35 | .idea/
36 |
37 | #gradle
38 | .gradle/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 | android:
3 | components:
4 | # Uncomment the lines below if you want to
5 | # use the latest revision of Android SDK Tools
6 | # - platform-tools
7 | # - tools
8 |
9 | # The BuildTools version used by your project
10 | - build-tools-22.0.1
11 |
12 | # The SDK version used to compile your project
13 | - android-22
14 |
15 | # Additional components
16 | - extra-google-google_play_services
17 | - extra-google-m2repository
18 | - extra-android-m2repository
19 | - addon-google_apis-google-19
20 |
21 | # Specify at least one system image,
22 | # if you need to run emulator(s) during your tests
23 | - sys-img-armeabi-v7a-android-19
24 | - sys-img-x86-android-17
25 | script: ./gradlew assembleDebug
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android Image Slider [](https://travis-ci.org/daimajia/AndroidImageSlider)
2 |
3 | [](https://gitter.im/daimajia/AndroidImageSlider?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4 |
5 | This is an amazing image slider for the Android platform. I decided to open source this because there is really not an attractive, convenient slider widget in Android.
6 |
7 | You can easily load images from an internet URL, drawable, or file. And there are many kinds of amazing animations you can choose. :-D
8 |
9 | ## Demo
10 |
11 | 
12 |
13 | [Download Apk](https://github.com/daimajia/AndroidImageSlider/releases/download/v1.0.8/demo-1.0.8.apk)
14 |
15 | ## Usage
16 |
17 | ### Step 1
18 |
19 | #### Gradle
20 |
21 | ```groovy
22 | dependencies {
23 | compile "com.android.support:support-v4:+"
24 | compile 'com.squareup.picasso:picasso:2.3.2'
25 | compile 'com.nineoldandroids:library:2.4.0'
26 | compile 'com.daimajia.slider:library:1.1.5@aar'
27 | }
28 | ```
29 |
30 |
31 | #### Maven
32 |
33 | ```xml
34 |
35 | com.squareup.picasso
36 | picasso
37 | 2.3.2
38 |
39 |
40 | com.nineoldandroids
41 | library
42 | 2.4.0
43 |
44 |
45 | com.daimajia.slider
46 | library
47 | 1.1.2
48 | apklib
49 |
50 | ```
51 |
52 | #### Eclipse
53 |
54 | For Eclipse users, I provided a sample project which orgnized as Eclipse way. You can download it from [here](https://github.com/daimajia/AndroidImageSlider/releases/download/v1.0.9/AndroidImageSlider-Eclipse.zip), and make some changes to fit your project.
55 |
56 | Notice: It's the version of 1.0.9, it may not update any more. You can update manually by yourself.
57 |
58 | ### Step 2
59 |
60 | Add permissions (if necessary) to your `AndroidManifest.xml`
61 |
62 | ```xml
63 |
64 |
65 |
66 |
67 |
68 | ```
69 |
70 | **Note:** If you want to load images from the internet, you need both the `INTERNET` and `READ_EXTERNAL_STORAGE` permissions to allow files from the internet to be cached into local storage.
71 |
72 | If you want to load images from drawable, then no additional permissions are necessary.
73 |
74 | ### Step 3
75 |
76 | Add the Slider to your layout:
77 |
78 | ```java
79 |
84 | ```
85 |
86 | There are some default indicators. If you want to use a provided indicator:
87 |
88 | ```java
89 |
95 | ```
96 |
97 | [Code example](https://github.com/daimajia/AndroidImageSlider/blob/master/demo%2Fsrc%2Fmain%2Fjava%2Fcom%2Fdaimajia%2Fslider%2Fdemo%2FMainActivity.java)
98 |
99 | ====
100 |
101 | ## Advanced usage
102 |
103 | Please visit [Wiki](https://github.com/daimajia/AndroidImageSlider/wiki)
104 |
105 | ## Thanks
106 |
107 | - [Picasso](https://github.com/square/picasso)
108 | - [NineOldAndroids](https://github.com/JakeWharton/NineOldAndroids)
109 | - [ViewPagerTransforms](https://github.com/ToxicBakery/ViewPagerTransforms)
110 |
111 | ##About me
112 |
113 | I am a student in mainland China. I love Google, love Android, love everything that is interesting. If you get any problems when using this library or you have an internship opportunity, please feel free to [email me](mailto:daimajia@gmail.com). :smiley:
114 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | task wrapper(type: Wrapper) {
4 | gradleVersion = '2.2.1'
5 | }
6 |
7 | buildscript {
8 | repositories {
9 | mavenCentral()
10 | }
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:1.1.2'
13 | classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.10.+'
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | mavenCentral()
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/demo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'android-sdk-manager'
2 | apply plugin: 'com.android.application'
3 |
4 |
5 | android {
6 | compileSdkVersion 22
7 | buildToolsVersion "22.0.1"
8 |
9 | defaultConfig {
10 | minSdkVersion 8
11 | targetSdkVersion 22
12 | versionCode 2
13 | versionName "1.0.1"
14 | }
15 | buildTypes {
16 | release {
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile project(':library')
25 | compile 'com.android.support:appcompat-v7:22.+'
26 | compile 'com.nineoldandroids:library:2.4.0'
27 | compile 'com.daimajia.androidanimations:library:1.0.3@aar'
28 | }
29 |
--------------------------------------------------------------------------------
/demo/proguard-rules.txt:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the ProGuard
5 | # include property in project.properties.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
--------------------------------------------------------------------------------
/demo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/demo/src/main/assets/nemo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/assets/nemo.jpg
--------------------------------------------------------------------------------
/demo/src/main/assets/toystory.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/assets/toystory.jpg
--------------------------------------------------------------------------------
/demo/src/main/assets/up.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/assets/up.jpg
--------------------------------------------------------------------------------
/demo/src/main/assets/wall.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/assets/wall.jpg
--------------------------------------------------------------------------------
/demo/src/main/java/com/daimajia/slider/demo/ChildAnimationExample.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.demo;
2 |
3 | import android.util.Log;
4 | import android.view.View;
5 |
6 | import com.daimajia.androidanimations.library.attention.StandUpAnimator;
7 | import com.daimajia.slider.library.Animations.BaseAnimationInterface;
8 |
9 | public class ChildAnimationExample implements BaseAnimationInterface {
10 |
11 | private final static String TAG = "ChildAnimationExample";
12 |
13 | @Override
14 | public void onPrepareCurrentItemLeaveScreen(View current) {
15 | View descriptionLayout = current.findViewById(com.daimajia.slider.library.R.id.description_layout);
16 | if(descriptionLayout!=null){
17 | current.findViewById(com.daimajia.slider.library.R.id.description_layout).setVisibility(View.INVISIBLE);
18 | }
19 | Log.e(TAG,"onPrepareCurrentItemLeaveScreen called");
20 | }
21 |
22 | @Override
23 | public void onPrepareNextItemShowInScreen(View next) {
24 | View descriptionLayout = next.findViewById(com.daimajia.slider.library.R.id.description_layout);
25 | if(descriptionLayout!=null){
26 | next.findViewById(com.daimajia.slider.library.R.id.description_layout).setVisibility(View.INVISIBLE);
27 | }
28 | Log.e(TAG,"onPrepareNextItemShowInScreen called");
29 | }
30 |
31 | @Override
32 | public void onCurrentItemDisappear(View view) {
33 | Log.e(TAG,"onCurrentItemDisappear called");
34 | }
35 |
36 | @Override
37 | public void onNextItemAppear(View view) {
38 |
39 | View descriptionLayout = view.findViewById(com.daimajia.slider.library.R.id.description_layout);
40 | if(descriptionLayout!=null){
41 | view.findViewById(com.daimajia.slider.library.R.id.description_layout).setVisibility(View.VISIBLE);
42 | // ValueAnimator animator = ObjectAnimator.ofFloat(
43 | // descriptionLayout, "y", -descriptionLayout.getHeight(),
44 | // 0).setDuration(500);
45 | // animator.start();
46 | // new BounceInAnimator().animate(descriptionLayout);
47 | new StandUpAnimator().animate(descriptionLayout);
48 | }
49 | Log.e(TAG,"onCurrentItemDisappear called");
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/daimajia/slider/demo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.demo;
2 |
3 | import android.content.Intent;
4 | import android.net.Uri;
5 | import android.os.Bundle;
6 | import android.support.v7.app.ActionBarActivity;
7 | import android.util.Log;
8 | import android.view.Menu;
9 | import android.view.MenuInflater;
10 | import android.view.MenuItem;
11 | import android.view.View;
12 | import android.widget.AdapterView;
13 | import android.widget.ListView;
14 | import android.widget.TextView;
15 | import android.widget.Toast;
16 |
17 | import com.daimajia.slider.library.Animations.DescriptionAnimation;
18 | import com.daimajia.slider.library.Indicators.PagerIndicator;
19 | import com.daimajia.slider.library.SliderLayout;
20 | import com.daimajia.slider.library.SliderTypes.BaseSliderView;
21 | import com.daimajia.slider.library.SliderTypes.TextSliderView;
22 | import com.daimajia.slider.library.Tricks.ViewPagerEx;
23 |
24 | import java.util.HashMap;
25 |
26 |
27 | public class MainActivity extends ActionBarActivity implements BaseSliderView.OnSliderClickListener, ViewPagerEx.OnPageChangeListener{
28 |
29 | private SliderLayout mDemoSlider;
30 |
31 | @Override
32 | protected void onCreate(Bundle savedInstanceState) {
33 | super.onCreate(savedInstanceState);
34 | setContentView(R.layout.activity_main);
35 | mDemoSlider = (SliderLayout)findViewById(R.id.slider);
36 |
37 | HashMap url_maps = new HashMap();
38 | url_maps.put("Hannibal", "http://static2.hypable.com/wp-content/uploads/2013/12/hannibal-season-2-release-date.jpg");
39 | url_maps.put("Big Bang Theory", "http://tvfiles.alphacoders.com/100/hdclearart-10.png");
40 | url_maps.put("House of Cards", "http://cdn3.nflximg.net/images/3093/2043093.jpg");
41 | url_maps.put("Game of Thrones", "http://images.boomsbeat.com/data/images/full/19640/game-of-thrones-season-4-jpg.jpg");
42 |
43 | HashMap file_maps = new HashMap();
44 | file_maps.put("Hannibal",R.drawable.hannibal);
45 | file_maps.put("Big Bang Theory",R.drawable.bigbang);
46 | file_maps.put("House of Cards",R.drawable.house);
47 | file_maps.put("Game of Thrones", R.drawable.game_of_thrones);
48 |
49 | for(String name : file_maps.keySet()){
50 | TextSliderView textSliderView = new TextSliderView(this);
51 | // initialize a SliderLayout
52 | textSliderView
53 | .description(name)
54 | .image(file_maps.get(name))
55 | .setScaleType(BaseSliderView.ScaleType.Fit)
56 | .setOnSliderClickListener(this);
57 |
58 | //add your extra information
59 | textSliderView.bundle(new Bundle());
60 | textSliderView.getBundle()
61 | .putString("extra",name);
62 |
63 | mDemoSlider.addSlider(textSliderView);
64 | }
65 | mDemoSlider.setPresetTransformer(SliderLayout.Transformer.Accordion);
66 | mDemoSlider.setPresetIndicator(SliderLayout.PresetIndicators.Center_Bottom);
67 | mDemoSlider.setCustomAnimation(new DescriptionAnimation());
68 | mDemoSlider.setDuration(4000);
69 | mDemoSlider.addOnPageChangeListener(this);
70 | ListView l = (ListView)findViewById(R.id.transformers);
71 | l.setAdapter(new TransformerAdapter(this));
72 | l.setOnItemClickListener(new AdapterView.OnItemClickListener() {
73 | @Override
74 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
75 | mDemoSlider.setPresetTransformer(((TextView) view).getText().toString());
76 | Toast.makeText(MainActivity.this, ((TextView) view).getText().toString(), Toast.LENGTH_SHORT).show();
77 | }
78 | });
79 |
80 |
81 | }
82 |
83 | @Override
84 | protected void onStop() {
85 | // To prevent a memory leak on rotation, make sure to call stopAutoCycle() on the slider before activity or fragment is destroyed
86 | mDemoSlider.stopAutoCycle();
87 | super.onStop();
88 | }
89 |
90 | @Override
91 | public void onSliderClick(BaseSliderView slider) {
92 | Toast.makeText(this,slider.getBundle().get("extra") + "",Toast.LENGTH_SHORT).show();
93 | }
94 |
95 | @Override
96 | public boolean onCreateOptionsMenu(Menu menu) {
97 | MenuInflater menuInflater = getMenuInflater();
98 | menuInflater.inflate(R.menu.main,menu);
99 | return super.onCreateOptionsMenu(menu);
100 | }
101 |
102 | @Override
103 | public boolean onOptionsItemSelected(MenuItem item) {
104 | switch (item.getItemId()){
105 | case R.id.action_custom_indicator:
106 | mDemoSlider.setCustomIndicator((PagerIndicator) findViewById(R.id.custom_indicator));
107 | break;
108 | case R.id.action_custom_child_animation:
109 | mDemoSlider.setCustomAnimation(new ChildAnimationExample());
110 | break;
111 | case R.id.action_restore_default:
112 | mDemoSlider.setPresetIndicator(SliderLayout.PresetIndicators.Center_Bottom);
113 | mDemoSlider.setCustomAnimation(new DescriptionAnimation());
114 | break;
115 | case R.id.action_github:
116 | Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/daimajia/AndroidImageSlider"));
117 | startActivity(browserIntent);
118 | break;
119 | }
120 | return super.onOptionsItemSelected(item);
121 | }
122 |
123 | @Override
124 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
125 |
126 | @Override
127 | public void onPageSelected(int position) {
128 | Log.d("Slider Demo", "Page Changed: " + position);
129 | }
130 |
131 | @Override
132 | public void onPageScrollStateChanged(int state) {}
133 | }
134 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/daimajia/slider/demo/TransformerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.demo;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.BaseAdapter;
8 | import android.widget.TextView;
9 |
10 | import com.daimajia.slider.library.SliderLayout;
11 |
12 | /**
13 | * Created by daimajia on 14-5-29.
14 | */
15 | public class TransformerAdapter extends BaseAdapter{
16 | private Context mContext;
17 | public TransformerAdapter(Context context) {
18 | mContext = context;
19 | }
20 |
21 | @Override
22 | public int getCount() {
23 | return SliderLayout.Transformer.values().length;
24 | }
25 |
26 | @Override
27 | public Object getItem(int position) {
28 | return SliderLayout.Transformer.values()[position].toString();
29 | }
30 |
31 | @Override
32 | public long getItemId(int position) {
33 | return position;
34 | }
35 |
36 | @Override
37 | public View getView(int position, View convertView, ViewGroup parent) {
38 | TextView t = (TextView)LayoutInflater.from(mContext).inflate(R.layout.item,null);
39 | t.setText(getItem(position).toString());
40 | return t;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/bigbang.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-hdpi/bigbang.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/bird.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-hdpi/bird.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/d1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-hdpi/d1.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/game_of_thrones.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-hdpi/game_of_thrones.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/hannibal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-hdpi/hannibal.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/house.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-hdpi/house.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/demo/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
16 |
17 |
38 |
45 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/demo/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/demo/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AndroidImageSlider
5 | Hello world!
6 | Settings
7 |
8 |
9 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Settings specified in this file will override any Gradle settings
5 | # configured through the IDE.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 |
21 | VERSION_NAME=1.1.2
22 | VERSION_CODE=13
23 | GROUP=com.daimajia.slider
24 |
25 | POM_DESCRIPTION=An amazing and convenient Android image slider.
26 | POM_URL=https://github.com/daimajia/AndroidImageSlider
27 | POM_SCM_URL=https://github.com/daimajia/AndroidImageSlider
28 | POM_SCM_CONNECTION=scm:https://github.com/daimajia/AndroidImageSlider.git
29 | POM_SCM_DEV_CONNECTION=scm:https://github.com/daimajia/AndroidImageSlider.git
30 | POM_LICENCE_NAME=MIT
31 | POM_LICENCE_URL=http://opensource.org/licenses/MIT
32 | POM_LICENCE_DIST=repo
33 | POM_DEVELOPER_ID=daimajia
34 | POM_DEVELOPER_NAME=daimajia
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daimajia/AndroidImageSlider/e318cabdef668de985efdcc45ca304e2ac6f58b5/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sun May 03 23:34:25 CST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 22
5 | buildToolsVersion "22.0.1"
6 |
7 | defaultConfig {
8 | minSdkVersion 8
9 | targetSdkVersion 22
10 | versionCode 15
11 | versionName "1.1.5"
12 | }
13 | buildTypes {
14 | release {
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
16 | }
17 | }
18 | lintOptions {
19 | abortOnError false
20 | }
21 | }
22 |
23 | dependencies {
24 | compile fileTree(dir: 'libs', include: ['*.jar'])
25 | compile 'com.android.support:appcompat-v7:22.1.1'
26 | compile "com.android.support:support-v4:22.1.1"
27 | compile 'com.squareup.picasso:picasso:2.5.2'
28 | compile 'com.nineoldandroids:library:2.4.0'
29 | }
30 | apply from: './gradle-mvn-push.gradle'
31 |
--------------------------------------------------------------------------------
/library/gradle-mvn-push.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 Chris Banes
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | apply plugin: 'maven'
18 | apply plugin: 'signing'
19 |
20 | def isReleaseBuild() {
21 | return VERSION_NAME.contains("SNAPSHOT") == false
22 | }
23 |
24 | def getReleaseRepositoryUrl() {
25 | return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
26 | : "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
27 | }
28 |
29 | def getSnapshotRepositoryUrl() {
30 | return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
31 | : "https://oss.sonatype.org/content/repositories/snapshots/"
32 | }
33 |
34 | def getRepositoryUsername() {
35 | return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
36 | }
37 |
38 | def getRepositoryPassword() {
39 | return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
40 | }
41 |
42 | afterEvaluate { project ->
43 | uploadArchives {
44 | repositories {
45 | mavenDeployer {
46 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
47 |
48 | pom.groupId = GROUP
49 | pom.artifactId = POM_ARTIFACT_ID
50 | pom.version = VERSION_NAME
51 |
52 | repository(url: getReleaseRepositoryUrl()) {
53 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
54 | }
55 | snapshotRepository(url: getSnapshotRepositoryUrl()) {
56 | authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
57 | }
58 |
59 | pom.project {
60 | name POM_NAME
61 | packaging POM_PACKAGING
62 | description POM_DESCRIPTION
63 | url POM_URL
64 |
65 | scm {
66 | url POM_SCM_URL
67 | connection POM_SCM_CONNECTION
68 | developerConnection POM_SCM_DEV_CONNECTION
69 | }
70 |
71 | licenses {
72 | license {
73 | name POM_LICENCE_NAME
74 | url POM_LICENCE_URL
75 | distribution POM_LICENCE_DIST
76 | }
77 | }
78 |
79 | developers {
80 | developer {
81 | id POM_DEVELOPER_ID
82 | name POM_DEVELOPER_NAME
83 | }
84 | }
85 | }
86 | }
87 | }
88 | }
89 |
90 | signing {
91 | required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
92 | sign configurations.archives
93 | }
94 |
95 | task apklib(type: Zip){
96 | appendix = extension = 'apklib'
97 |
98 | from 'AndroidManifest.xml'
99 | into('res') {
100 | from 'res'
101 | }
102 | into('src') {
103 | from 'src'
104 | }
105 | }
106 |
107 |
108 | task androidJavadocs(type: Javadoc) {
109 | source = android.sourceSets.main.java.srcDirs
110 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
111 | options.links("http://docs.oracle.com/javase/7/docs/api/");
112 | options.linksOffline "http://d.android.com/reference","${android.sdkDirectory}/docs/reference"
113 | exclude '**/BuildConfig.java'
114 | exclude '**/R.java'
115 | failOnError = false
116 | }
117 |
118 | task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
119 | classifier = 'javadoc'
120 | from androidJavadocs.destinationDir
121 | }
122 |
123 | task androidSourcesJar(type: Jar) {
124 | classifier = 'sources'
125 | from android.sourceSets.main.java.sourceFiles
126 | }
127 |
128 | artifacts {
129 | archives androidSourcesJar
130 | archives androidJavadocsJar
131 | archives apklib
132 | }
133 | }
--------------------------------------------------------------------------------
/library/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Settings specified in this file will override any Gradle settings
5 | # configured through the IDE.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | POM_NAME=AndroidImageSlider Library
21 | POM_ARTIFACT_ID=library
22 | POM_PACKAGING=aar
23 |
--------------------------------------------------------------------------------
/library/proguard-rules.txt:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the ProGuard
5 | # include property in project.properties.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Animations/BaseAnimationInterface.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Animations;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * This interface gives you chance to inject your own animation or do something when the
7 | * {@link com.daimajia.slider.library.Tricks.ViewPagerEx} animation (PagerTransformer) starts or ends.
8 | *
9 | *
10 | * There are two items you have to know. The first item is the slider you are dragging. This item
11 | * I call it Current Item. The second is the slider that gonna to show. I call that Next Item.
12 | *
13 | * When you start to drag the slider in front of you, onPrepareCurrentItemLeaveScreen() and
14 | * onPrepareNextItemShowInScreen will be called.
15 | *
16 | * When you finish drag, the onCurrentItemDisappear and onNextItemAppear will be invoked.
17 | *
18 | * You can see a demo class {@link com.daimajia.slider.library.Animations.DescriptionAnimation},
19 | * this class gives the description text an animation.
20 | */
21 | public interface BaseAnimationInterface {
22 |
23 | /**
24 | * When the current item prepare to start leaving the screen.
25 | * @param current
26 | */
27 | public void onPrepareCurrentItemLeaveScreen(View current);
28 |
29 | /**
30 | * The next item which will be shown in ViewPager/
31 | * @param next
32 | */
33 | public void onPrepareNextItemShowInScreen(View next);
34 |
35 | /**
36 | * Current item totally disappear from screen.
37 | * @param view
38 | */
39 | public void onCurrentItemDisappear(View view);
40 |
41 | /**
42 | * Next item totally show in screen.
43 | * @param view
44 | */
45 | public void onNextItemAppear(View view);
46 | }
47 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Animations/DescriptionAnimation.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Animations;
2 |
3 | import android.view.View;
4 |
5 | import com.daimajia.slider.library.R;
6 | import com.nineoldandroids.animation.ObjectAnimator;
7 | import com.nineoldandroids.animation.ValueAnimator;
8 | import com.nineoldandroids.view.ViewHelper;
9 |
10 | /**
11 | * A demo class to show how to use {@link com.daimajia.slider.library.Animations.BaseAnimationInterface}
12 | * to make your custom animation in {@link com.daimajia.slider.library.Tricks.ViewPagerEx.PageTransformer} action.
13 | */
14 | public class DescriptionAnimation implements BaseAnimationInterface {
15 |
16 | @Override
17 | public void onPrepareCurrentItemLeaveScreen(View current) {
18 | View descriptionLayout = current.findViewById(R.id.description_layout);
19 | if(descriptionLayout!=null){
20 | current.findViewById(R.id.description_layout).setVisibility(View.INVISIBLE);
21 | }
22 | }
23 |
24 | /**
25 | * When next item is coming to show, let's hide the description layout.
26 | * @param next
27 | */
28 | @Override
29 | public void onPrepareNextItemShowInScreen(View next) {
30 | View descriptionLayout = next.findViewById(R.id.description_layout);
31 | if(descriptionLayout!=null){
32 | next.findViewById(R.id.description_layout).setVisibility(View.INVISIBLE);
33 | }
34 | }
35 |
36 |
37 | @Override
38 | public void onCurrentItemDisappear(View view) {
39 |
40 | }
41 |
42 | /**
43 | * When next item show in ViewPagerEx, let's make an animation to show the
44 | * description layout.
45 | * @param view
46 | */
47 | @Override
48 | public void onNextItemAppear(View view) {
49 |
50 | View descriptionLayout = view.findViewById(R.id.description_layout);
51 | if(descriptionLayout!=null){
52 | float layoutY = ViewHelper.getY(descriptionLayout);
53 | view.findViewById(R.id.description_layout).setVisibility(View.VISIBLE);
54 | ValueAnimator animator = ObjectAnimator.ofFloat(
55 | descriptionLayout,"y",layoutY + descriptionLayout.getHeight(),
56 | layoutY).setDuration(500);
57 | animator.start();
58 | }
59 |
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Indicators/PagerIndicator.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Indicators;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.database.DataSetObserver;
6 | import android.graphics.Color;
7 | import android.graphics.drawable.Drawable;
8 | import android.graphics.drawable.GradientDrawable;
9 | import android.graphics.drawable.LayerDrawable;
10 | import android.support.v4.view.PagerAdapter;
11 | import android.util.AttributeSet;
12 | import android.view.View;
13 | import android.widget.ImageView;
14 | import android.widget.LinearLayout;
15 |
16 | import com.daimajia.slider.library.R;
17 | import com.daimajia.slider.library.Tricks.InfinitePagerAdapter;
18 | import com.daimajia.slider.library.Tricks.ViewPagerEx;
19 |
20 | import java.util.ArrayList;
21 |
22 | /**
23 | * Pager Indicator.
24 | */
25 | public class PagerIndicator extends LinearLayout implements ViewPagerEx.OnPageChangeListener{
26 |
27 | private Context mContext;
28 |
29 | /**
30 | * bind this Indicator with {@link com.daimajia.slider.library.Tricks.ViewPagerEx}
31 | */
32 | private ViewPagerEx mPager;
33 |
34 | /**
35 | * Variable to remember the previous selected indicator.
36 | */
37 | private ImageView mPreviousSelectedIndicator;
38 |
39 | /**
40 | * Previous selected indicator position.
41 | */
42 | private int mPreviousSelectedPosition;
43 |
44 | /**
45 | * Custom selected indicator style resource id.
46 | */
47 | private int mUserSetUnSelectedIndicatorResId;
48 |
49 |
50 | /**
51 | * Custom unselected indicator style resource id.
52 | */
53 | private int mUserSetSelectedIndicatorResId;
54 |
55 | private Drawable mSelectedDrawable;
56 | private Drawable mUnselectedDrawable;
57 |
58 | /**
59 | *This value is from {@link com.daimajia.slider.library.SliderAdapter} getRealCount() represent
60 | *
61 | * the indicator count that we should draw.
62 | */
63 | private int mItemCount = 0;
64 |
65 | private Shape mIndicatorShape = Shape.Oval;
66 |
67 | private IndicatorVisibility mVisibility = IndicatorVisibility.Visible;
68 |
69 | private int mDefaultSelectedColor;
70 | private int mDefaultUnSelectedColor;
71 |
72 | private float mDefaultSelectedWidth;
73 | private float mDefaultSelectedHeight;
74 |
75 | private float mDefaultUnSelectedWidth;
76 | private float mDefaultUnSelectedHeight;
77 |
78 | public enum IndicatorVisibility{
79 | Visible,
80 | Invisible;
81 | };
82 |
83 | private GradientDrawable mUnSelectedGradientDrawable;
84 | private GradientDrawable mSelectedGradientDrawable;
85 |
86 | private LayerDrawable mSelectedLayerDrawable;
87 | private LayerDrawable mUnSelectedLayerDrawable;
88 |
89 | private float mPadding_left;
90 | private float mPadding_right;
91 | private float mPadding_top;
92 | private float mPadding_bottom;
93 |
94 | private float mSelectedPadding_Left;
95 | private float mSelectedPadding_Right;
96 | private float mSelectedPadding_Top;
97 | private float mSelectedPadding_Bottom;
98 |
99 | private float mUnSelectedPadding_Left;
100 | private float mUnSelectedPadding_Right;
101 | private float mUnSelectedPadding_Top;
102 | private float mUnSelectedPadding_Bottom;
103 |
104 | /**
105 | * Put all the indicators into a ArrayList, so we can remove them easily.
106 | */
107 | private ArrayList mIndicators = new ArrayList();
108 |
109 |
110 | public PagerIndicator(Context context) {
111 | this(context,null);
112 | }
113 |
114 | public PagerIndicator(Context context, AttributeSet attrs) {
115 | super(context, attrs);
116 |
117 | mContext = context;
118 |
119 | final TypedArray attributes = context.obtainStyledAttributes(attrs,R.styleable.PagerIndicator,0,0);
120 |
121 | int visibility = attributes.getInt(R.styleable.PagerIndicator_visibility,IndicatorVisibility.Visible.ordinal());
122 |
123 | for(IndicatorVisibility v : IndicatorVisibility.values()){
124 | if(v.ordinal() == visibility){
125 | mVisibility = v;
126 | break;
127 | }
128 | }
129 |
130 | int shape = attributes.getInt(R.styleable.PagerIndicator_shape, Shape.Oval.ordinal());
131 | for(Shape s: Shape.values()){
132 | if(s.ordinal() == shape){
133 | mIndicatorShape = s;
134 | break;
135 | }
136 | }
137 |
138 | mUserSetSelectedIndicatorResId = attributes.getResourceId(R.styleable.PagerIndicator_selected_drawable,
139 | 0);
140 | mUserSetUnSelectedIndicatorResId = attributes.getResourceId(R.styleable.PagerIndicator_unselected_drawable,
141 | 0);
142 |
143 | mDefaultSelectedColor = attributes.getColor(R.styleable.PagerIndicator_selected_color, Color.rgb(255, 255, 255));
144 | mDefaultUnSelectedColor = attributes.getColor(R.styleable.PagerIndicator_unselected_color, Color.argb(33,255,255,255));
145 |
146 | mDefaultSelectedWidth = attributes.getDimension(R.styleable.PagerIndicator_selected_width,(int)pxFromDp(6));
147 | mDefaultSelectedHeight = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_selected_height,(int)pxFromDp(6));
148 |
149 | mDefaultUnSelectedWidth = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_unselected_width,(int)pxFromDp(6));
150 | mDefaultUnSelectedHeight = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_unselected_height,(int)pxFromDp(6));
151 |
152 | mSelectedGradientDrawable = new GradientDrawable();
153 | mUnSelectedGradientDrawable = new GradientDrawable();
154 |
155 | mPadding_left = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_left,(int)pxFromDp(3));
156 | mPadding_right = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_right,(int)pxFromDp(3));
157 | mPadding_top = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_top,(int)pxFromDp(0));
158 | mPadding_bottom = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_padding_bottom,(int)pxFromDp(0));
159 |
160 | mSelectedPadding_Left = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_selected_padding_left,(int)mPadding_left);
161 | mSelectedPadding_Right = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_selected_padding_right,(int)mPadding_right);
162 | mSelectedPadding_Top = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_selected_padding_top,(int)mPadding_top);
163 | mSelectedPadding_Bottom = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_selected_padding_bottom,(int)mPadding_bottom);
164 |
165 | mUnSelectedPadding_Left = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_unselected_padding_left,(int)mPadding_left);
166 | mUnSelectedPadding_Right = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_unselected_padding_right,(int)mPadding_right);
167 | mUnSelectedPadding_Top = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_unselected_padding_top,(int)mPadding_top);
168 | mUnSelectedPadding_Bottom = attributes.getDimensionPixelSize(R.styleable.PagerIndicator_unselected_padding_bottom,(int)mPadding_bottom);
169 |
170 | mSelectedLayerDrawable = new LayerDrawable(new Drawable[]{mSelectedGradientDrawable});
171 | mUnSelectedLayerDrawable = new LayerDrawable(new Drawable[]{mUnSelectedGradientDrawable});
172 |
173 |
174 | setIndicatorStyleResource(mUserSetSelectedIndicatorResId,mUserSetUnSelectedIndicatorResId);
175 | setDefaultIndicatorShape(mIndicatorShape);
176 | setDefaultSelectedIndicatorSize(mDefaultSelectedWidth,mDefaultSelectedHeight,Unit.Px);
177 | setDefaultUnselectedIndicatorSize(mDefaultUnSelectedWidth,mDefaultUnSelectedHeight,Unit.Px);
178 | setDefaultIndicatorColor(mDefaultSelectedColor, mDefaultUnSelectedColor);
179 | setIndicatorVisibility(mVisibility);
180 | attributes.recycle();
181 | }
182 |
183 | public enum Shape{
184 | Oval,Rectangle
185 | }
186 |
187 | /**
188 | * if you are using the default indicator, this method will help you to set the shape of
189 | * indicator, there are two kind of shapes you can set, oval and rect.
190 | * @param shape
191 | */
192 | public void setDefaultIndicatorShape(Shape shape){
193 | if(mUserSetSelectedIndicatorResId == 0){
194 | if(shape == Shape.Oval){
195 | mSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
196 | }else{
197 | mSelectedGradientDrawable.setShape(GradientDrawable.RECTANGLE);
198 | }
199 | }
200 | if(mUserSetUnSelectedIndicatorResId == 0){
201 | if(shape == Shape.Oval){
202 | mUnSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
203 | }else{
204 | mUnSelectedGradientDrawable.setShape(GradientDrawable.RECTANGLE);
205 | }
206 | }
207 | resetDrawable();
208 | }
209 |
210 |
211 | /**
212 | * Set Indicator style.
213 | * @param selected page selected drawable
214 | * @param unselected page unselected drawable
215 | */
216 | public void setIndicatorStyleResource(int selected, int unselected){
217 | mUserSetSelectedIndicatorResId = selected;
218 | mUserSetUnSelectedIndicatorResId = unselected;
219 | if(selected == 0){
220 | mSelectedDrawable = mSelectedLayerDrawable;
221 | }else{
222 | mSelectedDrawable = mContext.getResources().getDrawable(mUserSetSelectedIndicatorResId);
223 | }
224 | if(unselected == 0){
225 | mUnselectedDrawable = mUnSelectedLayerDrawable;
226 | }else{
227 | mUnselectedDrawable = mContext.getResources().getDrawable(mUserSetUnSelectedIndicatorResId);
228 | }
229 |
230 | resetDrawable();
231 | }
232 |
233 | /**
234 | * if you are using the default indicator , this method will help you to set the selected status and
235 | * the unselected status color.
236 | * @param selectedColor
237 | * @param unselectedColor
238 | */
239 | public void setDefaultIndicatorColor(int selectedColor,int unselectedColor){
240 | if(mUserSetSelectedIndicatorResId == 0){
241 | mSelectedGradientDrawable.setColor(selectedColor);
242 | }
243 | if(mUserSetUnSelectedIndicatorResId == 0){
244 | mUnSelectedGradientDrawable.setColor(unselectedColor);
245 | }
246 | resetDrawable();
247 | }
248 |
249 | public enum Unit{
250 | DP,Px
251 | }
252 |
253 | public void setDefaultSelectedIndicatorSize(float width,float height,Unit unit){
254 | if(mUserSetSelectedIndicatorResId == 0){
255 | float w = width;
256 | float h = height;
257 | if(unit == Unit.DP){
258 | w = pxFromDp(width);
259 | h = pxFromDp(height);
260 | }
261 | mSelectedGradientDrawable.setSize((int) w, (int) h);
262 | resetDrawable();
263 | }
264 | }
265 |
266 | public void setDefaultUnselectedIndicatorSize(float width,float height,Unit unit){
267 | if(mUserSetUnSelectedIndicatorResId == 0){
268 | float w = width;
269 | float h = height;
270 | if(unit == Unit.DP){
271 | w = pxFromDp(width);
272 | h = pxFromDp(height);
273 | }
274 | mUnSelectedGradientDrawable.setSize((int) w, (int) h);
275 | resetDrawable();
276 | }
277 | }
278 |
279 | public void setDefaultIndicatorSize(float width, float height, Unit unit){
280 | setDefaultSelectedIndicatorSize(width,height,unit);
281 | setDefaultUnselectedIndicatorSize(width,height,unit);
282 | }
283 |
284 | private float dpFromPx(float px)
285 | {
286 | return px / this.getContext().getResources().getDisplayMetrics().density;
287 | }
288 |
289 | private float pxFromDp(float dp)
290 | {
291 | return dp * this.getContext().getResources().getDisplayMetrics().density;
292 | }
293 |
294 | /**
295 | * set the visibility of indicator.
296 | * @param visibility
297 | */
298 | public void setIndicatorVisibility(IndicatorVisibility visibility){
299 | if(visibility == IndicatorVisibility.Visible){
300 | setVisibility(View.VISIBLE);
301 | }else{
302 | setVisibility(View.INVISIBLE);
303 | }
304 | resetDrawable();
305 | }
306 |
307 | /**
308 | * clear self means unregister the dataset observer and remove all the child views(indicators).
309 | */
310 | public void destroySelf(){
311 | if(mPager == null || mPager.getAdapter() == null){
312 | return;
313 | }
314 | InfinitePagerAdapter wrapper = (InfinitePagerAdapter)mPager.getAdapter();
315 | PagerAdapter adapter = wrapper.getRealAdapter();
316 | if(adapter!=null){
317 | adapter.unregisterDataSetObserver(dataChangeObserver);
318 | }
319 | removeAllViews();
320 | }
321 |
322 | /**
323 | * bind indicator with viewpagerEx.
324 | * @param pager
325 | */
326 | public void setViewPager(ViewPagerEx pager){
327 | if(pager.getAdapter() == null){
328 | throw new IllegalStateException("Viewpager does not have adapter instance");
329 | }
330 | mPager = pager;
331 | mPager.addOnPageChangeListener(this);
332 | ((InfinitePagerAdapter)mPager.getAdapter()).getRealAdapter().registerDataSetObserver(dataChangeObserver);
333 | }
334 |
335 |
336 | private void resetDrawable(){
337 | for(View i : mIndicators){
338 | if(mPreviousSelectedIndicator!= null && mPreviousSelectedIndicator.equals(i)){
339 | ((ImageView)i).setImageDrawable(mSelectedDrawable);
340 | }
341 | else{
342 | ((ImageView)i).setImageDrawable(mUnselectedDrawable);
343 | }
344 | }
345 | }
346 |
347 | /**
348 | * redraw the indicators.
349 | */
350 | public void redraw(){
351 | mItemCount = getShouldDrawCount();
352 | mPreviousSelectedIndicator = null;
353 | for(View i:mIndicators){
354 | removeView(i);
355 | }
356 |
357 |
358 | for(int i =0 ;i< mItemCount; i++){
359 | ImageView indicator = new ImageView(mContext);
360 | indicator.setImageDrawable(mUnselectedDrawable);
361 | indicator.setPadding((int)mUnSelectedPadding_Left,
362 | (int)mUnSelectedPadding_Top,
363 | (int)mUnSelectedPadding_Right,
364 | (int)mUnSelectedPadding_Bottom);
365 | addView(indicator);
366 | mIndicators.add(indicator);
367 | }
368 | setItemAsSelected(mPreviousSelectedPosition);
369 | }
370 |
371 | /**
372 | * since we used a adapter wrapper, so we can't getCount directly from wrapper.
373 | * @return
374 | */
375 | private int getShouldDrawCount(){
376 | if(mPager.getAdapter() instanceof InfinitePagerAdapter){
377 | return ((InfinitePagerAdapter)mPager.getAdapter()).getRealCount();
378 | }else{
379 | return mPager.getAdapter().getCount();
380 | }
381 | }
382 |
383 | private DataSetObserver dataChangeObserver = new DataSetObserver() {
384 | @Override
385 | public void onChanged() {
386 | PagerAdapter adapter = mPager.getAdapter();
387 | int count = 0;
388 | if(adapter instanceof InfinitePagerAdapter){
389 | count = ((InfinitePagerAdapter)adapter).getRealCount();
390 | }else{
391 | count = adapter.getCount();
392 | }
393 | if(count > mItemCount){
394 | for(int i =0 ; i< count - mItemCount;i++){
395 | ImageView indicator = new ImageView(mContext);
396 | indicator.setImageDrawable(mUnselectedDrawable);
397 | indicator.setPadding((int)mUnSelectedPadding_Left,
398 | (int)mUnSelectedPadding_Top,
399 | (int)mUnSelectedPadding_Right,
400 | (int)mUnSelectedPadding_Bottom);
401 | addView(indicator);
402 | mIndicators.add(indicator);
403 | }
404 | }else if(count < mItemCount){
405 | for(int i = 0; i < mItemCount - count;i++){
406 | removeView(mIndicators.get(0));
407 | mIndicators.remove(0);
408 | }
409 | }
410 | mItemCount = count;
411 | mPager.setCurrentItem(mItemCount*20 + mPager.getCurrentItem());
412 | }
413 |
414 | @Override
415 | public void onInvalidated() {
416 | super.onInvalidated();
417 | redraw();
418 | }
419 | };
420 |
421 | private void setItemAsSelected(int position){
422 | if(mPreviousSelectedIndicator != null){
423 | mPreviousSelectedIndicator.setImageDrawable(mUnselectedDrawable);
424 | mPreviousSelectedIndicator.setPadding(
425 | (int)mUnSelectedPadding_Left,
426 | (int)mUnSelectedPadding_Top,
427 | (int)mUnSelectedPadding_Right,
428 | (int)mUnSelectedPadding_Bottom
429 | );
430 | }
431 | ImageView currentSelected = (ImageView)getChildAt(position + 1);
432 | if(currentSelected != null){
433 | currentSelected.setImageDrawable(mSelectedDrawable);
434 | currentSelected.setPadding(
435 | (int)mSelectedPadding_Left,
436 | (int)mSelectedPadding_Top,
437 | (int)mSelectedPadding_Right,
438 | (int)mSelectedPadding_Bottom
439 | );
440 | mPreviousSelectedIndicator = currentSelected;
441 | }
442 | mPreviousSelectedPosition = position;
443 | }
444 |
445 | @Override
446 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
447 | }
448 |
449 | public IndicatorVisibility getIndicatorVisibility(){
450 | return mVisibility;
451 | }
452 |
453 | @Override
454 | public void onPageSelected(int position) {
455 | if(mItemCount == 0){
456 | return;
457 | }
458 | setItemAsSelected(position-1);
459 | }
460 | @Override
461 | public void onPageScrollStateChanged(int state) {
462 | }
463 |
464 | public int getSelectedIndicatorResId(){
465 | return mUserSetSelectedIndicatorResId;
466 | }
467 |
468 | public int getUnSelectedIndicatorResId(){
469 | return mUserSetUnSelectedIndicatorResId;
470 | }
471 |
472 | }
473 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/SliderAdapter.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library;
2 |
3 | import android.content.Context;
4 | import android.support.v4.view.PagerAdapter;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import com.daimajia.slider.library.SliderTypes.BaseSliderView;
9 |
10 | import java.util.ArrayList;
11 |
12 | /**
13 | * A slider adapter
14 | */
15 | public class SliderAdapter extends PagerAdapter implements BaseSliderView.ImageLoadListener{
16 |
17 | private Context mContext;
18 | private ArrayList mImageContents;
19 |
20 | public SliderAdapter(Context context){
21 | mContext = context;
22 | mImageContents = new ArrayList();
23 | }
24 |
25 | public void addSlider(T slider){
26 | slider.setOnImageLoadListener(this);
27 | mImageContents.add(slider);
28 | notifyDataSetChanged();
29 | }
30 |
31 | public BaseSliderView getSliderView(int position){
32 | if(position < 0 || position >= mImageContents.size()){
33 | return null;
34 | }else{
35 | return mImageContents.get(position);
36 | }
37 | }
38 |
39 | @Override
40 | public int getItemPosition(Object object) {
41 | return POSITION_NONE;
42 | }
43 |
44 | public void removeSlider(T slider){
45 | if(mImageContents.contains(slider)){
46 | mImageContents.remove(slider);
47 | notifyDataSetChanged();
48 | }
49 | }
50 |
51 | public void removeSliderAt(int position){
52 | if(mImageContents.size() > position){
53 | mImageContents.remove(position);
54 | notifyDataSetChanged();
55 | }
56 | }
57 |
58 | public void removeAllSliders(){
59 | mImageContents.clear();
60 | notifyDataSetChanged();
61 | }
62 |
63 | @Override
64 | public int getCount() {
65 | return mImageContents.size();
66 | }
67 |
68 | @Override
69 | public boolean isViewFromObject(View view, Object object) {
70 | return view==object;
71 | }
72 |
73 | @Override
74 | public void destroyItem(ViewGroup container, int position, Object object) {
75 | container.removeView((View) object);
76 | }
77 |
78 | @Override
79 | public Object instantiateItem(ViewGroup container, int position) {
80 | BaseSliderView b = mImageContents.get(position);
81 | View v = b.getView();
82 | container.addView(v);
83 | return v;
84 | }
85 |
86 | @Override
87 | public void onStart(BaseSliderView target) {
88 |
89 | }
90 |
91 | /**
92 | * When image download error, then remove.
93 | * @param result
94 | * @param target
95 | */
96 | @Override
97 | public void onEnd(boolean result, BaseSliderView target) {
98 | if(target.isErrorDisappear() == false || result == true){
99 | return;
100 | }
101 | for (BaseSliderView slider: mImageContents){
102 | if(slider.equals(target)){
103 | removeSlider(target);
104 | break;
105 | }
106 | }
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/SliderLayout.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.os.Message;
6 | import android.support.v4.view.PagerAdapter;
7 | import android.util.AttributeSet;
8 | import android.view.LayoutInflater;
9 | import android.view.MotionEvent;
10 | import android.view.View;
11 | import android.view.animation.Interpolator;
12 | import android.widget.RelativeLayout;
13 |
14 | import com.daimajia.slider.library.Animations.BaseAnimationInterface;
15 | import com.daimajia.slider.library.Indicators.PagerIndicator;
16 | import com.daimajia.slider.library.SliderTypes.BaseSliderView;
17 | import com.daimajia.slider.library.Transformers.AccordionTransformer;
18 | import com.daimajia.slider.library.Transformers.BackgroundToForegroundTransformer;
19 | import com.daimajia.slider.library.Transformers.BaseTransformer;
20 | import com.daimajia.slider.library.Transformers.CubeInTransformer;
21 | import com.daimajia.slider.library.Transformers.DefaultTransformer;
22 | import com.daimajia.slider.library.Transformers.DepthPageTransformer;
23 | import com.daimajia.slider.library.Transformers.FadeTransformer;
24 | import com.daimajia.slider.library.Transformers.FlipHorizontalTransformer;
25 | import com.daimajia.slider.library.Transformers.FlipPageViewTransformer;
26 | import com.daimajia.slider.library.Transformers.ForegroundToBackgroundTransformer;
27 | import com.daimajia.slider.library.Transformers.RotateDownTransformer;
28 | import com.daimajia.slider.library.Transformers.RotateUpTransformer;
29 | import com.daimajia.slider.library.Transformers.StackTransformer;
30 | import com.daimajia.slider.library.Transformers.TabletTransformer;
31 | import com.daimajia.slider.library.Transformers.ZoomInTransformer;
32 | import com.daimajia.slider.library.Transformers.ZoomOutSlideTransformer;
33 | import com.daimajia.slider.library.Transformers.ZoomOutTransformer;
34 | import com.daimajia.slider.library.Tricks.FixedSpeedScroller;
35 | import com.daimajia.slider.library.Tricks.InfinitePagerAdapter;
36 | import com.daimajia.slider.library.Tricks.InfiniteViewPager;
37 | import com.daimajia.slider.library.Tricks.ViewPagerEx;
38 |
39 | import java.lang.reflect.Field;
40 | import java.util.Timer;
41 | import java.util.TimerTask;
42 |
43 | /**
44 | * SliderLayout is compound layout. This is combined with {@link com.daimajia.slider.library.Indicators.PagerIndicator}
45 | * and {@link com.daimajia.slider.library.Tricks.ViewPagerEx} .
46 | *
47 | * There is some properties you can set in XML:
48 | *
49 | * indicator_visibility
50 | * visible
51 | * invisible
52 | *
53 | * indicator_shape
54 | * oval
55 | * rect
56 | *
57 | * indicator_selected_color
58 | *
59 | * indicator_unselected_color
60 | *
61 | * indicator_selected_drawable
62 | *
63 | * indicator_unselected_drawable
64 | *
65 | * pager_animation
66 | * Default
67 | * Accordion
68 | * Background2Foreground
69 | * CubeIn
70 | * DepthPage
71 | * Fade
72 | * FlipHorizontal
73 | * FlipPage
74 | * Foreground2Background
75 | * RotateDown
76 | * RotateUp
77 | * Stack
78 | * Tablet
79 | * ZoomIn
80 | * ZoomOutSlide
81 | * ZoomOut
82 | *
83 | * pager_animation_span
84 | *
85 | *
86 | */
87 | public class SliderLayout extends RelativeLayout{
88 |
89 | private Context mContext;
90 | /**
91 | * InfiniteViewPager is extended from ViewPagerEx. As the name says, it can scroll without bounder.
92 | */
93 | private InfiniteViewPager mViewPager;
94 |
95 | /**
96 | * InfiniteViewPager adapter.
97 | */
98 | private SliderAdapter mSliderAdapter;
99 |
100 | /**
101 | * {@link com.daimajia.slider.library.Tricks.ViewPagerEx} indicator.
102 | */
103 | private PagerIndicator mIndicator;
104 |
105 |
106 | /**
107 | * A timer and a TimerTask using to cycle the {@link com.daimajia.slider.library.Tricks.ViewPagerEx}.
108 | */
109 | private Timer mCycleTimer;
110 | private TimerTask mCycleTask;
111 |
112 | /**
113 | * For resuming the cycle, after user touch or click the {@link com.daimajia.slider.library.Tricks.ViewPagerEx}.
114 | */
115 | private Timer mResumingTimer;
116 | private TimerTask mResumingTask;
117 |
118 | /**
119 | * If {@link com.daimajia.slider.library.Tricks.ViewPagerEx} is Cycling
120 | */
121 | private boolean mCycling;
122 |
123 | /**
124 | * Determine if auto recover after user touch the {@link com.daimajia.slider.library.Tricks.ViewPagerEx}
125 | */
126 | private boolean mAutoRecover = true;
127 |
128 | private int mTransformerId;
129 |
130 | /**
131 | * {@link com.daimajia.slider.library.Tricks.ViewPagerEx} transformer time span.
132 | */
133 | private int mTransformerSpan = 1100;
134 |
135 | private boolean mAutoCycle;
136 |
137 | /**
138 | * the duration between animation.
139 | */
140 | private long mSliderDuration = 4000;
141 |
142 | /**
143 | * Visibility of {@link com.daimajia.slider.library.Indicators.PagerIndicator}
144 | */
145 | private PagerIndicator.IndicatorVisibility mIndicatorVisibility = PagerIndicator.IndicatorVisibility.Visible;
146 |
147 | /**
148 | * {@link com.daimajia.slider.library.Tricks.ViewPagerEx} 's transformer
149 | */
150 | private BaseTransformer mViewPagerTransformer;
151 |
152 | /**
153 | * @see com.daimajia.slider.library.Animations.BaseAnimationInterface
154 | */
155 | private BaseAnimationInterface mCustomAnimation;
156 |
157 | /**
158 | * {@link com.daimajia.slider.library.Indicators.PagerIndicator} shape, rect or oval.
159 | */
160 |
161 | public SliderLayout(Context context) {
162 | this(context,null);
163 | }
164 |
165 | public SliderLayout(Context context, AttributeSet attrs) {
166 | this(context,attrs,R.attr.SliderStyle);
167 | }
168 |
169 | public SliderLayout(Context context, AttributeSet attrs, int defStyle) {
170 | super(context, attrs, defStyle);
171 | mContext = context;
172 | LayoutInflater.from(context).inflate(R.layout.slider_layout, this, true);
173 |
174 | final TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs,R.styleable.SliderLayout,
175 | defStyle,0);
176 |
177 | mTransformerSpan = attributes.getInteger(R.styleable.SliderLayout_pager_animation_span, 1100);
178 | mTransformerId = attributes.getInt(R.styleable.SliderLayout_pager_animation, Transformer.Default.ordinal());
179 | mAutoCycle = attributes.getBoolean(R.styleable.SliderLayout_auto_cycle,true);
180 | int visibility = attributes.getInt(R.styleable.SliderLayout_indicator_visibility,0);
181 | for(PagerIndicator.IndicatorVisibility v: PagerIndicator.IndicatorVisibility.values()){
182 | if(v.ordinal() == visibility){
183 | mIndicatorVisibility = v;
184 | break;
185 | }
186 | }
187 | mSliderAdapter = new SliderAdapter(mContext);
188 | PagerAdapter wrappedAdapter = new InfinitePagerAdapter(mSliderAdapter);
189 |
190 | mViewPager = (InfiniteViewPager)findViewById(R.id.daimajia_slider_viewpager);
191 | mViewPager.setAdapter(wrappedAdapter);
192 |
193 | mViewPager.setOnTouchListener(new OnTouchListener() {
194 | @Override
195 | public boolean onTouch(View v, MotionEvent event) {
196 | int action = event.getAction();
197 | switch (action) {
198 | case MotionEvent.ACTION_UP:
199 | recoverCycle();
200 | break;
201 | }
202 | return false;
203 | }
204 | });
205 |
206 | attributes.recycle();
207 | setPresetIndicator(PresetIndicators.Center_Bottom);
208 | setPresetTransformer(mTransformerId);
209 | setSliderTransformDuration(mTransformerSpan,null);
210 | setIndicatorVisibility(mIndicatorVisibility);
211 | if(mAutoCycle){
212 | startAutoCycle();
213 | }
214 | }
215 |
216 | public void addOnPageChangeListener(ViewPagerEx.OnPageChangeListener onPageChangeListener){
217 | if(onPageChangeListener != null){
218 | mViewPager.addOnPageChangeListener(onPageChangeListener);
219 | }
220 | }
221 |
222 | public void removeOnPageChangeListener(ViewPagerEx.OnPageChangeListener onPageChangeListener) {
223 | mViewPager.removeOnPageChangeListener(onPageChangeListener);
224 | }
225 |
226 | public void setCustomIndicator(PagerIndicator indicator){
227 | if(mIndicator != null){
228 | mIndicator.destroySelf();
229 | }
230 | mIndicator = indicator;
231 | mIndicator.setIndicatorVisibility(mIndicatorVisibility);
232 | mIndicator.setViewPager(mViewPager);
233 | mIndicator.redraw();
234 | }
235 |
236 | public void addSlider(T imageContent){
237 | mSliderAdapter.addSlider(imageContent);
238 | }
239 |
240 | private android.os.Handler mh = new android.os.Handler(){
241 | @Override
242 | public void handleMessage(Message msg) {
243 | super.handleMessage(msg);
244 | moveNextPosition(true);
245 | }
246 | };
247 |
248 | public void startAutoCycle(){
249 | startAutoCycle(mSliderDuration, mSliderDuration, mAutoRecover);
250 | }
251 |
252 | /**
253 | * start auto cycle.
254 | * @param delay delay time
255 | * @param duration animation duration time.
256 | * @param autoRecover if recover after user touches the slider.
257 | */
258 | public void startAutoCycle(long delay,long duration,boolean autoRecover){
259 | if(mCycleTimer != null) mCycleTimer.cancel();
260 | if(mCycleTask != null) mCycleTask.cancel();
261 | if(mResumingTask != null) mResumingTask.cancel();
262 | if(mResumingTimer != null) mResumingTimer.cancel();
263 | mSliderDuration = duration;
264 | mCycleTimer = new Timer();
265 | mAutoRecover = autoRecover;
266 | mCycleTask = new TimerTask() {
267 | @Override
268 | public void run() {
269 | mh.sendEmptyMessage(0);
270 | }
271 | };
272 | mCycleTimer.schedule(mCycleTask,delay,mSliderDuration);
273 | mCycling = true;
274 | mAutoCycle = true;
275 | }
276 |
277 | /**
278 | * pause auto cycle.
279 | */
280 | private void pauseAutoCycle(){
281 | if(mCycling){
282 | mCycleTimer.cancel();
283 | mCycleTask.cancel();
284 | mCycling = false;
285 | }else{
286 | if(mResumingTimer != null && mResumingTask != null){
287 | recoverCycle();
288 | }
289 | }
290 | }
291 |
292 | /**
293 | * set the duration between two slider changes. the duration value must >= 500
294 | * @param duration
295 | */
296 | public void setDuration(long duration){
297 | if(duration >= 500){
298 | mSliderDuration = duration;
299 | if(mAutoCycle && mCycling){
300 | startAutoCycle();
301 | }
302 | }
303 | }
304 |
305 | /**
306 | * stop the auto circle
307 | */
308 | public void stopAutoCycle(){
309 | if(mCycleTask!=null){
310 | mCycleTask.cancel();
311 | }
312 | if(mCycleTimer!= null){
313 | mCycleTimer.cancel();
314 | }
315 | if(mResumingTimer!= null){
316 | mResumingTimer.cancel();
317 | }
318 | if(mResumingTask!=null){
319 | mResumingTask.cancel();
320 | }
321 | mAutoCycle = false;
322 | mCycling = false;
323 | }
324 |
325 | /**
326 | * when paused cycle, this method can weak it up.
327 | */
328 | private void recoverCycle(){
329 | if(!mAutoRecover || !mAutoCycle){
330 | return;
331 | }
332 |
333 | if(!mCycling){
334 | if(mResumingTask != null && mResumingTimer!= null){
335 | mResumingTimer.cancel();
336 | mResumingTask.cancel();
337 | }
338 | mResumingTimer = new Timer();
339 | mResumingTask = new TimerTask() {
340 | @Override
341 | public void run() {
342 | startAutoCycle();
343 | }
344 | };
345 | mResumingTimer.schedule(mResumingTask, 6000);
346 | }
347 | }
348 |
349 |
350 |
351 | @Override
352 | public boolean onInterceptTouchEvent(MotionEvent ev) {
353 | int action = ev.getAction();
354 | switch (action) {
355 | case MotionEvent.ACTION_DOWN:
356 | pauseAutoCycle();
357 | break;
358 | }
359 | return false;
360 | }
361 |
362 | /**
363 | * set ViewPager transformer.
364 | * @param reverseDrawingOrder
365 | * @param transformer
366 | */
367 | public void setPagerTransformer(boolean reverseDrawingOrder,BaseTransformer transformer){
368 | mViewPagerTransformer = transformer;
369 | mViewPagerTransformer.setCustomAnimationInterface(mCustomAnimation);
370 | mViewPager.setPageTransformer(reverseDrawingOrder,mViewPagerTransformer);
371 | }
372 |
373 |
374 |
375 | /**
376 | * set the duration between two slider changes.
377 | * @param period
378 | * @param interpolator
379 | */
380 | public void setSliderTransformDuration(int period,Interpolator interpolator){
381 | try{
382 | Field mScroller = ViewPagerEx.class.getDeclaredField("mScroller");
383 | mScroller.setAccessible(true);
384 | FixedSpeedScroller scroller = new FixedSpeedScroller(mViewPager.getContext(),interpolator, period);
385 | mScroller.set(mViewPager,scroller);
386 | }catch (Exception e){
387 |
388 | }
389 | }
390 |
391 | /**
392 | * preset transformers and their names
393 | */
394 | public enum Transformer{
395 | Default("Default"),
396 | Accordion("Accordion"),
397 | Background2Foreground("Background2Foreground"),
398 | CubeIn("CubeIn"),
399 | DepthPage("DepthPage"),
400 | Fade("Fade"),
401 | FlipHorizontal("FlipHorizontal"),
402 | FlipPage("FlipPage"),
403 | Foreground2Background("Foreground2Background"),
404 | RotateDown("RotateDown"),
405 | RotateUp("RotateUp"),
406 | Stack("Stack"),
407 | Tablet("Tablet"),
408 | ZoomIn("ZoomIn"),
409 | ZoomOutSlide("ZoomOutSlide"),
410 | ZoomOut("ZoomOut");
411 |
412 | private final String name;
413 |
414 | private Transformer(String s){
415 | name = s;
416 | }
417 | public String toString(){
418 | return name;
419 | }
420 |
421 | public boolean equals(String other){
422 | return (other == null)? false:name.equals(other);
423 | }
424 | };
425 |
426 | /**
427 | * set a preset viewpager transformer by id.
428 | * @param transformerId
429 | */
430 | public void setPresetTransformer(int transformerId){
431 | for(Transformer t : Transformer.values()){
432 | if(t.ordinal() == transformerId){
433 | setPresetTransformer(t);
434 | break;
435 | }
436 | }
437 | }
438 |
439 | /**
440 | * set preset PagerTransformer via the name of transforemer.
441 | * @param transformerName
442 | */
443 | public void setPresetTransformer(String transformerName){
444 | for(Transformer t : Transformer.values()){
445 | if(t.equals(transformerName)){
446 | setPresetTransformer(t);
447 | return;
448 | }
449 | }
450 | }
451 |
452 | /**
453 | * Inject your custom animation into PageTransformer, you can know more details in
454 | * {@link com.daimajia.slider.library.Animations.BaseAnimationInterface},
455 | * and you can see a example in {@link com.daimajia.slider.library.Animations.DescriptionAnimation}
456 | * @param animation
457 | */
458 | public void setCustomAnimation(BaseAnimationInterface animation){
459 | mCustomAnimation = animation;
460 | if(mViewPagerTransformer != null){
461 | mViewPagerTransformer.setCustomAnimationInterface(mCustomAnimation);
462 | }
463 | }
464 |
465 | /**
466 | * pretty much right? enjoy it. :-D
467 | *
468 | * @param ts
469 | */
470 | public void setPresetTransformer(Transformer ts){
471 | //
472 | // special thanks to https://github.com/ToxicBakery/ViewPagerTransforms
473 | //
474 | BaseTransformer t = null;
475 | switch (ts){
476 | case Default:
477 | t = new DefaultTransformer();
478 | break;
479 | case Accordion:
480 | t = new AccordionTransformer();
481 | break;
482 | case Background2Foreground:
483 | t = new BackgroundToForegroundTransformer();
484 | break;
485 | case CubeIn:
486 | t = new CubeInTransformer();
487 | break;
488 | case DepthPage:
489 | t = new DepthPageTransformer();
490 | break;
491 | case Fade:
492 | t = new FadeTransformer();
493 | break;
494 | case FlipHorizontal:
495 | t = new FlipHorizontalTransformer();
496 | break;
497 | case FlipPage:
498 | t = new FlipPageViewTransformer();
499 | break;
500 | case Foreground2Background:
501 | t = new ForegroundToBackgroundTransformer();
502 | break;
503 | case RotateDown:
504 | t = new RotateDownTransformer();
505 | break;
506 | case RotateUp:
507 | t = new RotateUpTransformer();
508 | break;
509 | case Stack:
510 | t = new StackTransformer();
511 | break;
512 | case Tablet:
513 | t = new TabletTransformer();
514 | break;
515 | case ZoomIn:
516 | t = new ZoomInTransformer();
517 | break;
518 | case ZoomOutSlide:
519 | t = new ZoomOutSlideTransformer();
520 | break;
521 | case ZoomOut:
522 | t = new ZoomOutTransformer();
523 | break;
524 | }
525 | setPagerTransformer(true,t);
526 | }
527 |
528 |
529 |
530 | /**
531 | * Set the visibility of the indicators.
532 | * @param visibility
533 | */
534 | public void setIndicatorVisibility(PagerIndicator.IndicatorVisibility visibility){
535 | if(mIndicator == null){
536 | return;
537 | }
538 |
539 | mIndicator.setIndicatorVisibility(visibility);
540 | }
541 |
542 | public PagerIndicator.IndicatorVisibility getIndicatorVisibility(){
543 | if(mIndicator == null){
544 | return mIndicator.getIndicatorVisibility();
545 | }
546 | return PagerIndicator.IndicatorVisibility.Invisible;
547 |
548 | }
549 |
550 | /**
551 | * get the {@link com.daimajia.slider.library.Indicators.PagerIndicator} instance.
552 | * You can manipulate the properties of the indicator.
553 | * @return
554 | */
555 | public PagerIndicator getPagerIndicator(){
556 | return mIndicator;
557 | }
558 |
559 | public enum PresetIndicators{
560 | Center_Bottom("Center_Bottom",R.id.default_center_bottom_indicator),
561 | Right_Bottom("Right_Bottom",R.id.default_bottom_right_indicator),
562 | Left_Bottom("Left_Bottom",R.id.default_bottom_left_indicator),
563 | Center_Top("Center_Top",R.id.default_center_top_indicator),
564 | Right_Top("Right_Top",R.id.default_center_top_right_indicator),
565 | Left_Top("Left_Top",R.id.default_center_top_left_indicator);
566 |
567 | private final String name;
568 | private final int id;
569 | private PresetIndicators(String name,int id){
570 | this.name = name;
571 | this.id = id;
572 | }
573 |
574 | public String toString(){
575 | return name;
576 | }
577 |
578 | public int getResourceId(){
579 | return id;
580 | }
581 | }
582 | public void setPresetIndicator(PresetIndicators presetIndicator){
583 | PagerIndicator pagerIndicator = (PagerIndicator)findViewById(presetIndicator.getResourceId());
584 | setCustomIndicator(pagerIndicator);
585 | }
586 |
587 | private InfinitePagerAdapter getWrapperAdapter(){
588 | PagerAdapter adapter = mViewPager.getAdapter();
589 | if(adapter!=null){
590 | return (InfinitePagerAdapter)adapter;
591 | }else{
592 | return null;
593 | }
594 | }
595 |
596 | private SliderAdapter getRealAdapter(){
597 | PagerAdapter adapter = mViewPager.getAdapter();
598 | if(adapter!=null){
599 | return ((InfinitePagerAdapter)adapter).getRealAdapter();
600 | }
601 | return null;
602 | }
603 |
604 | /**
605 | * get the current item position
606 | * @return
607 | */
608 | public int getCurrentPosition(){
609 |
610 | if(getRealAdapter() == null)
611 | throw new IllegalStateException("You did not set a slider adapter");
612 |
613 | return mViewPager.getCurrentItem() % getRealAdapter().getCount();
614 |
615 | }
616 |
617 | /**
618 | * get current slider.
619 | * @return
620 | */
621 | public BaseSliderView getCurrentSlider(){
622 |
623 | if(getRealAdapter() == null)
624 | throw new IllegalStateException("You did not set a slider adapter");
625 |
626 | int count = getRealAdapter().getCount();
627 | int realCount = mViewPager.getCurrentItem() % count;
628 | return getRealAdapter().getSliderView(realCount);
629 | }
630 |
631 | /**
632 | * remove the slider at the position. Notice: It's a not perfect method, a very small bug still exists.
633 | */
634 | public void removeSliderAt(int position){
635 | if(getRealAdapter()!=null){
636 | getRealAdapter().removeSliderAt(position);
637 | mViewPager.setCurrentItem(mViewPager.getCurrentItem(),false);
638 | }
639 | }
640 |
641 | /**
642 | * remove all the sliders. Notice: It's a not perfect method, a very small bug still exists.
643 | */
644 | public void removeAllSliders(){
645 | if(getRealAdapter()!=null){
646 | int count = getRealAdapter().getCount();
647 | getRealAdapter().removeAllSliders();
648 | //a small bug, but fixed by this trick.
649 | //bug: when remove adapter's all the sliders.some caching slider still alive.
650 | mViewPager.setCurrentItem(mViewPager.getCurrentItem() + count,false);
651 | }
652 | }
653 |
654 | /**
655 | *set current slider
656 | * @param position
657 | */
658 | public void setCurrentPosition(int position, boolean smooth) {
659 | if (getRealAdapter() == null)
660 | throw new IllegalStateException("You did not set a slider adapter");
661 | if(position >= getRealAdapter().getCount()){
662 | throw new IllegalStateException("Item position is not exist");
663 | }
664 | int p = mViewPager.getCurrentItem() % getRealAdapter().getCount();
665 | int n = (position - p) + mViewPager.getCurrentItem();
666 | mViewPager.setCurrentItem(n, smooth);
667 | }
668 |
669 | public void setCurrentPosition(int position) {
670 | setCurrentPosition(position, true);
671 | }
672 |
673 | /**
674 | * move to prev slide.
675 | */
676 | public void movePrevPosition(boolean smooth) {
677 |
678 | if (getRealAdapter() == null)
679 | throw new IllegalStateException("You did not set a slider adapter");
680 |
681 | mViewPager.setCurrentItem(mViewPager.getCurrentItem() - 1, smooth);
682 | }
683 |
684 | public void movePrevPosition(){
685 | movePrevPosition(true);
686 | }
687 |
688 | /**
689 | * move to next slide.
690 | */
691 | public void moveNextPosition(boolean smooth) {
692 |
693 | if (getRealAdapter() == null)
694 | throw new IllegalStateException("You did not set a slider adapter");
695 |
696 | mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1, smooth);
697 | }
698 |
699 | public void moveNextPosition() {
700 | moveNextPosition(true);
701 | }
702 | }
703 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/SliderTypes/BaseSliderView.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.SliderTypes;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.ImageView;
7 |
8 | import com.daimajia.slider.library.R;
9 | import com.squareup.picasso.Callback;
10 | import com.squareup.picasso.Picasso;
11 | import com.squareup.picasso.RequestCreator;
12 |
13 | import java.io.File;
14 |
15 | /**
16 | * When you want to make your own slider view, you must extends from this class.
17 | * BaseSliderView provides some useful methods.
18 | * I provide two example: {@link com.daimajia.slider.library.SliderTypes.DefaultSliderView} and
19 | * {@link com.daimajia.slider.library.SliderTypes.TextSliderView}
20 | * if you want to show progressbar, you just need to set a progressbar id as @+id/loading_bar.
21 | */
22 | public abstract class BaseSliderView {
23 |
24 | protected Context mContext;
25 |
26 | private Bundle mBundle;
27 |
28 | /**
29 | * Error place holder image.
30 | */
31 | private int mErrorPlaceHolderRes;
32 |
33 | /**
34 | * Empty imageView placeholder.
35 | */
36 | private int mEmptyPlaceHolderRes;
37 |
38 | private String mUrl;
39 | private File mFile;
40 | private int mRes;
41 |
42 | protected OnSliderClickListener mOnSliderClickListener;
43 |
44 | private boolean mErrorDisappear;
45 |
46 | private ImageLoadListener mLoadListener;
47 |
48 | private String mDescription;
49 |
50 | private Picasso mPicasso;
51 |
52 | /**
53 | * Scale type of the image.
54 | */
55 | private ScaleType mScaleType = ScaleType.Fit;
56 |
57 | public enum ScaleType{
58 | CenterCrop, CenterInside, Fit, FitCenterCrop
59 | }
60 |
61 | protected BaseSliderView(Context context) {
62 | mContext = context;
63 | }
64 |
65 | /**
66 | * the placeholder image when loading image from url or file.
67 | * @param resId Image resource id
68 | * @return
69 | */
70 | public BaseSliderView empty(int resId){
71 | mEmptyPlaceHolderRes = resId;
72 | return this;
73 | }
74 |
75 | /**
76 | * determine whether remove the image which failed to download or load from file
77 | * @param disappear
78 | * @return
79 | */
80 | public BaseSliderView errorDisappear(boolean disappear){
81 | mErrorDisappear = disappear;
82 | return this;
83 | }
84 |
85 | /**
86 | * if you set errorDisappear false, this will set a error placeholder image.
87 | * @param resId image resource id
88 | * @return
89 | */
90 | public BaseSliderView error(int resId){
91 | mErrorPlaceHolderRes = resId;
92 | return this;
93 | }
94 |
95 | /**
96 | * the description of a slider image.
97 | * @param description
98 | * @return
99 | */
100 | public BaseSliderView description(String description){
101 | mDescription = description;
102 | return this;
103 | }
104 |
105 | /**
106 | * set a url as a image that preparing to load
107 | * @param url
108 | * @return
109 | */
110 | public BaseSliderView image(String url){
111 | if(mFile != null || mRes != 0){
112 | throw new IllegalStateException("Call multi image function," +
113 | "you only have permission to call it once");
114 | }
115 | mUrl = url;
116 | return this;
117 | }
118 |
119 | /**
120 | * set a file as a image that will to load
121 | * @param file
122 | * @return
123 | */
124 | public BaseSliderView image(File file){
125 | if(mUrl != null || mRes != 0){
126 | throw new IllegalStateException("Call multi image function," +
127 | "you only have permission to call it once");
128 | }
129 | mFile = file;
130 | return this;
131 | }
132 |
133 | public BaseSliderView image(int res){
134 | if(mUrl != null || mFile != null){
135 | throw new IllegalStateException("Call multi image function," +
136 | "you only have permission to call it once");
137 | }
138 | mRes = res;
139 | return this;
140 | }
141 |
142 | /**
143 | * lets users add a bundle of additional information
144 | * @param bundle
145 | * @return
146 | */
147 | public BaseSliderView bundle(Bundle bundle){
148 | mBundle = bundle;
149 | return this;
150 | }
151 |
152 | public String getUrl(){
153 | return mUrl;
154 | }
155 |
156 | public boolean isErrorDisappear(){
157 | return mErrorDisappear;
158 | }
159 |
160 | public int getEmpty(){
161 | return mEmptyPlaceHolderRes;
162 | }
163 |
164 | public int getError(){
165 | return mErrorPlaceHolderRes;
166 | }
167 |
168 | public String getDescription(){
169 | return mDescription;
170 | }
171 |
172 | public Context getContext(){
173 | return mContext;
174 | }
175 |
176 | /**
177 | * set a slider image click listener
178 | * @param l
179 | * @return
180 | */
181 | public BaseSliderView setOnSliderClickListener(OnSliderClickListener l){
182 | mOnSliderClickListener = l;
183 | return this;
184 | }
185 |
186 | /**
187 | * When you want to implement your own slider view, please call this method in the end in `getView()` method
188 | * @param v the whole view
189 | * @param targetImageView where to place image
190 | */
191 | protected void bindEventAndShow(final View v, ImageView targetImageView){
192 | final BaseSliderView me = this;
193 |
194 | v.setOnClickListener(new View.OnClickListener() {
195 | @Override
196 | public void onClick(View v) {
197 | if(mOnSliderClickListener != null){
198 | mOnSliderClickListener.onSliderClick(me);
199 | }
200 | }
201 | });
202 |
203 | if (targetImageView == null)
204 | return;
205 |
206 | if (mLoadListener != null) {
207 | mLoadListener.onStart(me);
208 | }
209 |
210 | Picasso p = (mPicasso != null) ? mPicasso : Picasso.with(mContext);
211 | RequestCreator rq = null;
212 | if(mUrl!=null){
213 | rq = p.load(mUrl);
214 | }else if(mFile != null){
215 | rq = p.load(mFile);
216 | }else if(mRes != 0){
217 | rq = p.load(mRes);
218 | }else{
219 | return;
220 | }
221 |
222 | if(rq == null){
223 | return;
224 | }
225 |
226 | if(getEmpty() != 0){
227 | rq.placeholder(getEmpty());
228 | }
229 |
230 | if(getError() != 0){
231 | rq.error(getError());
232 | }
233 |
234 | switch (mScaleType){
235 | case Fit:
236 | rq.fit();
237 | break;
238 | case CenterCrop:
239 | rq.fit().centerCrop();
240 | break;
241 | case CenterInside:
242 | rq.fit().centerInside();
243 | break;
244 | }
245 |
246 | rq.into(targetImageView,new Callback() {
247 | @Override
248 | public void onSuccess() {
249 | if(v.findViewById(R.id.loading_bar) != null){
250 | v.findViewById(R.id.loading_bar).setVisibility(View.INVISIBLE);
251 | }
252 | }
253 |
254 | @Override
255 | public void onError() {
256 | if(mLoadListener != null){
257 | mLoadListener.onEnd(false,me);
258 | }
259 | if(v.findViewById(R.id.loading_bar) != null){
260 | v.findViewById(R.id.loading_bar).setVisibility(View.INVISIBLE);
261 | }
262 | }
263 | });
264 | }
265 |
266 |
267 |
268 | public BaseSliderView setScaleType(ScaleType type){
269 | mScaleType = type;
270 | return this;
271 | }
272 |
273 | public ScaleType getScaleType(){
274 | return mScaleType;
275 | }
276 |
277 | /**
278 | * the extended class have to implement getView(), which is called by the adapter,
279 | * every extended class response to render their own view.
280 | * @return
281 | */
282 | public abstract View getView();
283 |
284 | /**
285 | * set a listener to get a message , if load error.
286 | * @param l
287 | */
288 | public void setOnImageLoadListener(ImageLoadListener l){
289 | mLoadListener = l;
290 | }
291 |
292 | public interface OnSliderClickListener {
293 | public void onSliderClick(BaseSliderView slider);
294 | }
295 |
296 | /**
297 | * when you have some extra information, please put it in this bundle.
298 | * @return
299 | */
300 | public Bundle getBundle(){
301 | return mBundle;
302 | }
303 |
304 | public interface ImageLoadListener{
305 | public void onStart(BaseSliderView target);
306 | public void onEnd(boolean result,BaseSliderView target);
307 | }
308 |
309 | /**
310 | * Get the last instance set via setPicasso(), or null if no user provided instance was set
311 | *
312 | * @return The current user-provided Picasso instance, or null if none
313 | */
314 | public Picasso getPicasso() {
315 | return mPicasso;
316 | }
317 |
318 | /**
319 | * Provide a Picasso instance to use when loading pictures, this is useful if you have a
320 | * particular HTTP cache you would like to share.
321 | *
322 | * @param picasso The Picasso instance to use, may be null to let the system use the default
323 | * instance
324 | */
325 | public void setPicasso(Picasso picasso) {
326 | mPicasso = picasso;
327 | }
328 | }
329 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/SliderTypes/DefaultSliderView.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.SliderTypes;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.widget.ImageView;
7 |
8 | import com.daimajia.slider.library.R;
9 |
10 | /**
11 | * a simple slider view, which just show an image. If you want to make your own slider view,
12 | *
13 | * just extend BaseSliderView, and implement getView() method.
14 | */
15 | public class DefaultSliderView extends BaseSliderView{
16 |
17 | public DefaultSliderView(Context context) {
18 | super(context);
19 | }
20 |
21 | @Override
22 | public View getView() {
23 | View v = LayoutInflater.from(getContext()).inflate(R.layout.render_type_default,null);
24 | ImageView target = (ImageView)v.findViewById(R.id.daimajia_slider_image);
25 | bindEventAndShow(v, target);
26 | return v;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/SliderTypes/TextSliderView.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.SliderTypes;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import com.daimajia.slider.library.R;
10 |
11 | /**
12 | * This is a slider with a description TextView.
13 | */
14 | public class TextSliderView extends BaseSliderView{
15 | public TextSliderView(Context context) {
16 | super(context);
17 | }
18 |
19 | @Override
20 | public View getView() {
21 | View v = LayoutInflater.from(getContext()).inflate(R.layout.render_type_text,null);
22 | ImageView target = (ImageView)v.findViewById(R.id.daimajia_slider_image);
23 | TextView description = (TextView)v.findViewById(R.id.description);
24 | description.setText(getDescription());
25 | bindEventAndShow(v, target);
26 | return v;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/AccordionTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | /**
4 | * Created by daimajia on 14-5-29.
5 | */
6 | import android.view.View;
7 |
8 | import com.nineoldandroids.view.ViewHelper;
9 |
10 | public class AccordionTransformer extends BaseTransformer {
11 |
12 | @Override
13 | protected void onTransform(View view, float position) {
14 | ViewHelper.setPivotX(view,position < 0 ? 0 : view.getWidth());
15 | ViewHelper.setScaleX(view,position < 0 ? 1f + position : 1f - position);
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/BackgroundToForegroundTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class BackgroundToForegroundTransformer extends BaseTransformer {
8 |
9 | @Override
10 | protected void onTransform(View view, float position) {
11 | final float height = view.getHeight();
12 | final float width = view.getWidth();
13 | final float scale = min(position < 0 ? 1f : Math.abs(1f - position), 0.5f);
14 |
15 | ViewHelper.setScaleX(view,scale);
16 | ViewHelper.setScaleY(view,scale);
17 | ViewHelper.setPivotX(view,width*0.5f);
18 | ViewHelper.setPivotY(view,height*0.5f);
19 | ViewHelper.setTranslationX(view,position < 0 ? width * position : -width * position * 0.25f);
20 | }
21 |
22 | private static final float min(float val, float min) {
23 | return val < min ? min : val;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/BaseTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.daimajia.slider.library.Animations.BaseAnimationInterface;
6 | import com.daimajia.slider.library.Tricks.ViewPagerEx;
7 | import com.nineoldandroids.view.ViewHelper;
8 |
9 | import java.util.ArrayList;
10 | import java.util.HashMap;
11 |
12 | /**
13 | * This is all transformers father.
14 | *
15 | * BaseTransformer implement {@link com.daimajia.slider.library.Tricks.ViewPagerEx.PageTransformer}
16 | * which is just same as {@link android.support.v4.view.ViewPager.PageTransformer}.
17 | *
18 | * After you call setPageTransformer(), transformPage() will be called by {@link com.daimajia.slider.library.Tricks.ViewPagerEx}
19 | * when your slider are animating.
20 | *
21 | * In onPreTransform() function, that will make {@link com.daimajia.slider.library.Animations.BaseAnimationInterface}
22 | * work.
23 | *
24 | * if you want to make an acceptable transformer, please do not forget to extend from this class.
25 | */
26 | public abstract class BaseTransformer implements ViewPagerEx.PageTransformer {
27 |
28 | private BaseAnimationInterface mCustomAnimationInterface;
29 |
30 | /**
31 | * Called each {@link #transformPage(View, float)}.
32 | *
33 | * @param view
34 | * @param position
35 | */
36 | protected abstract void onTransform(View view, float position);
37 |
38 | private HashMap> h = new HashMap>();
39 |
40 | @Override
41 | public void transformPage(View view, float position) {
42 | onPreTransform(view, position);
43 | onTransform(view, position);
44 | onPostTransform(view, position);
45 | }
46 |
47 | /**
48 | * If the position offset of a fragment is less than negative one or greater than one, returning true will set the
49 | * visibility of the fragment to {@link View#GONE}. Returning false will force the fragment to {@link View#VISIBLE}.
50 | *
51 | * @return
52 | */
53 | protected boolean hideOffscreenPages() {
54 | return true;
55 | }
56 |
57 | /**
58 | * Indicates if the default animations of the view pager should be used.
59 | *
60 | * @return
61 | */
62 | protected boolean isPagingEnabled() {
63 | return false;
64 | }
65 |
66 | /**
67 | * Called each {@link #transformPage(View, float)} before {{@link #onTransform(View, float)} is called.
68 | *
69 | * @param view
70 | * @param position
71 | */
72 | protected void onPreTransform(View view, float position) {
73 | final float width = view.getWidth();
74 |
75 | ViewHelper.setRotationX(view,0);
76 | ViewHelper.setRotationY(view,0);
77 | ViewHelper.setRotation(view,0);
78 | ViewHelper.setScaleX(view,1);
79 | ViewHelper.setScaleY(view,1);
80 | ViewHelper.setPivotX(view,0);
81 | ViewHelper.setPivotY(view,0);
82 | ViewHelper.setTranslationY(view,0);
83 | ViewHelper.setTranslationX(view,isPagingEnabled() ? 0f : -width * position);
84 |
85 | if (hideOffscreenPages()) {
86 | ViewHelper.setAlpha(view,position <= -1f || position >= 1f ? 0f : 1f);
87 | } else {
88 | ViewHelper.setAlpha(view,1f);
89 | }
90 | if(mCustomAnimationInterface != null){
91 | if(h.containsKey(view) == false || h.get(view).size() == 1){
92 | if(position > -1 && position < 1){
93 | if(h.get(view) == null){
94 | h.put(view,new ArrayList());
95 | }
96 | h.get(view).add(position);
97 | if(h.get(view).size() == 2){
98 | float zero = h.get(view).get(0);
99 | float cha = h.get(view).get(1) - h.get(view).get(0);
100 | if(zero > 0){
101 | if(cha > -1 && cha < 0){
102 | //in
103 | mCustomAnimationInterface.onPrepareNextItemShowInScreen(view);
104 | }else{
105 | //out
106 | mCustomAnimationInterface.onPrepareCurrentItemLeaveScreen(view);
107 | }
108 | }else{
109 | if(cha > -1 && cha < 0){
110 | //out
111 | mCustomAnimationInterface.onPrepareCurrentItemLeaveScreen(view);
112 | }else{
113 | //in
114 | mCustomAnimationInterface.onPrepareNextItemShowInScreen(view);
115 | }
116 | }
117 | }
118 | }
119 | }
120 | }
121 | }
122 | boolean isApp,isDis;
123 | /**
124 | * Called each {@link #transformPage(View, float)} call after {@link #onTransform(View, float)} is finished.
125 | *
126 | * @param view
127 | * @param position
128 | */
129 | protected void onPostTransform(View view, float position) {
130 | if(mCustomAnimationInterface != null){
131 | if(position == -1 || position == 1){
132 | mCustomAnimationInterface.onCurrentItemDisappear(view);
133 | isApp = true;
134 | }else if(position == 0){
135 | mCustomAnimationInterface.onNextItemAppear(view);
136 | isDis = true;
137 | }
138 | if(isApp && isDis){
139 | h.clear();
140 | isApp = false;
141 | isDis = false;
142 | }
143 | }
144 | }
145 |
146 |
147 | public void setCustomAnimationInterface(BaseAnimationInterface animationInterface){
148 | mCustomAnimationInterface = animationInterface;
149 | }
150 |
151 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/CubeInTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class CubeInTransformer extends BaseTransformer {
8 |
9 | @Override
10 | protected void onTransform(View view, float position) {
11 | // Rotate the fragment on the left or right edge
12 | ViewHelper.setPivotX(view,position > 0 ? 0 : view.getWidth());
13 | ViewHelper.setPivotY(view,0);
14 | ViewHelper.setRotation(view,-90f * position);
15 | }
16 |
17 | @Override
18 | public boolean isPagingEnabled() {
19 | return true;
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/DefaultTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | public class DefaultTransformer extends BaseTransformer {
6 |
7 | @Override
8 | protected void onTransform(View view, float position) {
9 | }
10 |
11 | @Override
12 | public boolean isPagingEnabled() {
13 | return true;
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/DepthPageTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class DepthPageTransformer extends BaseTransformer {
8 |
9 | private static final float MIN_SCALE = 0.75f;
10 |
11 | @Override
12 | protected void onTransform(View view, float position) {
13 | if (position <= 0f) {
14 | ViewHelper.setTranslationX(view,0f);
15 | ViewHelper.setScaleX(view,1f);
16 | ViewHelper.setScaleY(view,1f);
17 | } else if (position <= 1f) {
18 | final float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
19 | ViewHelper.setAlpha(view,1-position);
20 | ViewHelper.setPivotY(view,0.5f * view.getHeight());
21 | ViewHelper.setTranslationX(view,view.getWidth() * - position);
22 | ViewHelper.setScaleX(view,scaleFactor);
23 | ViewHelper.setScaleY(view,scaleFactor);
24 | }
25 | }
26 |
27 | @Override
28 | protected boolean isPagingEnabled() {
29 | return true;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/FadeTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | /**
8 | * Created by realandylawton on 11/22/13.
9 | */
10 | public class FadeTransformer extends BaseTransformer {
11 |
12 | @Override
13 | protected void onTransform(View view, float position) {
14 |
15 | // Page is not an immediate sibling, just make transparent
16 | if(position < -1 || position > 1) {
17 | ViewHelper.setAlpha(view,0.6f);
18 | }
19 | // Page is sibling to left or right
20 | else if (position <= 0 || position <= 1) {
21 |
22 | // Calculate alpha. Position is decimal in [-1,0] or [0,1]
23 | float alpha = (position <= 0) ? position + 1 : 1 - position;
24 | ViewHelper.setAlpha(view,alpha);
25 |
26 | }
27 | // Page is active, make fully visible
28 | else if (position == 0) {
29 | ViewHelper.setAlpha(view,1);
30 | }
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/FlipHorizontalTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class FlipHorizontalTransformer extends BaseTransformer {
8 |
9 | @Override
10 | protected void onTransform(View view, float position) {
11 | final float rotation = 180f * position;
12 | ViewHelper.setAlpha(view,rotation > 90f || rotation < -90f ? 0 : 1);
13 | ViewHelper.setPivotY(view,view.getHeight()*0.5f);
14 | ViewHelper.setPivotX(view,view.getWidth() * 0.5f);
15 | ViewHelper.setRotationY(view,rotation);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/FlipPageViewTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.os.Build;
4 | import android.view.View;
5 |
6 | import com.daimajia.slider.library.Tricks.ViewPagerEx;
7 | import com.nineoldandroids.view.ViewHelper;
8 |
9 | public class FlipPageViewTransformer extends BaseTransformer {
10 |
11 | @Override
12 | protected void onTransform(View view, float position) {
13 | float percentage = 1 - Math.abs(position);
14 | if(Build.VERSION.SDK_INT >= 13){
15 | view.setCameraDistance(12000);
16 | }
17 | setVisibility(view, position);
18 | setTranslation(view);
19 | setSize(view, position, percentage);
20 | setRotation(view, position, percentage);
21 | }
22 |
23 | private void setVisibility(View page, float position) {
24 | if (position < 0.5 && position > -0.5) {
25 | page.setVisibility(View.VISIBLE);
26 | } else {
27 | page.setVisibility(View.INVISIBLE);
28 | }
29 | }
30 |
31 | private void setTranslation(View view) {
32 | ViewPagerEx viewPager = (ViewPagerEx) view.getParent();
33 | int scroll = viewPager.getScrollX() - view.getLeft();
34 | ViewHelper.setTranslationX(view,scroll);
35 | }
36 |
37 | private void setSize(View view, float position, float percentage) {
38 | ViewHelper.setScaleX(view,(position != 0 && position != 1) ? percentage : 1);
39 | ViewHelper.setScaleY(view,(position != 0 && position != 1) ? percentage : 1);
40 | }
41 |
42 | private void setRotation(View view, float position, float percentage) {
43 | if (position > 0) {
44 | ViewHelper.setRotationY(view,-180 * (percentage + 1));
45 | } else {
46 | ViewHelper.setRotationY(view,180 * (percentage + 1));
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/ForegroundToBackgroundTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class ForegroundToBackgroundTransformer extends BaseTransformer {
8 |
9 | @Override
10 | protected void onTransform(View view, float position) {
11 | final float height = view.getHeight();
12 | final float width = view.getWidth();
13 | final float scale = min(position > 0 ? 1f : Math.abs(1f + position), 0.5f);
14 |
15 | ViewHelper.setScaleX(view,scale);
16 | ViewHelper.setScaleY(view,scale);
17 | ViewHelper.setPivotX(view,width * 0.5f);
18 | ViewHelper.setPivotY(view,height * 0.5f);
19 | ViewHelper.setTranslationX(view,position > 0 ? width * position : -width * position * 0.25f);
20 | }
21 |
22 | private static final float min(float val, float min) {
23 | return val < min ? min : val;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/RotateDownTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class RotateDownTransformer extends BaseTransformer {
8 |
9 | private static final float ROT_MOD = -15f;
10 |
11 | @Override
12 | protected void onTransform(View view, float position) {
13 | final float width = view.getWidth();
14 | final float height = view.getHeight();
15 | final float rotation = ROT_MOD * position * -1.25f;
16 |
17 | ViewHelper.setPivotX(view,width * 0.5f);
18 | ViewHelper.setPivotY(view,height);
19 | ViewHelper.setRotation(view,rotation);
20 | }
21 |
22 | @Override
23 | protected boolean isPagingEnabled() {
24 | return true;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/RotateUpTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class RotateUpTransformer extends BaseTransformer {
8 |
9 | private static final float ROT_MOD = -15f;
10 |
11 | @Override
12 | protected void onTransform(View view, float position) {
13 | final float width = view.getWidth();
14 | final float rotation = ROT_MOD * position;
15 |
16 | ViewHelper.setPivotX(view,width * 0.5f);
17 | ViewHelper.setPivotY(view,0f);
18 | ViewHelper.setTranslationX(view,0f);
19 | ViewHelper.setRotation(view,rotation);
20 | }
21 |
22 | @Override
23 | protected boolean isPagingEnabled() {
24 | return true;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/StackTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class StackTransformer extends BaseTransformer {
8 |
9 | @Override
10 | protected void onTransform(View view, float position) {
11 | ViewHelper.setTranslationX(view,position < 0 ? 0f : -view.getWidth() * position);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/TabletTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.graphics.Camera;
4 | import android.graphics.Matrix;
5 | import android.view.View;
6 |
7 | import com.nineoldandroids.view.ViewHelper;
8 |
9 | public class TabletTransformer extends BaseTransformer {
10 |
11 | private static final Matrix OFFSET_MATRIX = new Matrix();
12 | private static final Camera OFFSET_CAMERA = new Camera();
13 | private static final float[] OFFSET_TEMP_FLOAT = new float[2];
14 |
15 | @Override
16 | protected void onTransform(View view, float position) {
17 | final float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);
18 |
19 | ViewHelper.setTranslationX(view,getOffsetXForRotation(rotation, view.getWidth(), view.getHeight()));
20 | ViewHelper.setPivotX(view,view.getWidth() * 0.5f);
21 | ViewHelper.setPivotY(view,0);
22 | ViewHelper.setRotationY(view,rotation);
23 | }
24 |
25 | protected static final float getOffsetXForRotation(float degrees, int width, int height) {
26 | OFFSET_MATRIX.reset();
27 | OFFSET_CAMERA.save();
28 | OFFSET_CAMERA.rotateY(Math.abs(degrees));
29 | OFFSET_CAMERA.getMatrix(OFFSET_MATRIX);
30 | OFFSET_CAMERA.restore();
31 |
32 | OFFSET_MATRIX.preTranslate(-width * 0.5f, -height * 0.5f);
33 | OFFSET_MATRIX.postTranslate(width * 0.5f, height * 0.5f);
34 | OFFSET_TEMP_FLOAT[0] = width;
35 | OFFSET_TEMP_FLOAT[1] = height;
36 | OFFSET_MATRIX.mapPoints(OFFSET_TEMP_FLOAT);
37 | return (width - OFFSET_TEMP_FLOAT[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomInTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class ZoomInTransformer extends BaseTransformer {
8 |
9 | @Override
10 | protected void onTransform(View view, float position) {
11 | final float scale = position < 0 ? position + 1f : Math.abs(1f - position);
12 | ViewHelper.setScaleX(view,scale);
13 | ViewHelper.setScaleY(view,scale);
14 | ViewHelper.setPivotX(view,view.getWidth() * 0.5f);
15 | ViewHelper.setPivotY(view,view.getHeight() * 0.5f);
16 | ViewHelper.setAlpha(view,position < -1f || position > 1f ? 0f : 1f - (scale - 1f));
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomOutSlideTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class ZoomOutSlideTransformer extends BaseTransformer {
8 |
9 | private static final float MIN_SCALE = 0.85f;
10 | private static final float MIN_ALPHA = 0.5f;
11 |
12 | @Override
13 | protected void onTransform(View view, float position) {
14 | if (position >= -1 || position <= 1) {
15 | // Modify the default slide transition to shrink the page as well
16 | final float height = view.getHeight();
17 | final float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
18 | final float vertMargin = height * (1 - scaleFactor) / 2;
19 | final float horzMargin = view.getWidth() * (1 - scaleFactor) / 2;
20 |
21 | // Center vertically
22 | ViewHelper.setPivotY(view,0.5f * height);
23 |
24 |
25 | if (position < 0) {
26 | ViewHelper.setTranslationX(view,horzMargin - vertMargin / 2);
27 | } else {
28 | ViewHelper.setTranslationX(view,-horzMargin + vertMargin / 2);
29 | }
30 |
31 | // Scale the page down (between MIN_SCALE and 1)
32 | ViewHelper.setScaleX(view,scaleFactor);
33 | ViewHelper.setScaleY(view,scaleFactor);
34 |
35 | // Fade the page relative to its size.
36 | ViewHelper.setAlpha(view,MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Transformers/ZoomOutTransformer.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Transformers;
2 |
3 | import android.view.View;
4 |
5 | import com.nineoldandroids.view.ViewHelper;
6 |
7 | public class ZoomOutTransformer extends BaseTransformer {
8 |
9 | @Override
10 | protected void onTransform(View view, float position) {
11 | final float scale = 1f + Math.abs(position);
12 | ViewHelper.setScaleX(view,scale);
13 | ViewHelper.setScaleY(view,scale);
14 | ViewHelper.setPivotX(view,view.getWidth() * 0.5f);
15 | ViewHelper.setPivotY(view,view.getWidth() * 0.5f);
16 | ViewHelper.setAlpha(view,position < -1f || position > 1f ? 0f : 1f - (scale - 1f));
17 | if(position < -0.9){
18 | //-0.9 to prevent a small bug
19 | ViewHelper.setTranslationX(view,view.getWidth() * position);
20 | }
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Tricks/FixedSpeedScroller.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Tricks;
2 |
3 | import android.content.Context;
4 | import android.view.animation.Interpolator;
5 | import android.widget.Scroller;
6 |
7 | public class FixedSpeedScroller extends Scroller {
8 |
9 | private int mDuration = 1000;
10 |
11 | public FixedSpeedScroller(Context context) {
12 | super(context);
13 | }
14 |
15 | public FixedSpeedScroller(Context context, Interpolator interpolator) {
16 | super(context, interpolator);
17 | }
18 |
19 | public FixedSpeedScroller(Context context, Interpolator interpolator, int period){
20 | this(context,interpolator);
21 | mDuration = period;
22 | }
23 |
24 | @Override
25 | public void startScroll(int startX, int startY, int dx, int dy, int duration) {
26 | // Ignore received duration, use fixed one instead
27 | super.startScroll(startX, startY, dx, dy, mDuration);
28 | }
29 |
30 | @Override
31 | public void startScroll(int startX, int startY, int dx, int dy) {
32 | // Ignore received duration, use fixed one instead
33 | super.startScroll(startX, startY, dx, dy, mDuration);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Tricks/InfinitePagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Tricks;
2 |
3 | import android.os.Parcelable;
4 | import android.support.v4.view.PagerAdapter;
5 | import android.util.Log;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.daimajia.slider.library.SliderAdapter;
10 |
11 | /**
12 | * A PagerAdapter that wraps around another PagerAdapter to handle paging wrap-around.
13 | * Thanks to: https://github.com/antonyt/InfiniteViewPager
14 | */
15 | public class InfinitePagerAdapter extends PagerAdapter {
16 |
17 | private static final String TAG = "InfinitePagerAdapter";
18 | private static final boolean DEBUG = false;
19 |
20 | private SliderAdapter adapter;
21 |
22 | public InfinitePagerAdapter(SliderAdapter adapter) {
23 | this.adapter = adapter;
24 | }
25 |
26 | public SliderAdapter getRealAdapter(){
27 | return this.adapter;
28 | }
29 |
30 | @Override
31 | public int getCount() {
32 | // warning: scrolling to very high values (1,000,000+) results in
33 | // strange drawing behaviour
34 | return Integer.MAX_VALUE;
35 | }
36 |
37 | /**
38 | * @return the {@link #getCount()} result of the wrapped adapter
39 | */
40 | public int getRealCount() {
41 | return adapter.getCount();
42 | }
43 |
44 | @Override
45 | public Object instantiateItem(ViewGroup container, int position) {
46 | if(getRealCount() == 0){
47 | return null;
48 | }
49 | int virtualPosition = position % getRealCount();
50 | debug("instantiateItem: real position: " + position);
51 | debug("instantiateItem: virtual position: " + virtualPosition);
52 |
53 | // only expose virtual position to the inner adapter
54 | return adapter.instantiateItem(container, virtualPosition);
55 | }
56 |
57 | @Override
58 | public void destroyItem(ViewGroup container, int position, Object object) {
59 | if(getRealCount() == 0){
60 | return;
61 | }
62 | int virtualPosition = position % getRealCount();
63 | debug("destroyItem: real position: " + position);
64 | debug("destroyItem: virtual position: " + virtualPosition);
65 |
66 | // only expose virtual position to the inner adapter
67 | adapter.destroyItem(container, virtualPosition, object);
68 | }
69 |
70 | /*
71 | * Delegate rest of methods directly to the inner adapter.
72 | */
73 |
74 | @Override
75 | public void finishUpdate(ViewGroup container) {
76 | adapter.finishUpdate(container);
77 | }
78 |
79 | @Override
80 | public boolean isViewFromObject(View view, Object object) {
81 | return adapter.isViewFromObject(view, object);
82 | }
83 |
84 | @Override
85 | public void restoreState(Parcelable bundle, ClassLoader classLoader) {
86 | adapter.restoreState(bundle, classLoader);
87 | }
88 |
89 | @Override
90 | public Parcelable saveState() {
91 | return adapter.saveState();
92 | }
93 |
94 | @Override
95 | public void startUpdate(ViewGroup container) {
96 | adapter.startUpdate(container);
97 | }
98 |
99 | /*
100 | * End delegation
101 | */
102 |
103 | private void debug(String message) {
104 | if (DEBUG) {
105 | Log.d(TAG, message);
106 | }
107 | }
108 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/daimajia/slider/library/Tricks/InfiniteViewPager.java:
--------------------------------------------------------------------------------
1 | package com.daimajia.slider.library.Tricks;
2 |
3 | import android.content.Context;
4 | import android.support.v4.view.PagerAdapter;
5 | import android.support.v4.view.ViewPager;
6 | import android.util.AttributeSet;
7 |
8 | /**
9 | * A {@link ViewPager} that allows pseudo-infinite paging with a wrap-around effect. Should be used with an {@link
10 | * InfinitePagerAdapter}.
11 | */
12 | public class InfiniteViewPager extends ViewPagerEx {
13 |
14 | public InfiniteViewPager(Context context) {
15 | super(context);
16 | }
17 |
18 | public InfiniteViewPager(Context context, AttributeSet attrs) {
19 | super(context, attrs);
20 | }
21 |
22 | @Override
23 | public void setAdapter(PagerAdapter adapter) {
24 | super.setAdapter(adapter);
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/library/src/main/res/drawable/indicator_corner_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/indicator_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/render_type_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
14 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/render_type_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
14 |
24 |
29 |
30 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/slider_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
11 |
20 |
29 |
38 |
46 |
55 |
64 |
--------------------------------------------------------------------------------
/library/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Default
16 | Accordion
17 | Background2Foreground
18 | CubeIn
19 | DepthPage
20 | Fade
21 | FlipHorizontal
22 | FlipPage
23 | Foreground2Background
24 | RotateDown
25 | RotateUp
26 | Stack
27 | Tablet
28 | ZoomIn
29 | ZoomOutSlide
30 | ZoomOut
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Slider
3 |
4 |
--------------------------------------------------------------------------------
/library/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
24 |
43 |
44 |
63 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':demo', ':library'
2 |
--------------------------------------------------------------------------------