Skip to content

Commit 474900a

Browse files
author
fuzzagrosner
committed
[register] removen need for ugly call to callback. Let notifyChange handle that. Simplify register such that callback handling is private to base class so devs dont introduce memory leaking.
1 parent 896dd78 commit 474900a

File tree

2 files changed

+36
-43
lines changed

2 files changed

+36
-43
lines changed

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,11 @@ Without convenience methods, we must create a `ViewRegister`:
263263
```kotlin
264264
class MyOnTextChangedRegister : ViewRegister<TextView, String>(), TextWatcher {
265265

266-
override fun register(view: TextView) {
266+
override fun registerView(view: TextView) {
267267
view.addTextChangedListener(this)
268268
}
269269

270-
override fun deregister(view: TextView) {
271-
this.callback = null
270+
override fun deregisterFromView(view: TextView) {
272271
view.removeTextChangedListener(this)
273272
}
274273

okbinding/src/main/java/com/andrewgrosner/okbinding/bindings/ViewRegisters.kt

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,56 +14,60 @@ private typealias Callback<T> = (T) -> Unit
1414

1515
abstract class ViewRegister<in V : View, Output> {
1616

17-
var callback: (((Output?) -> Unit))? = null
17+
private var callback: (((Output?) -> Unit))? = null
1818

1919
fun register(view: V, callback: Callback<Output?>) {
2020
this.callback = callback
21-
register(view)
21+
registerView(view)
2222
}
2323

24-
abstract fun register(view: V)
2524

26-
abstract fun deregister(view: V)
25+
fun deregister(view: V) {
26+
deregisterFromView(view)
27+
this.callback = null
28+
}
29+
30+
abstract fun registerView(view: V)
31+
32+
open fun deregisterFromView(view: V) {}
2733

2834
abstract fun getValue(view: V): Output
35+
36+
protected fun notifyChange(output: Output?) {
37+
callback?.invoke(output)
38+
}
2939
}
3040

3141
class OnTextChangedRegister : ViewRegister<TextView, String>(), TextWatcher {
3242

33-
override fun register(view: TextView) {
43+
override fun registerView(view: TextView) {
3444
view.addTextChangedListener(this)
3545
}
3646

37-
override fun deregister(view: TextView) {
38-
this.callback = null
47+
override fun deregisterFromView(view: TextView) {
3948
view.removeTextChangedListener(this)
4049
}
4150

4251
override fun afterTextChanged(s: Editable?) = Unit
4352

4453
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
4554

46-
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
47-
@Suppress("UNCHECKED_CAST")
48-
callback?.invoke(s?.toString())
49-
}
55+
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = notifyChange(s?.toString())
5056

5157
override fun getValue(view: TextView) = view.text.toString()
5258
}
5359

5460
class OnCheckedChangeRegister : ViewRegister<CompoundButton, Boolean>(), CompoundButton.OnCheckedChangeListener {
5561

56-
override fun register(view: CompoundButton) {
62+
override fun registerView(view: CompoundButton) {
5763
view.setOnCheckedChangeListener(this)
5864
}
5965

60-
override fun deregister(view: CompoundButton) {
66+
override fun deregisterFromView(view: CompoundButton) {
6167
view.setOnCheckedChangeListener(null)
6268
}
6369

64-
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
65-
callback?.invoke(isChecked)
66-
}
70+
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) = notifyChange(isChecked)
6771

6872
override fun getValue(view: CompoundButton) = view.isChecked
6973
}
@@ -82,14 +86,10 @@ class OnDateChangedRegister(private val initialValue: Calendar) : ViewRegister<D
8286

8387
private val listener = WeakOnDateChangedListener(this)
8488

85-
override fun register(view: DatePicker) {
89+
override fun registerView(view: DatePicker) {
8690
view.init(initialValue[YEAR], initialValue[MONTH], initialValue[DAY_OF_MONTH], listener)
8791
}
8892

89-
override fun deregister(view: DatePicker) {
90-
this.callback = null
91-
}
92-
9393
override fun getValue(view: DatePicker) = getInstance().apply {
9494
set(MONTH, view.month)
9595
set(DAY_OF_MONTH, view.dayOfMonth)
@@ -101,18 +101,18 @@ class OnDateChangedRegister(private val initialValue: Calendar) : ViewRegister<D
101101
calendar[MONTH] = monthOfYear
102102
calendar[DAY_OF_MONTH] = dayOfMonth
103103
calendar[YEAR] = year
104-
callback?.invoke(calendar)
104+
notifyChange(calendar)
105105
}
106106

107107
}
108108

109109
class OnTimeChangedRegister : ViewRegister<TimePicker, Calendar>(), TimePicker.OnTimeChangedListener {
110110

111-
override fun register(view: TimePicker) {
111+
override fun registerView(view: TimePicker) {
112112
view.setOnTimeChangedListener(this)
113113
}
114114

115-
override fun deregister(view: TimePicker) {
115+
override fun deregisterFromView(view: TimePicker) {
116116
view.setOnTimeChangedListener(null)
117117
}
118118

@@ -126,48 +126,42 @@ class OnTimeChangedRegister : ViewRegister<TimePicker, Calendar>(), TimePicker.O
126126
}
127127
}!!
128128

129-
override fun onTimeChanged(view: TimePicker, hourOfDay: Int, minute: Int) {
130-
callback?.invoke(getInstance().apply {
131-
set(HOUR_OF_DAY, hourOfDay)
132-
set(MINUTE, minute)
133-
})
134-
}
129+
override fun onTimeChanged(view: TimePicker, hourOfDay: Int, minute: Int) = notifyChange(getInstance().apply {
130+
set(HOUR_OF_DAY, hourOfDay)
131+
set(MINUTE, minute)
132+
})
135133

136134
}
137135

138136
class OnRatingBarChangedRegister : ViewRegister<RatingBar, Float>(), RatingBar.OnRatingBarChangeListener {
139137

140-
override fun register(view: RatingBar) {
138+
override fun registerView(view: RatingBar) {
141139
view.onRatingBarChangeListener = this
142140
}
143141

144-
override fun deregister(view: RatingBar) {
142+
override fun deregisterFromView(view: RatingBar) {
145143
view.onRatingBarChangeListener = null
146144
}
147145

148146
override fun getValue(view: RatingBar) = view.rating
149147

150-
override fun onRatingChanged(ratingBar: RatingBar?, rating: Float, fromUser: Boolean) {
151-
callback?.invoke(rating)
152-
}
148+
override fun onRatingChanged(ratingBar: RatingBar?, rating: Float, fromUser: Boolean) = notifyChange(rating)
153149

154150
}
155151

156152
class OnSeekBarChangedRegister : ViewRegister<SeekBar, Int>(), SeekBar.OnSeekBarChangeListener {
157153

158-
override fun register(view: SeekBar) {
154+
override fun registerView(view: SeekBar) {
159155
view.setOnSeekBarChangeListener(this)
160156
}
161157

162-
override fun deregister(view: SeekBar) {
158+
override fun deregisterFromView(view: SeekBar) {
163159
view.setOnSeekBarChangeListener(null)
164160
}
165161

166162
override fun getValue(view: SeekBar) = view.progress
167163

168-
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
169-
callback?.invoke(progress)
170-
}
164+
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) = notifyChange(progress)
171165

172166
override fun onStartTrackingTouch(seekBar: SeekBar?) {
173167
}

0 commit comments

Comments
 (0)