Skip to content

Commit f7a1a33

Browse files
Merge pull request #7 from SimformSolutionsPvtLtd/feature/UNT-T5572_add_gif_as_pull_animations
UNT-T5572 set custom animations, gif animations
2 parents e086f20 + e324baa commit f7a1a33

File tree

25 files changed

+304
-83
lines changed

25 files changed

+304
-83
lines changed

.DS_Store

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

README.md

Lines changed: 83 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
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
34

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+
[![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)
56

67
SSPullToRefresh 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 |
20+
|--|--|
21+
| ![](gif/default_anim.gif) | ![](gif/custom_anim.gif) |
22+
23+
| Lottie animation 2 | Wave animation ( Custom class ) |
24+
|--|--|
25+
| ![](gif/custom_anim2.gif) | ![](gif/wave_anim.gif) |
26+
27+
| Gif animation |
28+
|--|
29+
| ![](gif/gif_anim.gif) |
2030

2131
# How it works:
2232

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

3747
```groovy
3848
dependencies {
39-
implementation 'com.github.SimformSolutionsPvtLtd:SSPullToRefresh:1.1'
49+
implementation 'com.github.SimformSolutionsPvtLtd:SSPullToRefresh:1.2'
4050
}
4151
```
4252
2. Wrap your refreshing view ( RecyclerView, listView etc..) with SSPullToRefreshLayout
@@ -81,7 +91,6 @@ SSPullToRefresh uses lottie animations to render high quality animations on pull
8191

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

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

103159
override fun reset() {
104-
cancelAnimation()
105-
playAnimation()
106160
}
107161

108162
override fun refreshing() {
109163
}
110164

111165
override fun refreshComplete() {
112-
cancelAnimation()
166+
animator?.cancel()
113167
}
114168

115169
override fun pullToRefresh() {
116-
playAnimation()
170+
animator = createAnimator().apply {
171+
start()
172+
}
117173
}
118174

119175
override fun releaseToRefresh() {
@@ -123,20 +179,22 @@ SSPullToRefresh uses lottie animations to render high quality animations on pull
123179
}
124180
}
125181
```
126-
* Provide you CustomView by setRefreshView() method
182+
* Provide your CustomView by setRefreshView() method
127183
```kotlin
128-
ssPullRefresh.setRefreshView(
129-
MytAnimationView(this),
130-
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,300)
131-
)
184+
ssPullRefresh.setRefreshView(WaveAnimation(this))
132185
```
133-
* You can aslo provide only view without parameters, in that case refreshView will take MATCH_PARENT,70 width,hight respectively
186+
* Provide layoutParams if you need to channge RefreshView height/width
134187
```kotlin
135-
ssPullRefresh.setRefreshView(MytAnimationView(this))
188+
ssPullRefresh.setRefreshViewParams(ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,300))
189+
```
190+
* Set Gif animation just by using setGifAnimation method ( This can only be done on SSAnimationView )
191+
```kotlin
192+
ssPullRefresh.setGifAnimation(R.raw.bird)
136193
```
137194

138195
# Other Library used:
139196
* [Lottie][lottie-repo-url]
197+
* [android-gif-drawable][gif-lib-repo]
140198

141199
### Credits:
142200
- This library was inspired by __[RecyclerRefreshLayout]__
@@ -147,9 +205,12 @@ Support it by joining __[stargazers]__ for this repository.⭐
147205
## 🤝 How to Contribute
148206

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

210+
211+
# iOS Library:
212+
* Check our iOS Library also - [SSCustomPullToRefresh][SSCustomPullToRefresh]
213+
153214
## Bugs and Feedback
154215

155216
For bugs, feature requests, and discussion please use __[GitHub Issues]__.
@@ -177,3 +238,5 @@ Copyright 2021 Simform Solutions
177238
[Contributing Guide]: <https://github.com/SimformSolutionsPvtLtd/SSPullToRefresh/blob/main/CONTRIBUTING.md>
178239
[GitHub Issues]: <https://github.com/SimformSolutionsPvtLtd/SSPullToRefresh/issues>
179240
[RecyclerRefreshLayout]: <https://github.com/dinuscxj/RecyclerRefreshLayout?utm_source=android-arsenal.com&utm_medium=referral&utm_campaign=3383>
241+
[gif-lib-repo]: <https://github.com/koral--/android-gif-drawable.git>
242+
[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)