Skip to content

Commit 124699f

Browse files
Merge pull request #10 from SimformSolutionsPvtLtd/develop
✨ custom animations, gif animations
2 parents febeda8 + 4757718 commit 124699f

File tree

25 files changed

+302
-85
lines changed

25 files changed

+302
-85
lines changed

.DS_Store

2 KB
Binary file not shown.
File renamed without changes.
File renamed without changes.

README.md

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
1+
<a href="https://www.simform.com/"><img src="https://github.com/SimformSolutionsPvtLtd/SSToastMessage/blob/master/simformBanner.png"></a>
12
# SSPullToRefresh
23
## Pull to Refresh with custom animations
4+
[![Build Status](https://travis-ci.org/joemccann/dillinger.svg?branch=master)][git-repo-url] [![](https://jitpack.io/v/SimformSolutionsPvtLtd/SSPullToRefresh.svg)](https://jitpack.io/#SimformSolutionsPvtLtd/SSPullToRefresh) [![Kotlin Version](https://img.shields.io/badge/Kotlin-v1.5.10-blue.svg)](https://kotlinlang.org) [![Platform](https://img.shields.io/badge/Platform-Android-green.svg?style=flat)](https://www.android.com/) [![API](https://img.shields.io/badge/API-17%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=17)
35

4-
[![Build Status](https://travis-ci.org/joemccann/dillinger.svg?branch=master)][git-repo-url] [![](https://jitpack.io/v/SimformSolutionsPvtLtd/SSPullToRefresh.svg)](https://jitpack.io/#SimformSolutionsPvtLtd/SSPullToRefresh) [![Kotlin Version](https://img.shields.io/badge/Kotlin-v1.5.0-blue.svg)](https://kotlinlang.org) [![Platform](https://img.shields.io/badge/Platform-Android-green.svg?style=flat)](https://www.android.com/) [![API](https://img.shields.io/badge/API-21%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=21)
5-
6-
SSPullToRefresh uses lottie animations to render high quality animations on pull refresh.
6+
SSPullToRefresh makes PullRefresh easy to use, you can provide your own custom animations or set simple gifs on refresh view.
7+
The best feature is Lottie animations in refresh view, it uses lottie animations to render high quality animations on pull refresh.
78

89
## Features
910

1011
- Simple and easy to use ( no complex animations to deal with )
11-
- Customize the animation view by providing you own ( need to subclass SSAnimationView )
12+
- Customize the animation view by providing your own custom RefreshView (need to subclass SSAnimationView)
13+
- Set Gif animations in refresh view
1214
- Import lottie jason in assets folder and apply animation ( as simple as that )
1315
- Customize repeateMode, repeateCount and Interpolators on different points of animations
1416

1517
# 🎬 Preview
1618

17-
| Default refreshView | Custom animation 1 | Custom animation 2 |
18-
|--|--| --|
19-
| ![](default_anim.gif) | ![](custom_anim.gif) | ![](custom_anim2.gif) |
19+
| Default refreshView | Lottie animation 1 | Lottie animation 2 |
20+
|--|--|--|
21+
| ![](gifs/default_anim.gif) | ![](gifs/custom_anim.gif) | ![](gifs/custom_anim2.gif) |
22+
23+
| Wave animation (Custom class) | Gif animation |
24+
|--|--|
25+
| ![](gifs/wave_anim.gif) |![](gifs/gif_anim.gif) |
2026

2127
# How it works:
2228

@@ -36,7 +42,7 @@ SSPullToRefresh uses lottie animations to render high quality animations on pull
3642

3743
```groovy
3844
dependencies {
39-
implementation 'com.github.SimformSolutionsPvtLtd:SSPullToRefresh:1.1'
45+
implementation 'com.github.SimformSolutionsPvtLtd:SSPullToRefresh:1.2'
4046
}
4147
```
4248
2. Wrap your refreshing view ( RecyclerView, listView etc..) with SSPullToRefreshLayout
@@ -81,7 +87,6 @@ SSPullToRefresh uses lottie animations to render high quality animations on pull
8187

8288
* To customize SSPullToRefreshLayout, you can set a different lottie animation of your choice
8389
* you need to have .json file of you lottie animations in assets forlder of you app module
84-
8590
![](asset_folder.png)
8691

8792
```kotlin
@@ -98,22 +103,69 @@ SSPullToRefresh uses lottie animations to render high quality animations on pull
98103
```
99104
* To customize the whole refresh view you need to inherit SSAnimationView for your custom class and override the methods needed
100105
```kotlin
101-
class MytAnimationView(context: Context): SSAnimationView(context) {
106+
class WaveAnimation(context: Context): SSAnimationView(context) {
107+
private var amplitude = 22f.toDp() // scale
108+
private var speed = 0f
109+
private val path = Path()
110+
private var paint = Paint(Paint.ANTI_ALIAS_FLAG)
111+
private var animator: ValueAnimator? = null
112+
113+
override fun onDraw(c: Canvas) = c.drawPath(path, paint)
114+
115+
private fun createAnimator(): ValueAnimator {
116+
return ValueAnimator.ofFloat(0f, Float.MAX_VALUE).apply {
117+
repeatCount = ValueAnimator.INFINITE
118+
addUpdateListener {
119+
speed -= WAVE_SPEED
120+
createPath()
121+
invalidate()
122+
}
123+
}
124+
}
125+
126+
private fun createPath() {
127+
path.reset()
128+
paint.color = Color.parseColor("#203354")
129+
path.moveTo(0f, height.toFloat())
130+
path.lineTo(0f, amplitude)
131+
path.lineTo(0f, amplitude - 10)
132+
var i = 0
133+
while (i < width + 10) {
134+
val wx = i.toFloat()
135+
val wy = amplitude * 2 + amplitude * sin((i + 10) * Math.PI / WAVE_AMOUNT_ON_SCREEN + speed).toFloat()
136+
path.lineTo(wx, wy)
137+
i += 10
138+
}
139+
path.lineTo(width.toFloat(), height.toFloat())
140+
path.close()
141+
}
142+
143+
override fun onDetachedFromWindow() {
144+
animator?.cancel()
145+
super.onDetachedFromWindow()
146+
}
147+
148+
companion object {
149+
const val WAVE_SPEED = 0.25f
150+
const val WAVE_AMOUNT_ON_SCREEN = 350
151+
}
152+
153+
private fun Float.toDp() = this * context.resources.displayMetrics.density
102154

103155
override fun reset() {
104-
cancelAnimation()
105-
playAnimation()
106156
}
107157

108158
override fun refreshing() {
109159
}
110160

111161
override fun refreshComplete() {
112-
cancelAnimation()
162+
animator?.cancel()
113163
}
114164

115165
override fun pullToRefresh() {
116-
playAnimation()
166+
animator = createAnimator().apply {
167+
start()
168+
}
117169
}
118170

119171
override fun releaseToRefresh() {
@@ -123,20 +175,22 @@ SSPullToRefresh uses lottie animations to render high quality animations on pull
123175
}
124176
}
125177
```
126-
* Provide you CustomView by setRefreshView() method
178+
* Provide your CustomView by setRefreshView() method
127179
```kotlin
128-
ssPullRefresh.setRefreshView(
129-
MytAnimationView(this),
130-
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,300)
131-
)
180+
ssPullRefresh.setRefreshView(WaveAnimation(this))
132181
```
133-
* You can aslo provide only view without parameters, in that case refreshView will take MATCH_PARENT,70 width,hight respectively
182+
* Provide layoutParams if you need to channge RefreshView height/width
134183
```kotlin
135-
ssPullRefresh.setRefreshView(MytAnimationView(this))
184+
ssPullRefresh.setRefreshViewParams(ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,300))
185+
```
186+
* Set Gif animation just by using setGifAnimation method ( This can only be done on SSAnimationView )
187+
```kotlin
188+
ssPullRefresh.setGifAnimation(R.raw.bird)
136189
```
137190

138191
# Other Library used:
139192
* [Lottie][lottie-repo-url]
193+
* [android-gif-drawable][gif-lib-repo]
140194

141195
### Credits:
142196
- This library was inspired by __[RecyclerRefreshLayout]__
@@ -147,9 +201,12 @@ Support it by joining __[stargazers]__ for this repository.⭐
147201
## 🤝 How to Contribute
148202

149203
Whether you're helping us fix bugs, improve the docs, or a feature request, we'd love to have you! 💪
150-
151204
Check out our __[Contributing Guide]__ for ideas on contributing.
152205

206+
207+
# iOS Library:
208+
* Check our iOS Library also - [SSCustomPullToRefresh][SSCustomPullToRefresh]
209+
153210
## Bugs and Feedback
154211

155212
For bugs, feature requests, and discussion please use __[GitHub Issues]__.
@@ -177,3 +234,5 @@ Copyright 2021 Simform Solutions
177234
[Contributing Guide]: <https://github.com/SimformSolutionsPvtLtd/SSPullToRefresh/blob/main/CONTRIBUTING.md>
178235
[GitHub Issues]: <https://github.com/SimformSolutionsPvtLtd/SSPullToRefresh/issues>
179236
[RecyclerRefreshLayout]: <https://github.com/dinuscxj/RecyclerRefreshLayout?utm_source=android-arsenal.com&utm_medium=referral&utm_campaign=3383>
237+
[gif-lib-repo]: <https://github.com/koral--/android-gif-drawable.git>
238+
[SSCustomPullToRefresh]: <https://github.com/SimformSolutionsPvtLtd/SSCustomPullToRefresh.git>

app/.DS_Store

0 Bytes
Binary file not shown.

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ android {
1010

1111
defaultConfig {
1212
applicationId "com.simform.pulltorefresh"
13-
minSdkVersion 16
13+
minSdkVersion 17
1414
targetSdkVersion 30
1515
versionCode 1
1616
versionName "1.0"

app/src/main/java/com/simform/demo/MainActivity.kt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.simform.demo
22

3+
import android.annotation.SuppressLint
34
import androidx.appcompat.app.AppCompatActivity
45
import android.os.Bundle
56
import android.view.ViewGroup
67
import android.widget.Toast
78
import androidx.recyclerview.widget.LinearLayoutManager
89
import com.example.pulltorefresh.R
10+
import com.simform.refresh.SSAnimationView
911
import com.simform.refresh.SSPullToRefreshLayout
1012
import kotlinx.android.synthetic.main.activity_main.ssPullRefresh
1113
import kotlinx.android.synthetic.main.activity_main.rv
@@ -18,16 +20,18 @@ class MainActivity : AppCompatActivity() {
1820

1921
private var adapter = RecyclerAdapter(this@MainActivity)
2022

23+
@SuppressLint("ResourceType")
2124
override fun onCreate(savedInstanceState: Bundle?) {
2225
super.onCreate(savedInstanceState)
2326
setContentView(R.layout.activity_main)
2427
title = "SSPullToRefresh"
2528

2629
setUpRecyclerView()
30+
// set setOnRefreshListener on pull refresh view
2731
ssPullRefresh.setOnRefreshListener(object : SSPullToRefreshLayout.OnRefreshListener {
2832
override fun onRefresh() {
2933
GlobalScope.launch {
30-
delay(3000)
34+
delay(5000)
3135
ssPullRefresh.setRefreshing(false)
3236
MainScope().launch {
3337
adapter.randomizeData()
@@ -37,14 +41,15 @@ class MainActivity : AppCompatActivity() {
3741
}
3842
})
3943

40-
ssPullRefresh.setDragDistanceConverter(com.simform.refresh.SSDragDistanceConverter())
44+
// set height and width of refresh view
45+
ssPullRefresh.setRefreshViewParams(ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,300))
46+
// set any lottie animation
4147
ssPullRefresh.setLottieAnimation("lottie_clock.json")
42-
ssPullRefresh.setRefreshView(
43-
com.simform.refresh.DefaultAnimationView(this),
44-
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,300)
45-
)
48+
// set repeat mode of lottie animation
4649
ssPullRefresh.setRepeatMode(SSPullToRefreshLayout.RepeatMode.REPEAT)
50+
// set number of times the animation repeats
4751
ssPullRefresh.setRepeatCount(SSPullToRefreshLayout.RepeatCount.INFINITE)
52+
//set style of RefreshLayout : NORMAL, FLOAT, PINNED
4853
ssPullRefresh.setRefreshStyle(SSPullToRefreshLayout.RefreshStyle.NORMAL)
4954
}
5055

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.simform.demo
2+
3+
import android.animation.ValueAnimator
4+
import android.content.Context
5+
import android.graphics.Canvas
6+
import android.graphics.Color
7+
import android.graphics.Paint
8+
import android.graphics.Path
9+
import com.simform.refresh.SSAnimationView
10+
import kotlin.math.sin
11+
12+
// This is a demo view in which user can set any animation or
13+
// just make it blank and set Gif animation using setGifAnimation() method on SSPullToRefreshLayout
14+
class WaveAnimation(context: Context): SSAnimationView(context) {
15+
16+
private var amplitude = 22f.toDp() // scale
17+
private var speed = 0f
18+
private val path = Path()
19+
private var paint = Paint(Paint.ANTI_ALIAS_FLAG)
20+
private var animator: ValueAnimator? = null
21+
22+
override fun onDraw(c: Canvas) = c.drawPath(path, paint)
23+
24+
private fun createAnimator(): ValueAnimator {
25+
return ValueAnimator.ofFloat(0f, Float.MAX_VALUE).apply {
26+
repeatCount = ValueAnimator.INFINITE
27+
addUpdateListener {
28+
speed -= WAVE_SPEED
29+
createPath()
30+
invalidate()
31+
}
32+
}
33+
}
34+
35+
private fun createPath() {
36+
path.reset()
37+
paint.color = Color.parseColor("#203354")
38+
path.moveTo(0f, height.toFloat())
39+
path.lineTo(0f, amplitude)
40+
path.lineTo(0f, amplitude - 10)
41+
var i = 0
42+
while (i < width + 10) {
43+
val wx = i.toFloat()
44+
val wy = amplitude * 2 + amplitude * sin((i + 10) * Math.PI / WAVE_AMOUNT_ON_SCREEN + speed).toFloat()
45+
path.lineTo(wx, wy)
46+
i += 10
47+
}
48+
path.lineTo(width.toFloat(), height.toFloat())
49+
path.close()
50+
}
51+
52+
override fun onDetachedFromWindow() {
53+
animator?.cancel()
54+
super.onDetachedFromWindow()
55+
}
56+
57+
companion object {
58+
const val WAVE_SPEED = 0.25f
59+
const val WAVE_AMOUNT_ON_SCREEN = 350
60+
}
61+
62+
private fun Float.toDp() = this * context.resources.displayMetrics.density
63+
64+
65+
override fun reset() {
66+
}
67+
68+
override fun refreshing() {
69+
}
70+
71+
override fun refreshComplete() {
72+
animator?.cancel()
73+
}
74+
75+
override fun pullToRefresh() {
76+
animator = createAnimator().apply {
77+
start()
78+
}
79+
}
80+
81+
override fun releaseToRefresh() {
82+
}
83+
84+
override fun pullProgress(pullDistance: Float, pullProgress: Float) {
85+
}
86+
87+
}
391 KB
Loading

app/src/main/res/raw/bird_gif.gif

391 KB
Loading

0 commit comments

Comments
 (0)