Repository: saeedsh92/Banner-Slider
Branch: master
Commit: 291e18d5a629
Files: 59
Total size: 86.1 KB
Directory structure:
gitextract_3qbqixxs/
├── .gitignore
├── README.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ ├── java/
│ │ └── ss/
│ │ └── com/
│ │ └── bannerslidersample/
│ │ ├── MainActivity.java
│ │ ├── MainSliderAdapter.java
│ │ └── PicassoImageLoadingService.java
│ └── res/
│ ├── drawable-xxhdpi/
│ │ ├── selected_slide_indicator.xml
│ │ └── unselected_slide_indicator.xml
│ ├── layout/
│ │ ├── activity_main.xml
│ │ └── layout_empty_view.xml
│ ├── values/
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── values-w820dp/
│ └── dimens.xml
├── bannerslider/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ ├── java/
│ │ └── ss/
│ │ └── com/
│ │ └── bannerslider/
│ │ ├── Config.java
│ │ ├── ImageLoadingService.java
│ │ ├── SlideIndicatorsGroup.java
│ │ ├── SlideType.java
│ │ ├── Slider.java
│ │ ├── SsSnapHelper.java
│ │ ├── adapters/
│ │ │ ├── PositionController.java
│ │ │ ├── SliderAdapter.java
│ │ │ └── SliderRecyclerViewAdapter.java
│ │ ├── event/
│ │ │ ├── OnSlideChangeListener.java
│ │ │ └── OnSlideClickListener.java
│ │ ├── indicators/
│ │ │ ├── CircleIndicator.java
│ │ │ ├── DashIndicator.java
│ │ │ ├── IndicatorShape.java
│ │ │ ├── RoundSquareIndicator.java
│ │ │ └── SquareIndicator.java
│ │ └── viewholder/
│ │ └── ImageSlideViewHolder.java
│ └── res/
│ ├── drawable/
│ │ ├── indicator_circle_selected.xml
│ │ ├── indicator_circle_unselected.xml
│ │ ├── indicator_dash_selected.xml
│ │ ├── indicator_dash_unselected.xml
│ │ ├── indicator_round_square_selected.xml
│ │ ├── indicator_round_square_unselected.xml
│ │ ├── indicator_square_selected.xml
│ │ └── indicator_square_unselected.xml
│ ├── layout/
│ │ └── item_slide_image.xml
│ └── values/
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ └── strings.xml
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
.DS_Store
/build
/captures
.externalNativeBuild
/.idea
================================================
FILE: README.md
================================================
# Deprecated
### I created this project in 2016. many things have changed and there are many other new great alternatives for creating sliders in android. so I decided to deprecate banner-slider.
# Banner-Slider
Banner slider is an easy to use library for making beautiful sliders in your android app.
## How to download
### Gradle
add this line to your module build.gradle dependecies block:
compile 'com.ss.bannerslider:bannerslider:2.0.0'
### Maven
com.ss.bannerslider
bannerslider
2.0.0
pom
## How use this library
### XML
```xml
```
### Java
### Step 1: extend SliderAdapter
in first step you must create an adapter to adapt your data model with slides. example implemented adapter with 3 slides:
```java
public class MainSliderAdapter extends SliderAdapter {
@Override
public int getItemCount() {
return 3;
}
@Override
public void onBindImageSlide(int position, ImageSlideViewHolder viewHolder) {
switch (position) {
case 0:
viewHolder.bindImageSlide("https://assets.materialup.com/uploads/dcc07ea4-845a-463b-b5f0-4696574da5ed/preview.jpg");
break;
case 1:
viewHolder.bindImageSlide("https://assets.materialup.com/uploads/20ded50d-cc85-4e72-9ce3-452671cf7a6d/preview.jpg");
break;
case 2:
viewHolder.bindImageSlide("https://assets.materialup.com/uploads/76d63bbc-54a1-450a-a462-d90056be881b/preview.png");
break;
}
}
}
```
### Step 2: specify your image loading service
you must specify image loading service for loading images(for better flexibility and prevent adding unnecessary libraries).
for example if you work with picasso for loading images in your project, you must implement ImageLoadingService interface like below:
```java
public class PicassoImageLoadingService implements ImageLoadingService {
public Context context;
public PicassoImageLoadingService(Context context) {
this.context = context;
}
@Override
public void loadImage(String url, ImageView imageView) {
Picasso.with(context).load(url).into(imageView);
}
@Override
public void loadImage(int resource, ImageView imageView) {
Picasso.with(context).load(resource).into(imageView);
}
@Override
public void loadImage(String url, int placeHolder, int errorDrawable, ImageView imageView) {
Picasso.with(context).load(url).placeholder(placeHolder).error(errorDrawable).into(imageView);
}
}
```
### Step 3: initialize slider in your Application class
```java
Slider.init(YOUR IMAGE LOADING SERVICE);
```
### Step 4: set your adapter on slider
```java
slider = findViewById(R.id.banner_slider1);
slider.setAdapter(new MainSliderAdapter());
```
## You want more customization?
#### Changing slides automatically in specifed periods
interval attribute get miliseconds.
```xml
app:slider_interval="5000"
```
#### Loop slides
```xml
app:slider_loopSlides="true"
```
#### Choose default banner to show up first
```java
slider.setSelectedSlide(2);
```
you must pass banner position to it:
```xml
app:slider_defaultBanner="1"
```
#### Enable/disable indicators animations
in default, animations are enabled
```xml
app:slider_animateIndicators="true"
```
#### Use custom Indicators
if you also set default indicators, then this attributes will ignored
```xml
app:slider_selectedSlideIndicator="@drawable/selected_slide_indicator"
app:slider_unselectedSlideIndicator="@drawable/unselected_slide_indicator"
```
#### How set empty view, when banners not received from server yet?
```xml
app:slider_emptyView="@layout/layout_empty_view"
```
#### Change indicator sizes
```xml
app:slider_indicatorSize="12dp"
```
#### Set OnBannerClickListener
```java
slider.setOnSlideClickListener(new OnSlideClickListener() {
@Override
public void onSlideClick(int position) {
//Do what you want
}
});
});
```
## Licence
Copyright 2016 Saeed Shahini
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
## Author
Saeed shahini
email: saeedshahiniit@gmail.com
github: https://github.com/saeedsh92
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "ss.com.bannerslidersample"
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation project(':bannerslider')
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support:support-vector-drawable:26.1.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.android.support:cardview-v7:26.0.0-alpha1'
implementation 'com.android.support:customtabs:26.0.0-alpha1'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/saeed/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
================================================
FILE: app/src/main/java/ss/com/bannerslidersample/MainActivity.java
================================================
package ss.com.bannerslidersample;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.customtabs.CustomTabsIntent;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SwitchCompat;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Spinner;
import ss.com.bannerslider.Slider;
import ss.com.bannerslider.indicators.IndicatorShape;
public class MainActivity extends AppCompatActivity {
private Slider slider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Slider.init(new PicassoImageLoadingService(this));
setupViews();
}
private void setupViews() {
setupToolbar();
setupPageIndicatorChooser();
setupSettingsUi();
slider = findViewById(R.id.banner_slider1);
//delay for testing empty view functionality
slider.postDelayed(new Runnable() {
@Override
public void run() {
slider.setAdapter(new MainSliderAdapter());
slider.setSelectedSlide(0);
}
}, 1500);
}
private void setupSettingsUi() {
final SeekBar intervalSeekBar = findViewById(R.id.seekbar_interval);
intervalSeekBar.setMax(10000);
intervalSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (b) {
slider.setInterval(i);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
SeekBar indicatorSizeSeekBar = findViewById(R.id.seekbar_indicator_size);
indicatorSizeSeekBar.setMax(getResources().getDimensionPixelSize(R.dimen.max_slider_indicator_size));
indicatorSizeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if (b) {
slider.setIndicatorSize(i);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
SwitchCompat loopSlidesSwitch = findViewById(R.id.checkbox_loop_slides);
loopSlidesSwitch.setChecked(true);
SwitchCompat mustAnimateIndicators = findViewById(R.id.checkbox_animate_indicators);
mustAnimateIndicators.setChecked(true);
loopSlidesSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
slider.setLoopSlides(b);
}
});
mustAnimateIndicators.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
slider.setAnimateIndicators(b);
}
});
SwitchCompat hideIndicatorsSwitch = findViewById(R.id.checkbox_hide_indicators);
hideIndicatorsSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
slider.hideIndicators();
} else {
slider.showIndicators();
}
}
});
}
private void setupToolbar() {
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ImageView githubSourceImageView = findViewById(R.id.image_github);
githubSourceImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Uri uri = Uri.parse("https://github.com/saeedsh92/Banner-Slider");
if (Build.VERSION.SDK_INT > 15) {
CustomTabsIntent.Builder intentBuilder = new CustomTabsIntent.Builder();
intentBuilder.setToolbarColor(ContextCompat.getColor(MainActivity.this, R.color.colorPrimary));
intentBuilder.setSecondaryToolbarColor(ContextCompat.getColor(MainActivity.this, R.color.colorPrimaryDark));
intentBuilder.setStartAnimations(MainActivity.this, android.R.anim.fade_in, android.R.anim.fade_out);
intentBuilder.setExitAnimations(MainActivity.this, android.R.anim.fade_in, android.R.anim.fade_out);
CustomTabsIntent customTabsIntent = intentBuilder.build();
customTabsIntent.launchUrl(MainActivity.this, uri);
} else {
startActivity(Intent.createChooser(new Intent(Intent.ACTION_VIEW, uri), "Choose Browser..."));
}
}
});
}
private void setupPageIndicatorChooser() {
String[] pageIndicatorsLabels = getResources().getStringArray(R.array.page_indicators);
ArrayAdapter arrayAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_dropdown_item,
pageIndicatorsLabels
);
Spinner spinner = findViewById(R.id.spinner_page_indicator);
spinner.setAdapter(arrayAdapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> adapterView, View view, int i, long l) {
switch (i) {
case 0:
slider.setIndicatorStyle(IndicatorShape.CIRCLE);
break;
case 1:
slider.setIndicatorStyle(IndicatorShape.DASH);
break;
case 2:
slider.setIndicatorStyle(IndicatorShape.ROUND_SQUARE);
break;
case 3:
slider.setIndicatorStyle(IndicatorShape.SQUARE);
break;
case 4:
slider.setSelectedSlideIndicator(ContextCompat.getDrawable(MainActivity.this, R.drawable.selected_slide_indicator));
slider.setUnSelectedSlideIndicator(ContextCompat.getDrawable(MainActivity.this, R.drawable.unselected_slide_indicator));
break;
}
}
@Override
public void onNothingSelected(AdapterView> adapterView) {
}
});
}
}
================================================
FILE: app/src/main/java/ss/com/bannerslidersample/MainSliderAdapter.java
================================================
package ss.com.bannerslidersample;
import ss.com.bannerslider.SlideType;
import ss.com.bannerslider.adapters.SliderAdapter;
import ss.com.bannerslider.viewholder.ImageSlideViewHolder;
/**
* @author S.Shahini
* @since 2/12/18
*/
public class MainSliderAdapter extends SliderAdapter {
@Override
public int getItemCount() {
return 3;
}
@Override
public void onBindImageSlide(int position, ImageSlideViewHolder viewHolder) {
switch (position) {
case 0:
viewHolder.bindImageSlide("https://assets.materialup.com/uploads/dcc07ea4-845a-463b-b5f0-4696574da5ed/preview.jpg");
break;
case 1:
viewHolder.bindImageSlide("https://assets.materialup.com/uploads/20ded50d-cc85-4e72-9ce3-452671cf7a6d/preview.jpg");
break;
case 2:
viewHolder.bindImageSlide("https://assets.materialup.com/uploads/76d63bbc-54a1-450a-a462-d90056be881b/preview.png");
break;
}
}
}
================================================
FILE: app/src/main/java/ss/com/bannerslidersample/PicassoImageLoadingService.java
================================================
package ss.com.bannerslidersample;
import android.content.Context;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import ss.com.bannerslider.ImageLoadingService;
/**
* @author S.Shahini
* @since 4/7/18
*/
public class PicassoImageLoadingService implements ImageLoadingService {
public Context context;
public PicassoImageLoadingService(Context context) {
this.context = context;
}
@Override
public void loadImage(String url, ImageView imageView) {
Picasso.with(context).load(url).into(imageView);
}
@Override
public void loadImage(int resource, ImageView imageView) {
Picasso.with(context).load(resource).into(imageView);
}
@Override
public void loadImage(String url, int placeHolder, int errorDrawable, ImageView imageView) {
Picasso.with(context).load(url).placeholder(placeHolder).error(errorDrawable).into(imageView);
}
}
================================================
FILE: app/src/main/res/drawable-xxhdpi/selected_slide_indicator.xml
================================================
================================================
FILE: app/src/main/res/drawable-xxhdpi/unselected_slide_indicator.xml
================================================
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
================================================
FILE: app/src/main/res/layout/layout_empty_view.xml
================================================
================================================
FILE: app/src/main/res/values/colors.xml
================================================
#fff
#aaaaaa
#2facb2
#eeee
#717171
================================================
FILE: app/src/main/res/values/dimens.xml
================================================
16dp
16dp
8dp
16dp
20dp
================================================
FILE: app/src/main/res/values/strings.xml
================================================
BannerSliderSample
This Is Empty View
Interval:
Indicator size:
Animate indicators:
Hide Indicators
Loop slides:
- Circle
- Dash
- Round Square
- Square
- Custom
================================================
FILE: app/src/main/res/values/styles.xml
================================================
================================================
FILE: app/src/main/res/values-w820dp/dimens.xml
================================================
64dp
================================================
FILE: bannerslider/.gitignore
================================================
/build
================================================
FILE: bannerslider/build.gradle
================================================
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 10
versionName "2.0.0"
group = 'com.ss.bannerslider'
version = '2.0.0'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'com.android.support:recyclerview-v7:26.1.0'
}
================================================
FILE: bannerslider/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/saeed/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: bannerslider/src/main/AndroidManifest.xml
================================================
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/Config.java
================================================
package ss.com.bannerslider;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
/**
* @author S.Shahini
* @since 3/5/18
*/
public class Config {
public static final int NOT_SELECTED = -1;
protected boolean hideIndicators = false;
protected boolean loopSlides = true;
protected int indicatorSize = NOT_SELECTED;
protected Drawable selectedSlideIndicator;
protected Drawable unselectedSlideIndicator;
protected boolean animateIndicators = true;
protected int slideChangeInterval = 0;
protected int emptyView = NOT_SELECTED;
private Config() {
}
public static class Builder {
private Config config = new Config();
private Context context;
public Builder(Context context) {
this.context = context.getApplicationContext();
}
public Builder hideIndicators(boolean hideIndicators) {
config.hideIndicators = hideIndicators;
return this;
}
public Builder loopSlides(boolean loopSlides) {
config.loopSlides = loopSlides;
return this;
}
public Builder indicatorSize(int indicatorSize) {
config.indicatorSize = indicatorSize;
return this;
}
public Builder selectedSlideIndicator(Drawable selectedSlideIndicator) {
config.selectedSlideIndicator = selectedSlideIndicator;
return this;
}
public Builder unselectedSlideIndicator(Drawable unselectedSlideIndicator) {
config.unselectedSlideIndicator = unselectedSlideIndicator;
return this;
}
public Builder animateIndicators(boolean animateIndicators) {
config.animateIndicators = animateIndicators;
return this;
}
public Builder slideChangeInterval(int slideChangeInterval) {
config.slideChangeInterval = slideChangeInterval;
return this;
}
public Builder emptyView(int emptyView) {
config.emptyView = emptyView;
return this;
}
public Config build() {
if (config.selectedSlideIndicator == null) {
config.selectedSlideIndicator = ContextCompat.getDrawable(context, R.drawable.indicator_circle_selected);
}
if (config.unselectedSlideIndicator == null) {
config.unselectedSlideIndicator = ContextCompat.getDrawable(context, R.drawable.indicator_circle_unselected);
}
if (config.indicatorSize == NOT_SELECTED) {
config.indicatorSize = context.getResources().getDimensionPixelSize(R.dimen.default_indicator_size);
}
return config;
}
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/ImageLoadingService.java
================================================
package ss.com.bannerslider;
import android.support.annotation.DrawableRes;
import android.widget.ImageView;
/**
* @author S.Shahini
* @since 4/4/18
*/
public interface ImageLoadingService {
void loadImage(String url, ImageView imageView);
void loadImage(@DrawableRes int resource, ImageView imageView);
void loadImage(String url, @DrawableRes int placeHolder, @DrawableRes int errorDrawable, ImageView imageView);
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/SlideIndicatorsGroup.java
================================================
package ss.com.bannerslider;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
import ss.com.bannerslider.event.OnSlideChangeListener;
import ss.com.bannerslider.indicators.CircleIndicator;
import ss.com.bannerslider.indicators.DashIndicator;
import ss.com.bannerslider.indicators.IndicatorShape;
import ss.com.bannerslider.indicators.RoundSquareIndicator;
import ss.com.bannerslider.indicators.SquareIndicator;
/**
* @author S.Shahini
* @since 11/26/16
*/
class SlideIndicatorsGroup extends LinearLayout implements OnSlideChangeListener {
private static final String TAG = "SlideIndicatorsGroup";
private final Context context;
private int slidesCount;
private Drawable selectedSlideIndicator;
private Drawable unselectedSlideIndicator;
private int defaultIndicator;
private int indicatorSize;
private boolean mustAnimateIndicators = true;
private List indicatorShapes = new ArrayList<>();
public SlideIndicatorsGroup(Context context, Drawable selectedSlideIndicator, Drawable unselectedSlideIndicator, int defaultIndicator, int indicatorSize, boolean mustAnimateIndicators) {
super(context);
this.context = context;
this.selectedSlideIndicator = selectedSlideIndicator;
this.unselectedSlideIndicator = unselectedSlideIndicator;
this.defaultIndicator = defaultIndicator;
this.indicatorSize = indicatorSize;
this.mustAnimateIndicators = mustAnimateIndicators;
setup();
}
public void setSlides(int slidesCount) {
removeAllViews();
indicatorShapes.clear();
this.slidesCount = 0;
for (int i = 0; i < slidesCount; i++) {
onSlideAdd();
}
this.slidesCount = slidesCount;
}
public void onSlideAdd() {
this.slidesCount += 1;
addIndicator();
}
private void addIndicator() {
IndicatorShape indicatorShape;
if (selectedSlideIndicator != null && unselectedSlideIndicator != null) {
indicatorShape = new IndicatorShape(context, indicatorSize, mustAnimateIndicators) {
@Override
public void onCheckedChange(boolean isChecked) {
super.onCheckedChange(isChecked);
if (isChecked) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(selectedSlideIndicator);
} else {
setBackgroundDrawable(selectedSlideIndicator);
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(unselectedSlideIndicator);
} else {
setBackgroundDrawable(unselectedSlideIndicator);
}
}
}
};
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
indicatorShape.setBackground(unselectedSlideIndicator);
} else {
indicatorShape.setBackgroundDrawable(unselectedSlideIndicator);
}
indicatorShapes.add(indicatorShape);
addView(indicatorShape);
} else {
switch (defaultIndicator) {
case IndicatorShape.SQUARE:
indicatorShape = new SquareIndicator(context, indicatorSize, mustAnimateIndicators);
indicatorShapes.add(indicatorShape);
addView(indicatorShape);
break;
case IndicatorShape.ROUND_SQUARE:
indicatorShape = new RoundSquareIndicator(context, indicatorSize, mustAnimateIndicators);
indicatorShapes.add(indicatorShape);
addView(indicatorShape);
break;
case IndicatorShape.DASH:
indicatorShape = new DashIndicator(context, indicatorSize, mustAnimateIndicators);
indicatorShapes.add(indicatorShape);
addView(indicatorShape);
break;
case IndicatorShape.CIRCLE:
indicatorShape = new CircleIndicator(context, indicatorSize, mustAnimateIndicators);
indicatorShapes.add(indicatorShape);
addView(indicatorShape);
break;
default:
break;
}
}
}
public void setup() {
setOrientation(LinearLayout.HORIZONTAL);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
int margin = getResources().getDimensionPixelSize(R.dimen.default_indicator_margins) * 2;
layoutParams.setMargins(0, 0, 0, margin);
setLayoutParams(layoutParams);
}
@Override
public void onSlideChange(int selectedSlidePosition) {
Log.i(TAG, "onSlideChange: "+selectedSlidePosition);
for (int i = 0; i < indicatorShapes.size(); i++) {
if (i == selectedSlidePosition) {
indicatorShapes.get(i).onCheckedChange(true);
} else {
indicatorShapes.get(i).onCheckedChange(false);
}
}
}
public void setMustAnimateIndicators(boolean shouldAnimate) {
this.mustAnimateIndicators = shouldAnimate;
for (IndicatorShape indicatorShape :
indicatorShapes) {
indicatorShape.setMustAnimateChange(shouldAnimate);
}
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/SlideType.java
================================================
package ss.com.bannerslider;
public enum SlideType {
//Custom,Video And Gif Slides will add in future
IMAGE(0);
private final int value;
SlideType(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/Slider.java
================================================
package ss.com.bannerslider;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import java.util.Timer;
import java.util.TimerTask;
import ss.com.bannerslider.adapters.PositionController;
import ss.com.bannerslider.adapters.SliderAdapter;
import ss.com.bannerslider.adapters.SliderRecyclerViewAdapter;
import ss.com.bannerslider.event.OnSlideChangeListener;
import ss.com.bannerslider.event.OnSlideClickListener;
import ss.com.bannerslider.indicators.IndicatorShape;
/**
* @author S.Shahini
* @since 12/16/17
*/
public class Slider extends FrameLayout {
private static final String TAG = "Slider";
public OnSlideChangeListener onSlideChangeListener;
public OnSlideClickListener onSlideClickListener;
public RecyclerView recyclerView;
public SliderRecyclerViewAdapter adapter;
public SlideIndicatorsGroup slideIndicatorsGroup;
public int pendingPosition = RecyclerView.NO_POSITION;
public SliderAdapter sliderAdapter;
public Config config;
public int selectedSlidePosition = 0;
public Timer timer;
public PositionController positionController;
public static ImageLoadingService imageLoadingService;
private View emptyView;
public Slider(@NonNull Context context) {
super(context);
setupViews(null);
}
public Slider(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
setupViews(attrs);
}
public Slider(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setupViews(attrs);
}
private void setupViews(AttributeSet attributeSet) {
if (attributeSet != null) {
TypedArray typedArray = getContext().obtainStyledAttributes(attributeSet, R.styleable.Slider);
try {
config = new Config.Builder(getContext())
.animateIndicators(typedArray.getBoolean(R.styleable.Slider_slider_animateIndicators, true))
.emptyView(typedArray.getResourceId(R.styleable.Slider_slider_emptyView, Config.NOT_SELECTED))
.indicatorSize(typedArray.getDimensionPixelSize(R.styleable.Slider_slider_indicatorSize, 0))
.loopSlides(typedArray.getBoolean(R.styleable.Slider_slider_loopSlides, false))
.slideChangeInterval(typedArray.getInteger(R.styleable.Slider_slider_interval, 0))
.selectedSlideIndicator(typedArray.getDrawable(R.styleable.Slider_slider_selectedSlideIndicator))
.unselectedSlideIndicator(typedArray.getDrawable(R.styleable.Slider_slider_unselectedSlideIndicator))
.hideIndicators(typedArray.getBoolean(R.styleable.Slider_slider_hideIndicators, false))
.build();
} catch (Exception e) {
Log.e("Slider", "setupViews: ".toString());
} finally {
typedArray.recycle();
}
} else {
config = new Config.Builder(getContext()).build();
}
setupRv();
setupSlideIndicator();
}
private void setupRv() {
recyclerView = new RecyclerView(getContext());
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (!config.loopSlides) return;
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (selectedSlidePosition == 0) {
recyclerView.scrollToPosition(adapter.getItemCount() - 2);
onImageSlideChange(adapter.getItemCount() - 2);
} else if (selectedSlidePosition == adapter.getItemCount() - 1) {
recyclerView.scrollToPosition(1);
onImageSlideChange(1);
}
}
}
});
if (config.emptyView != Config.NOT_SELECTED) {
emptyView = LayoutInflater.from(getContext()).inflate(config.emptyView, this, false);
addView(emptyView);
}
}
private void setupSlideIndicator() {
if (!config.hideIndicators) {
slideIndicatorsGroup = new SlideIndicatorsGroup(getContext(),
config.selectedSlideIndicator,
config.unselectedSlideIndicator,
0,
config.indicatorSize,
config.animateIndicators);
}
}
public void onImageSlideChange(int position) {
Log.d(TAG, "onImageSlideChange() called with: position = [" + position + "]");
selectedSlidePosition = position;
int userSlidePosition = positionController.getUserSlidePosition(position);
if (slideIndicatorsGroup != null)
slideIndicatorsGroup.onSlideChange(userSlidePosition);
if (onSlideChangeListener != null) {
onSlideChangeListener.onSlideChange(userSlidePosition);
}
}
public void setSelectedSlide(int position, boolean animate) {
if (recyclerView != null && recyclerView.getAdapter() != null) {
if (animate) {
recyclerView.smoothScrollToPosition(position);
} else {
recyclerView.scrollToPosition(position);
}
onImageSlideChange(position);
} else {
pendingPosition = position;
}
}
public void setSelectedSlide(int position) {
setSelectedSlide(positionController.getRealSlidePosition(position), true);
}
private void onAdapterAttached() {
if (pendingPosition != RecyclerView.NO_POSITION) {
recyclerView.smoothScrollToPosition(pendingPosition);
onImageSlideChange(pendingPosition);
pendingPosition = RecyclerView.NO_POSITION;
}
}
public void setSlideChangeListener(OnSlideChangeListener onSlideChangeListener) {
this.onSlideChangeListener = onSlideChangeListener;
}
public void setOnSlideClickListener(OnSlideClickListener onSlideClickListener) {
this.onSlideClickListener = onSlideClickListener;
if (adapter != null)
adapter.setOnSlideClickListener(onSlideClickListener);
}
public SliderAdapter getAdapter() {
return this.sliderAdapter;
}
public void setAdapter(SliderAdapter sliderAdapter) {
if (sliderAdapter != null && recyclerView != null) {
this.sliderAdapter = sliderAdapter;
if (indexOfChild(recyclerView) == -1) {
if (getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) {
recyclerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
} else {
recyclerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
addView(recyclerView);
}
recyclerView.setNestedScrollingEnabled(false);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
positionController = new PositionController(sliderAdapter, config.loopSlides);
adapter = new SliderRecyclerViewAdapter(sliderAdapter, sliderAdapter.getItemCount() > 1 && config.loopSlides, recyclerView.getLayoutParams(), new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
stopTimer();
} else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
startTimer();
}
return false;
}
}, positionController);
recyclerView.setAdapter(adapter);
positionController.setRecyclerViewAdapter(adapter);
//Show default selected slide
selectedSlidePosition = config.loopSlides ? 1 : 0;
recyclerView.scrollToPosition(selectedSlidePosition);
onImageSlideChange(selectedSlidePosition);
pendingPosition = RecyclerView.NO_POSITION;
onAdapterAttached();
SsSnapHelper snapHelper = new SsSnapHelper(new SsSnapHelper.OnSelectedItemChange() {
@Override
public void onSelectedItemChange(int position) {
onImageSlideChange(position);
}
});
recyclerView.setOnFlingListener(null);
snapHelper.attachToRecyclerView(recyclerView);
if (slideIndicatorsGroup != null && sliderAdapter.getItemCount() > 1) {
if (indexOfChild(slideIndicatorsGroup) == -1) {
addView(slideIndicatorsGroup);
}
slideIndicatorsGroup.setSlides(sliderAdapter.getItemCount());
slideIndicatorsGroup.onSlideChange(0);
}
if (emptyView != null) {
emptyView.setVisibility(GONE);
}
}
}
public Config getConfig() {
return this.config;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
startTimer();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
stopTimer();
}
private void startTimer() {
if (config.slideChangeInterval > 0) {
stopTimer();
timer = new Timer();
timer.schedule(new SliderTimerTask(), config.slideChangeInterval, config.slideChangeInterval);
}
}
private void stopTimer() {
if (timer != null) {
timer.cancel();
timer.purge();
}
}
public static void init(ImageLoadingService imageLoadingService) {
Slider.imageLoadingService = imageLoadingService;
}
public static ImageLoadingService getImageLoadingService() {
if (imageLoadingService == null) {
throw new IllegalStateException("ImageLoadingService is null, you should call init method first");
}
return imageLoadingService;
}
private class SliderTimerTask extends TimerTask {
@Override
public void run() {
if (getContext() instanceof Activity) {
((Activity) getContext()).runOnUiThread(new Runnable() {
@Override
public void run() {
int nextSlidePosition = positionController.getNextSlide(selectedSlidePosition);
recyclerView.smoothScrollToPosition(nextSlidePosition);
onImageSlideChange(nextSlidePosition);
}
});
}
}
}
public void setInterval(int interval) {
config.slideChangeInterval = interval;
stopTimer();
startTimer();
}
public void setLoopSlides(boolean loopSlides) {
config.loopSlides = loopSlides;
adapter.setLoop(loopSlides);
positionController.setLoop(loopSlides);
adapter.notifyDataSetChanged();
recyclerView.scrollToPosition(loopSlides ? 1 : 0);
onImageSlideChange(loopSlides ? 1 : 0);
}
public void setAnimateIndicators(boolean shouldAnimate) {
config.animateIndicators = shouldAnimate;
if (slideIndicatorsGroup != null)
slideIndicatorsGroup.setMustAnimateIndicators(shouldAnimate);
}
public void hideIndicators() {
config.hideIndicators = true;
if (slideIndicatorsGroup != null)
slideIndicatorsGroup.setVisibility(GONE);
}
public void showIndicators() {
config.hideIndicators = false;
if (slideIndicatorsGroup != null)
slideIndicatorsGroup.setVisibility(VISIBLE);
}
public void setIndicatorSize(int indicatorSize) {
config.indicatorSize = indicatorSize;
refreshIndicators();
}
public void setSelectedSlideIndicator(Drawable selectedSlideIndicator) {
config.selectedSlideIndicator = selectedSlideIndicator;
refreshIndicators();
}
public void setUnSelectedSlideIndicator(Drawable unSelectedSlideIndicator) {
config.unselectedSlideIndicator = unSelectedSlideIndicator;
refreshIndicators();
}
private void refreshIndicators() {
if (!config.hideIndicators && sliderAdapter != null) {
if (slideIndicatorsGroup != null) {
removeView(slideIndicatorsGroup);
}
slideIndicatorsGroup = new SlideIndicatorsGroup(getContext(), config.selectedSlideIndicator, config.unselectedSlideIndicator, 0, config.indicatorSize, config.animateIndicators);
addView(slideIndicatorsGroup);
for (int i = 0; i < sliderAdapter.getItemCount(); i++) {
slideIndicatorsGroup.onSlideAdd();
}
}
}
public void setIndicatorStyle(int indicatorStyle) {
switch (indicatorStyle) {
case IndicatorShape.CIRCLE:
config.selectedSlideIndicator = ContextCompat.getDrawable(getContext(), R.drawable.indicator_circle_selected);
config.unselectedSlideIndicator = ContextCompat.getDrawable(getContext(), R.drawable.indicator_circle_unselected);
break;
case IndicatorShape.SQUARE:
config.selectedSlideIndicator = ContextCompat.getDrawable(getContext(), R.drawable.indicator_square_selected);
config.unselectedSlideIndicator = ContextCompat.getDrawable(getContext(), R.drawable.indicator_square_unselected);
break;
case IndicatorShape.DASH:
config.selectedSlideIndicator = ContextCompat.getDrawable(getContext(), R.drawable.indicator_dash_selected);
config.unselectedSlideIndicator = ContextCompat.getDrawable(getContext(), R.drawable.indicator_dash_unselected);
break;
case IndicatorShape.ROUND_SQUARE:
config.selectedSlideIndicator = ContextCompat.getDrawable(getContext(), R.drawable.indicator_round_square_selected);
config.unselectedSlideIndicator = ContextCompat.getDrawable(getContext(), R.drawable.indicator_round_square_unselected);
break;
}
refreshIndicators();
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/SsSnapHelper.java
================================================
package ss.com.bannerslider;
import android.support.v7.widget.PagerSnapHelper;
import android.support.v7.widget.RecyclerView;
/**
* @author S.Shahini
* @since 2/17/18
*/
class SsSnapHelper extends PagerSnapHelper {
private OnSelectedItemChange onSelectedItemChange;
private int lastPosition;
public SsSnapHelper(OnSelectedItemChange onSelectedItemChange) {
this.onSelectedItemChange = onSelectedItemChange;
}
@Override
public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
int position = super.findTargetSnapPosition(layoutManager, velocityX, velocityY);
if (position != RecyclerView.NO_POSITION && lastPosition != position && position < layoutManager.getItemCount()) {
onSelectedItemChange.onSelectedItemChange(position);
lastPosition = position;
}
return position;
}
public interface OnSelectedItemChange {
void onSelectedItemChange(int position);
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/adapters/PositionController.java
================================================
package ss.com.bannerslider.adapters;
import android.util.Log;
/**
* @author S.Shahini
* @since 4/7/18
*/
public class PositionController {
private static final String TAG = "PositionController";
private SliderRecyclerViewAdapter recyclerViewAdapter;
private SliderAdapter sliderAdapter;
private boolean loop;
public PositionController(SliderAdapter sliderAdapter, boolean loop) {
this.sliderAdapter = sliderAdapter;
this.loop = loop;
}
public int getUserSlidePosition(int position) {
if (loop) {
if (position == 0) {
return recyclerViewAdapter.getItemCount() - 3;
} else if (position == recyclerViewAdapter.getItemCount() - 1) {
return 0;
} else {
return position - 1;
}
} else {
return position;
}
}
public int getRealSlidePosition(int position) {
if (!loop) {
return position;
} else {
if (position >= 0 && position < sliderAdapter.getItemCount()) {
return position + 1;
} else {
Log.e(TAG, "setSelectedSlide: Invalid Item Position");
return 1;
}
}
}
public int getLastUserSlidePosition() {
return sliderAdapter.getItemCount() - 1;
}
public int getFirstUserSlidePosition() {
return 0;
}
public void setRecyclerViewAdapter(SliderRecyclerViewAdapter recyclerViewAdapter) {
this.recyclerViewAdapter = recyclerViewAdapter;
}
public int getNextSlide(int currentPosition) {
if (currentPosition < recyclerViewAdapter.getItemCount() - 1) {
return currentPosition + 1;
} else {
return loop ? 1 : 0;
}
}
public void setLoop(boolean loop) {
this.loop = loop;
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/adapters/SliderAdapter.java
================================================
package ss.com.bannerslider.adapters;
import ss.com.bannerslider.SlideType;
import ss.com.bannerslider.viewholder.ImageSlideViewHolder;
/**
* @author S.Shahini
* @since 3/4/18
*/
public abstract class SliderAdapter {
public abstract int getItemCount();
public final SlideType getSlideType(int position) {
return SlideType.IMAGE;
}
public abstract void onBindImageSlide(int position, ImageSlideViewHolder imageSlideViewHolder);
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/adapters/SliderRecyclerViewAdapter.java
================================================
package ss.com.bannerslider.adapters;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import ss.com.bannerslider.SlideType;
import ss.com.bannerslider.event.OnSlideClickListener;
import ss.com.bannerslider.viewholder.ImageSlideViewHolder;
/**
* @author S.Shahini
* @since 12/16/17
*/
public class SliderRecyclerViewAdapter extends RecyclerView.Adapter {
private ViewGroup.LayoutParams imageViewLayoutParams;
private OnSlideClickListener onSlideClickListener;
private SliderAdapter sliderAdapter;
private boolean loop;
private View.OnTouchListener itemOnTouchListener;
private PositionController positionController;
public SliderRecyclerViewAdapter(SliderAdapter iSliderAdapter, boolean loop, ViewGroup.LayoutParams imageViewLayoutParams, View.OnTouchListener itemOnTouchListener, PositionController positionController) {
this.sliderAdapter = iSliderAdapter;
this.imageViewLayoutParams = imageViewLayoutParams;
this.loop = loop;
this.itemOnTouchListener = itemOnTouchListener;
this.positionController = positionController;
}
public void setOnSlideClickListener(OnSlideClickListener onSlideClickListener) {
this.onSlideClickListener = onSlideClickListener;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == SlideType.IMAGE.getValue()) {
ImageView imageView = new ImageView(parent.getContext());
imageView.setLayoutParams(imageViewLayoutParams);
imageView.setAdjustViewBounds(true);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
return new ImageSlideViewHolder(imageView);
} else {
return null;
}
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
if (!loop) {
sliderAdapter.onBindImageSlide(position, (ImageSlideViewHolder) holder);
} else {
if (position == 0) {
sliderAdapter.onBindImageSlide(positionController.getLastUserSlidePosition(), (ImageSlideViewHolder) holder);
} else if (position == getItemCount() - 1) {
sliderAdapter.onBindImageSlide(positionController.getFirstUserSlidePosition(), (ImageSlideViewHolder) holder);
} else {
sliderAdapter.onBindImageSlide(position - 1, (ImageSlideViewHolder) holder);
}
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onSlideClickListener != null)
onSlideClickListener.onSlideClick(positionController.getUserSlidePosition(holder.getAdapterPosition()));
}
});
holder.itemView.setOnTouchListener(itemOnTouchListener);
}
@Override
public int getItemCount() {
return sliderAdapter.getItemCount() + (loop ? 2 : 0);
}
public void setLoop(boolean loop) {
this.loop = loop;
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/event/OnSlideChangeListener.java
================================================
package ss.com.bannerslider.event;
/**
* @author S.Shahini
* @since 3/4/18
*/
public interface OnSlideChangeListener {
void onSlideChange(int position);
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/event/OnSlideClickListener.java
================================================
package ss.com.bannerslider.event;
/**
* @author S.Shahini
* @since 3/4/18
*/
public interface OnSlideClickListener {
void onSlideClick(int position);
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/indicators/CircleIndicator.java
================================================
package ss.com.bannerslider.indicators;
import android.content.Context;
import android.os.Build;
import android.support.v4.content.res.ResourcesCompat;
import ss.com.bannerslider.R;
/**
* @author S.Shahini
* @since 11/27/16
*/
public class CircleIndicator extends IndicatorShape {
public CircleIndicator(Context context, int indicatorSize, boolean mustAnimateChanges) {
super(context, indicatorSize, mustAnimateChanges);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_circle_unselected, null));
} else {
setBackgroundDrawable(getResources().getDrawable(R.drawable.indicator_circle_unselected));
}
}
@Override
public void onCheckedChange(boolean isChecked) {
super.onCheckedChange(isChecked);
if (isChecked) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_circle_selected, null));
} else {
setBackgroundDrawable(getResources().getDrawable(R.drawable.indicator_circle_selected));
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_circle_unselected, null));
} else {
setBackgroundDrawable(getResources().getDrawable(R.drawable.indicator_circle_unselected));
}
}
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/indicators/DashIndicator.java
================================================
package ss.com.bannerslider.indicators;
import android.content.Context;
import android.support.v4.content.res.ResourcesCompat;
import android.widget.LinearLayout;
import ss.com.bannerslider.R;
/**
* @author S.Shahini
* @since 11/27/16
*/
public class DashIndicator extends IndicatorShape {
public DashIndicator(Context context, int indicatorSize, boolean mustAnimateChanges) {
super(context, indicatorSize, mustAnimateChanges);
setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_dash_unselected, null));
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
if (layoutParams != null) {
layoutParams.width = getResources().getDimensionPixelSize(R.dimen.default_dash_indicator_width);
setLayoutParams(layoutParams);
}
}
@Override
public void onCheckedChange(boolean isChecked) {
super.onCheckedChange(isChecked);
if (isChecked) {
setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_dash_selected, null));
} else {
setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_dash_unselected, null));
}
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/indicators/IndicatorShape.java
================================================
package ss.com.bannerslider.indicators;
import android.content.Context;
import android.view.Gravity;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import ss.com.bannerslider.R;
/**
* @author S.Shahini
* @since 11/26/16
*/
public abstract class IndicatorShape extends ImageView {
private boolean isChecked = false;
private int indicatorSize;
private boolean mustAnimateChange;
public static final int CIRCLE = 0;
public static final int SQUARE = 1;
public static final int ROUND_SQUARE = 2;
public static final int DASH = 3;
private static final int ANIMATION_DURATION = 150;
public IndicatorShape(Context context, int indicatorSize, boolean mustAnimateChange) {
super(context);
this.indicatorSize = indicatorSize;
this.mustAnimateChange = mustAnimateChange;
setup();
}
private void setup() {
if (this.indicatorSize == 0) {
indicatorSize = (int) getResources().getDimension(R.dimen.default_indicator_size);
}
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(indicatorSize, indicatorSize);
int margin = getResources().getDimensionPixelSize(R.dimen.default_indicator_margins);
layoutParams.gravity = Gravity.CENTER_VERTICAL;
layoutParams.setMargins(margin, 0, margin, 0);
setLayoutParams(layoutParams);
}
public void onCheckedChange(boolean isChecked) {
if (this.isChecked != isChecked) {
if (mustAnimateChange) {
if (isChecked) {
scale();
} else {
descale();
}
}else {
if (isChecked) {
scale(0);
} else {
descale(0);
}
}
this.isChecked = isChecked;
}
}
private void scale() {
scale(ANIMATION_DURATION);
}
private void scale(int duration) {
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 1.1f, 1f, 1.1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(duration);
scaleAnimation.setFillAfter(true);
startAnimation(scaleAnimation);
}
private void descale() {
descale(ANIMATION_DURATION);
}
private void descale(int duration) {
ScaleAnimation scaleAnimation = new ScaleAnimation(1.1f, 1f, 1.1f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(duration);
scaleAnimation.setFillAfter(true);
startAnimation(scaleAnimation);
}
public void setMustAnimateChange(boolean mustAnimateChange){
this.mustAnimateChange=mustAnimateChange;
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/indicators/RoundSquareIndicator.java
================================================
package ss.com.bannerslider.indicators;
import android.content.Context;
import android.os.Build;
import android.support.v4.content.res.ResourcesCompat;
import ss.com.bannerslider.R;
/**
* @author S.Shahini
* @since 11/27/16
*/
public class RoundSquareIndicator extends IndicatorShape {
public RoundSquareIndicator(Context context, int indicatorSize, boolean mustAnimateChanges) {
super(context, indicatorSize, mustAnimateChanges);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.indicator_round_square_unselected, null));
} else {
setBackgroundDrawable(getResources().getDrawable(R.drawable.indicator_round_square_unselected));
}
}
@Override
public void onCheckedChange(boolean isChecked) {
super.onCheckedChange(isChecked);
if (isChecked) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_round_square_selected, null));
} else {
setBackgroundDrawable(getResources().getDrawable(R.drawable.indicator_round_square_selected));
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_round_square_unselected, null));
} else {
setBackgroundDrawable(getResources().getDrawable(R.drawable.indicator_round_square_unselected));
}
}
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/indicators/SquareIndicator.java
================================================
package ss.com.bannerslider.indicators;
import android.content.Context;
import android.os.Build;
import android.support.v4.content.res.ResourcesCompat;
import ss.com.bannerslider.R;
/**
* @author S.Shahini
* @since 11/27/16
*/
public class SquareIndicator extends IndicatorShape {
public SquareIndicator(Context context, int indicatorSize, boolean mustAnimateChanges) {
super(context, indicatorSize, mustAnimateChanges);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_square_unselected, null));
} else {
setBackgroundDrawable(getResources().getDrawable(R.drawable.indicator_square_unselected));
}
}
@Override
public void onCheckedChange(boolean isChecked) {
super.onCheckedChange(isChecked);
if (isChecked) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_square_selected, null));
} else {
setBackgroundDrawable(getResources().getDrawable(R.drawable.indicator_square_selected));
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.indicator_square_unselected, null));
} else {
setBackgroundDrawable(getResources().getDrawable(R.drawable.indicator_square_unselected));
}
}
}
}
================================================
FILE: bannerslider/src/main/java/ss/com/bannerslider/viewholder/ImageSlideViewHolder.java
================================================
package ss.com.bannerslider.viewholder;
import android.support.annotation.DrawableRes;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import ss.com.bannerslider.Slider;
public class ImageSlideViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public ImageSlideViewHolder(View itemView) {
super(itemView);
this.imageView = (ImageView) itemView;
}
public void bindImageSlide(String imageUrl) {
if (imageUrl != null) {
Slider.getImageLoadingService().loadImage(imageUrl, imageView);
}
}
public void bindImageSlide(@DrawableRes int imageResourceId) {
Slider.getImageLoadingService().loadImage(imageResourceId, imageView);
}
public void bindImageSlide(String url, @DrawableRes int placeHolder, @DrawableRes int error) {
Slider.getImageLoadingService().loadImage(url, placeHolder, error, imageView);
}
}
================================================
FILE: bannerslider/src/main/res/drawable/indicator_circle_selected.xml
================================================
================================================
FILE: bannerslider/src/main/res/drawable/indicator_circle_unselected.xml
================================================
================================================
FILE: bannerslider/src/main/res/drawable/indicator_dash_selected.xml
================================================
================================================
FILE: bannerslider/src/main/res/drawable/indicator_dash_unselected.xml
================================================
================================================
FILE: bannerslider/src/main/res/drawable/indicator_round_square_selected.xml
================================================
================================================
FILE: bannerslider/src/main/res/drawable/indicator_round_square_unselected.xml
================================================
================================================
FILE: bannerslider/src/main/res/drawable/indicator_square_selected.xml
================================================
================================================
FILE: bannerslider/src/main/res/drawable/indicator_square_unselected.xml
================================================
================================================
FILE: bannerslider/src/main/res/layout/item_slide_image.xml
================================================
================================================
FILE: bannerslider/src/main/res/values/attrs.xml
================================================
================================================
FILE: bannerslider/src/main/res/values/colors.xml
================================================
#eeee
#66eeeeee
================================================
FILE: bannerslider/src/main/res/values/dimens.xml
================================================
8dp
5dp
12dp
2dp
16dp
================================================
FILE: bannerslider/src/main/res/values/strings.xml
================================================
BannerSlider
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Wed Apr 04 15:05:26 IRDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
================================================
FILE: gradle.properties
================================================
## Project-wide Gradle settings.
#
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Sat Apr 07 10:07:45 IRDT 2018
systemProp.http.proxyPassword=
systemProp.http.proxyHost=92.222.252.193
org.gradle.jvmargs=-Xmx1536m
systemProp.http.proxyUser=s.shahini
systemProp.http.proxyPort=6060
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: settings.gradle
================================================
include ':app', ':bannerslider'