Skip to content

Commit c4ef0e8

Browse files
committed
Feat. Added Option to hide drawable when text is empty
1 parent ea9190c commit c4ef0e8

3 files changed

Lines changed: 134 additions & 82 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
android:id="@+id/drawableEditText"
1313
android:layout_width="match_parent"
1414
android:layout_height="wrap_content"
15+
app:isDrawableShownWhenTextIsEmpty="false"
1516
android:drawableRight="@drawable/ic_remove_red_eye_black_24dp"
1617
android:hint="@string/clickTheDrawables"
1718
android:inputType="text"

editdrawabletext/src/main/java/com/mindorks/editdrawabletext/EditDrawableText.kt

Lines changed: 127 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,49 @@
11
package com.mindorks.editdrawabletext
22

33
import android.content.Context
4+
import android.content.res.TypedArray
45
import android.graphics.Rect
56
import android.graphics.drawable.Drawable
7+
import android.text.Editable
8+
import android.text.TextWatcher
69
import android.util.AttributeSet
710
import android.view.MotionEvent
811
import android.widget.EditText
912
import kotlin.math.abs
1013

11-
class EditDrawableText : EditText {
14+
class EditDrawableText(context: Context, attrs: AttributeSet) : EditText(context, attrs) {
1215

1316
private var drawableRight: Drawable? = null
1417
private var drawableLeft: Drawable? = null
1518
private var drawableTop: Drawable? = null
1619
private var drawableBottom: Drawable? = null
1720
private var positionX: Int = 0
1821
private var positionY: Int = 0
19-
22+
private var isDrawableShownWhenTextIsEmpty = true
2023
private var onDrawableClickListener: OnDrawableClickListener? = null
2124

22-
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
2325

24-
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
26+
init {
27+
parseAttributes(
28+
context.obtainStyledAttributes(
29+
attrs,
30+
R.styleable.EditDrawableText
31+
)
32+
)
33+
}
34+
35+
36+
private fun parseAttributes(obtainStyledAttributes: TypedArray) {
37+
isDrawableShownWhenTextIsEmpty = obtainStyledAttributes.getBoolean(R.styleable.EditDrawableText_isDrawableShownWhenTextIsEmpty, isDrawableShownWhenTextIsEmpty);
38+
obtainStyledAttributes.recycle()
39+
hasDrawable(isDrawableShownWhenTextIsEmpty)
40+
}
41+
42+
private fun hasDrawable(value: Boolean) {
43+
isDrawableShownWhenTextIsEmpty = value
44+
if (!isDrawableShownWhenTextIsEmpty) this.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
45+
invalidate()
46+
}
2547

2648
override fun setCompoundDrawables(leftDrawable: Drawable?,
2749
topDrawable: Drawable?,
@@ -33,106 +55,129 @@ class EditDrawableText : EditText {
3355
if (bottomDrawable != null) drawableBottom = bottomDrawable
3456
super.setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable)
3557
}
36-
58+
3759
override fun onTouchEvent(event: MotionEvent): Boolean {
3860
var bounds: Rect?
39-
if (event.action == MotionEvent.ACTION_DOWN) {
40-
positionX = event.x.toInt()
41-
positionY = event.y.toInt()
42-
43-
44-
// this works for left since container shares 0,0 origin with bounds
45-
if (drawableLeft != null) {
46-
bounds = drawableLeft!!.bounds
47-
48-
var xClickPosition: Int
49-
var yClickPosition: Int
50-
/*
51-
* @return pixels into dp
52-
*/
53-
val extraClickArea = (13 * resources.displayMetrics.density + 0.5).toInt()
61+
val editText = this
62+
this.addTextChangedListener(object : TextWatcher {
63+
override fun afterTextChanged(p0: Editable?) {
5464

55-
xClickPosition = positionX
56-
yClickPosition = positionY
65+
}
5766

58-
if (!bounds!!.contains(positionX, positionY)) {
59-
/** Gives some extra space for tapping. */
60-
xClickPosition = positionX - extraClickArea
61-
yClickPosition = positionY - extraClickArea
67+
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
68+
}
6269

63-
if (xClickPosition <= 0) xClickPosition = positionX
64-
if (yClickPosition <= 0) yClickPosition = positionY
70+
override fun onTextChanged(char: CharSequence, p1: Int, p2: Int, p3: Int) {
71+
if (char.isEmpty()) {
72+
if (!isDrawableShownWhenTextIsEmpty) editText.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
73+
} else editText.setCompoundDrawables(drawableLeft, drawableTop, drawableRight, drawableBottom)
74+
}
6575

66-
/** Creates square from the smallest value from x or y*/
67-
if (xClickPosition < yClickPosition) yClickPosition = xClickPosition
68-
}
6976

70-
if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
71-
onDrawableClickListener!!.onClick(DrawablePosition.LEFT)
72-
event.action = MotionEvent.ACTION_CANCEL
73-
return false
77+
})
78+
if (event.action == MotionEvent.ACTION_DOWN) {
79+
positionX = event.x.toInt()
80+
positionY = event.y.toInt()
7481

75-
}
82+
// this works for left since container shares 0,0 origin with bounds
83+
if (drawableLeft != null) {
84+
bounds = drawableLeft?.bounds
85+
setupDrawableLeftClick(bounds, event)
7686
}
77-
87+
7888
if (drawableRight != null) {
79-
bounds = drawableRight!!.bounds
80-
var xClickPosition: Int
81-
var yClickPosition: Int
82-
val extraClickingArea = 13
83-
84-
xClickPosition = positionX + extraClickingArea
85-
yClickPosition = positionY - extraClickingArea
86-
87-
/**
88-
* It right drawable -> subtract the value of x from the width of view. so that width - tapped area * will result in x co-ordinate in drawable bound.
89-
*/
90-
xClickPosition = width - xClickPosition
91-
if (xClickPosition <= 0) xClickPosition += extraClickingArea
92-
93-
/* If after calculating for extra clickable area is negative.
94-
* assign the original value so that after subtracting
95-
* extra clicking area value doesn't go into negative value.
96-
*/
97-
98-
if (yClickPosition <= 0) yClickPosition = positionY
99-
100-
/**If drawable bounds contains the x and y points then move ahead. */
101-
if (bounds!!.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
102-
onDrawableClickListener!!.onClick(DrawablePosition.RIGHT)
103-
event.action = MotionEvent.ACTION_CANCEL
104-
return false
105-
}
106-
return super.onTouchEvent(event)
89+
bounds = drawableRight?.bounds
90+
setupDrawableRightClick(bounds, event)
10791
}
10892

10993
if (drawableTop != null) {
110-
bounds = drawableTop!!.bounds
111-
val extraClickingArea = 13
112-
if (abs((width - paddingLeft - paddingRight) / 2 + paddingLeft - positionX) <= bounds.width() / 2 + extraClickingArea) {
113-
onDrawableClickListener!!.onClick(DrawablePosition.TOP)
114-
event.action = MotionEvent.ACTION_CANCEL
115-
return false
116-
}
94+
bounds = drawableTop?.bounds
95+
setupDrawableTopClick(bounds, event)
11796
}
11897

119-
if(drawableBottom!=null)
120-
{
121-
bounds = drawableBottom!!.bounds
122-
val extraClickingArea = 13
123-
124-
if (abs((width - paddingLeft - paddingRight) / 2 + paddingLeft - positionX) <= bounds.width() / 2 + extraClickingArea) {
125-
onDrawableClickListener!!.onClick(DrawablePosition.BOTTOM)
126-
event.action = MotionEvent.ACTION_CANCEL
127-
return false
128-
}
98+
if (drawableBottom != null) {
99+
bounds = drawableBottom?.bounds
100+
setupDrawableBottomClick(bounds, event)
129101
}
130102

131103

132104
}
133105
return super.onTouchEvent(event)
134106
}
135107

108+
private fun setupDrawableBottomClick(bounds: Rect?, event: MotionEvent) {
109+
val extraClickingArea = 13
110+
if (abs((width - paddingLeft - paddingRight) / 2 + paddingLeft - positionX) <= bounds!!.width() / 2 + extraClickingArea) {
111+
onDrawableClickListener?.onClick(DrawablePosition.BOTTOM)
112+
event.action = MotionEvent.ACTION_CANCEL
113+
}
114+
}
115+
116+
private fun setupDrawableTopClick(bounds: Rect?, event: MotionEvent) {
117+
val extraClickingArea = 13
118+
if (abs((width - paddingLeft - paddingRight) / 2 + paddingLeft - positionX) <= bounds!!.width() / 2 + extraClickingArea) {
119+
onDrawableClickListener?.onClick(DrawablePosition.TOP)
120+
event.action = MotionEvent.ACTION_CANCEL
121+
}
122+
}
123+
124+
private fun setupDrawableLeftClick(bounds: Rect?, event: MotionEvent) {
125+
var xClickPosition: Int
126+
var yClickPosition: Int
127+
/*
128+
* @return pixels into dp
129+
*/
130+
val extraClickArea = (13 * resources.displayMetrics.density + 0.5).toInt()
131+
132+
xClickPosition = positionX
133+
yClickPosition = positionY
134+
135+
if (!bounds!!.contains(positionX, positionY)) {
136+
/** Gives some extra space for tapping. */
137+
xClickPosition = positionX - extraClickArea
138+
yClickPosition = positionY - extraClickArea
139+
140+
if (xClickPosition <= 0) xClickPosition = positionX
141+
if (yClickPosition <= 0) yClickPosition = positionY
142+
143+
/** Creates square from the smallest value from x or y*/
144+
if (xClickPosition < yClickPosition) yClickPosition = xClickPosition
145+
}
146+
147+
if (bounds.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
148+
onDrawableClickListener?.onClick(DrawablePosition.LEFT)
149+
event.action = MotionEvent.ACTION_CANCEL
150+
151+
}
152+
}
153+
154+
private fun setupDrawableRightClick(bounds: Rect?, event: MotionEvent) {
155+
var xClickPosition: Int
156+
var yClickPosition: Int
157+
val extraClickingArea = 13
158+
159+
xClickPosition = positionX + extraClickingArea
160+
yClickPosition = positionY - extraClickingArea
161+
162+
/**
163+
* It right drawable -> subtract the value of x from the width of view. so that width - tapped area * will result in x co-ordinate in drawable bound.
164+
*/
165+
xClickPosition = width - xClickPosition
166+
if (xClickPosition <= 0) xClickPosition += extraClickingArea
167+
168+
/* If after calculating for extra clickable area is negative.
169+
* assign the original value so that after subtracting
170+
* extra clicking area value doesn't go into negative value.
171+
*/
172+
173+
if (yClickPosition <= 0) yClickPosition = positionY
174+
175+
/**If drawable bounds contains the x and y points then move ahead. */
176+
if (bounds!!.contains(xClickPosition, yClickPosition) && onDrawableClickListener != null) {
177+
onDrawableClickListener?.onClick(DrawablePosition.RIGHT)
178+
event.action = MotionEvent.ACTION_CANCEL
179+
}
180+
}
136181

137182
fun setDrawableClickListener(OnDrawableClickListener: OnDrawableClickListener) {
138183
this.onDrawableClickListener = OnDrawableClickListener
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources>
3+
<declare-styleable name="EditDrawableText">
4+
<attr name="isDrawableShownWhenTextIsEmpty" format="boolean"/>
5+
</declare-styleable>
6+
</resources>

0 commit comments

Comments
 (0)