Skip to content

Commit c1bd3c2

Browse files
committed
refactor code
1 parent 52db9ec commit c1bd3c2

File tree

5 files changed

+190
-78
lines changed

5 files changed

+190
-78
lines changed

README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,23 @@ allprojects {
1616
}
1717
}
1818
dependencies {
19-
implementation 'com.github.ibrahimsn98:android-particles:1.8'
19+
implementation 'com.github.ibrahimsn98:android-particles:1.9'
2020
}
2121
```
2222

2323
# Attributions
2424
```xml
2525
<me.ibrahimsn.particle.ParticleView
26-
android:id="@+id/particleView"
27-
android:layout_width="match_parent"
28-
android:layout_height="match_parent"
29-
app:particleCount="20"
30-
app:minParticleRadius="5"
31-
app:maxParticleRadius="12"
32-
app:particleColor="@android:color/white"
33-
app:backgroundColor="@android:color/holo_red_light" />
26+
android:id="@+id/particleView"
27+
android:layout_width="match_parent"
28+
android:layout_height="match_parent"
29+
app:particleCount="60"
30+
app:particleMinRadius="3"
31+
app:particleMaxRadius="10"
32+
app:particlesBackgroundColor="#23262a"
33+
app:particleColor="@android:color/holo_green_dark"
34+
app:particleLineColor="@android:color/holo_green_dark"
35+
app:particleLinesEnabled="true" />
3436
```
3537

3638
# Usage

app/src/main/res/layout/activity_main.xml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
android:layout_width="match_parent"
1414
android:layout_height="match_parent"
1515
app:particleCount="60"
16-
app:linesColor="@android:color/holo_green_dark"
16+
app:particleMinRadius="3"
17+
app:particleMaxRadius="10"
18+
app:particlesBackgroundColor="#23262a"
1719
app:particleColor="@android:color/holo_green_dark"
18-
app:backgroundColor="#23262a"
19-
app:minParticleRadius="3"
20-
app:maxParticleRadius="10"/>
20+
app:particleLineColor="@android:color/holo_green_dark"
21+
app:particleLinesEnabled="true" />
2122

2223
</FrameLayout>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package me.ibrahimsn.particle
22

3-
data class Particle constructor(
3+
data class Particle (
44
var radius: Float,
55
var x: Float,
66
var y: Float,
77
var vx: Int,
88
var vy: Int,
99
var alpha: Int
10-
)
10+
)

particle/src/main/java/me/ibrahimsn/particle/ParticleView.kt

Lines changed: 164 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,106 @@
11
package me.ibrahimsn.particle
22

33
import android.content.Context
4-
import android.graphics.Canvas
5-
import android.graphics.Color
6-
import android.graphics.Paint
7-
import android.graphics.Path
4+
import android.graphics.*
85
import android.util.AttributeSet
96
import android.view.SurfaceHolder
107
import android.view.SurfaceView
8+
import androidx.annotation.ColorInt
9+
import androidx.annotation.Dimension
1110
import kotlin.math.min
1211
import kotlin.math.sqrt
1312
import kotlin.random.Random
1413

15-
class ParticleView : SurfaceView, SurfaceHolder.Callback {
14+
class ParticleView @JvmOverloads constructor(
15+
context: Context,
16+
attrs: AttributeSet,
17+
defStyleAttr: Int = R.attr.ParticleViewStyle
18+
) : SurfaceView(context, attrs, defStyleAttr), SurfaceHolder.Callback {
1619

1720
private val particles = mutableListOf<Particle>()
1821
private var surfaceViewThread: SurfaceViewThread? = null
19-
20-
private var particleCount = 20
21-
private var minRadius = 5
22-
private var maxRadius = 10
23-
private var isLinesEnabled = true
2422
private var hasSurface: Boolean = false
2523
private var hasSetup = false
2624

27-
private var background = Color.BLACK
28-
private var colorParticles = Color.WHITE
29-
private var colorLines = Color.WHITE
3025
private val path = Path()
3126

27+
// Attribute Defaults
28+
private var _particleCount = 20
29+
30+
@Dimension
31+
private var _particleMinRadius = 5
32+
33+
@Dimension
34+
private var _particleMaxRadius = 10
35+
36+
@ColorInt
37+
private var _particlesBackgroundColor = Color.BLACK
38+
39+
@ColorInt
40+
private var _particleColor = Color.WHITE
41+
42+
@ColorInt
43+
private var _particleLineColor = Color.WHITE
44+
45+
private var _particleLinesEnabled = true
46+
47+
// Core Attributes
48+
var particleCount: Int
49+
get() = _particleCount
50+
set(value) {
51+
_particleCount = when {
52+
value > 50 -> 50
53+
value < 0 -> 0
54+
else -> value
55+
}
56+
}
57+
58+
var particleMinRadius: Int
59+
@Dimension get() = _particleMinRadius
60+
set(@Dimension value) {
61+
_particleMinRadius = when {
62+
value <= 0 -> 1
63+
value >= particleMaxRadius -> 1
64+
else -> value
65+
}
66+
}
67+
68+
var particleMaxRadius: Int
69+
@Dimension get() = _particleMaxRadius
70+
set(@Dimension value) {
71+
_particleMaxRadius = when {
72+
value <= particleMinRadius -> particleMinRadius + 1
73+
else -> value
74+
}
75+
}
76+
77+
var particlesBackgroundColor: Int
78+
@ColorInt get() = _particlesBackgroundColor
79+
set(@ColorInt value) {
80+
_particlesBackgroundColor = value
81+
}
82+
83+
var particleColor: Int
84+
@ColorInt get() = _particleColor
85+
set(@ColorInt value) {
86+
_particleColor = value
87+
paintParticles.color = value
88+
}
89+
90+
var particleLineColor: Int
91+
@ColorInt get() = _particleLineColor
92+
set(@ColorInt value) {
93+
_particleLineColor = value
94+
paintLines.color = value
95+
}
96+
97+
var particleLinesEnabled: Boolean
98+
get() = _particleLinesEnabled
99+
set(value) {
100+
_particleLinesEnabled = value
101+
}
102+
103+
// Paints
32104
private val paintParticles: Paint = Paint().apply {
33105
isAntiAlias = true
34106
style = Paint.Style.FILL
@@ -37,35 +109,64 @@ class ParticleView : SurfaceView, SurfaceHolder.Callback {
37109

38110
private val paintLines: Paint = Paint().apply {
39111
isAntiAlias = true
40-
style = Paint.Style.STROKE
112+
style = Paint.Style.FILL_AND_STROKE
41113
strokeWidth = 2F
42114
}
43115

44-
constructor(context: Context) : super(context)
45-
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
46-
val a = context.obtainStyledAttributes(attrs, R.styleable.ParticleView, 0, 0)
47-
48-
isLinesEnabled = a.getBoolean(R.styleable.ParticleView_lines, isLinesEnabled)
49-
particleCount = a.getInt(R.styleable.ParticleView_particleCount, particleCount)
50-
minRadius = a.getInt(R.styleable.ParticleView_minParticleRadius, minRadius)
51-
maxRadius = a.getInt(R.styleable.ParticleView_maxParticleRadius, maxRadius)
52-
colorParticles = a.getColor(R.styleable.ParticleView_particleColor, colorParticles)
53-
colorLines = a.getColor(R.styleable.ParticleView_linesColor, colorLines)
54-
background = a.getColor(R.styleable.ParticleView_backgroundColor, background)
55-
a.recycle()
56-
57-
paintParticles.color = colorParticles
58-
paintLines.color = colorLines
59-
60-
if (particleCount > 50) particleCount = 50
61-
if (minRadius <= 0) minRadius = 1
62-
if (maxRadius <= minRadius) maxRadius = minRadius + 1
116+
init {
117+
obtainStyledAttributes(attrs, defStyleAttr)
118+
if (holder != null) holder.addCallback(this)
119+
hasSurface = false
120+
}
63121

64-
if (holder != null) {
65-
holder.addCallback(this)
122+
private fun obtainStyledAttributes(attrs: AttributeSet, defStyleAttr: Int) {
123+
val typedArray = context.obtainStyledAttributes(
124+
attrs,
125+
R.styleable.ParticleView,
126+
defStyleAttr,
127+
0
128+
)
129+
130+
try {
131+
particleCount = typedArray.getInt(
132+
R.styleable.ParticleView_particleCount,
133+
particleCount
134+
)
135+
136+
particleMinRadius = typedArray.getInt(
137+
R.styleable.ParticleView_particleMinRadius,
138+
particleMinRadius
139+
)
140+
141+
particleMaxRadius = typedArray.getInt(
142+
R.styleable.ParticleView_particleMaxRadius,
143+
particleMaxRadius
144+
)
145+
146+
particlesBackgroundColor = typedArray.getColor(
147+
R.styleable.ParticleView_particlesBackgroundColor,
148+
particlesBackgroundColor
149+
)
150+
151+
particleColor = typedArray.getColor(
152+
R.styleable.ParticleView_particleColor,
153+
particleColor
154+
)
155+
156+
particleLineColor = typedArray.getColor(
157+
R.styleable.ParticleView_particleLineColor,
158+
particleLineColor
159+
)
160+
161+
particleLinesEnabled = typedArray.getBoolean(
162+
R.styleable.ParticleView_particleLinesEnabled,
163+
particleLinesEnabled
164+
)
165+
} catch (e: Exception) {
166+
e.printStackTrace()
167+
} finally {
168+
typedArray.recycle()
66169
}
67-
68-
hasSurface = false
69170
}
70171

71172
override fun surfaceCreated(holder: SurfaceHolder) {
@@ -100,7 +201,26 @@ class ParticleView : SurfaceView, SurfaceHolder.Callback {
100201
}
101202

102203
override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) {
103-
// Ignore
204+
// ignored
205+
}
206+
207+
private fun setupParticles() {
208+
if (!hasSetup) {
209+
hasSetup = true
210+
particles.clear()
211+
for (i in 0 until particleCount) {
212+
particles.add(
213+
Particle(
214+
Random.nextInt(particleMinRadius, particleMaxRadius).toFloat(),
215+
Random.nextInt(0, width).toFloat(),
216+
Random.nextInt(0, height).toFloat(),
217+
Random.nextInt(-2, 2),
218+
Random.nextInt(-2, 2),
219+
Random.nextInt(150, 255)
220+
)
221+
)
222+
}
223+
}
104224
}
105225

106226
private inner class SurfaceViewThread : Thread() {
@@ -109,28 +229,15 @@ class ParticleView : SurfaceView, SurfaceHolder.Callback {
109229
private var canvas: Canvas? = null
110230

111231
override fun run() {
112-
if (!hasSetup) {
113-
hasSetup = true
114-
for (i in 0 until particleCount) {
115-
particles.add(
116-
Particle(
117-
Random.nextInt(minRadius, maxRadius).toFloat(),
118-
Random.nextInt(0, width).toFloat(),
119-
Random.nextInt(0, height).toFloat(),
120-
Random.nextInt(-2, 2),
121-
Random.nextInt(-2, 2),
122-
Random.nextInt(150, 255)
123-
)
124-
)
125-
}
126-
}
232+
setupParticles()
127233

128234
while (running) {
129235
try {
130236
canvas = holder.lockCanvas()
131237

132238
synchronized (holder) {
133-
canvas?.drawColor(background)
239+
// Clear screen every frame
240+
canvas?.drawColor(particlesBackgroundColor, PorterDuff.Mode.CLEAR)
134241

135242
for (i in 0 until particleCount) {
136243
particles[i].x += particles[i].vx
@@ -149,7 +256,7 @@ class ParticleView : SurfaceView, SurfaceHolder.Callback {
149256
}
150257

151258
canvas?.let {
152-
if (isLinesEnabled) {
259+
if (particleLinesEnabled) {
153260
for (j in 0 until particleCount) {
154261
if (i != j) {
155262
linkParticles(it, particles[i], particles[j])
@@ -178,8 +285,8 @@ class ParticleView : SurfaceView, SurfaceHolder.Callback {
178285

179286
try {
180287
join()
181-
} catch (ignored: InterruptedException) {
182-
288+
} catch (e: InterruptedException) {
289+
// ignored
183290
}
184291
}
185292
}
Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33
<declare-styleable name="ParticleView">
4-
<attr name="lines" format="boolean" />
5-
<attr name="backgroundColor" format="color" />
6-
<attr name="particleColor" format="color" />
7-
<attr name="linesColor" format="color" />
84
<attr name="particleCount" format="integer" />
9-
<attr name="minParticleRadius" format="integer" />
10-
<attr name="maxParticleRadius" format="integer" />
5+
<attr name="particleMinRadius" format="integer" />
6+
<attr name="particleMaxRadius" format="integer" />
7+
<attr name="particlesBackgroundColor" format="color" />
8+
<attr name="particleColor" format="color" />
9+
<attr name="particleLineColor" format="color" />
10+
<attr name="particleLinesEnabled" format="boolean" />
1111
</declare-styleable>
12+
13+
<attr name="ParticleViewStyle" format="reference" />
1214
</resources>

0 commit comments

Comments
 (0)