11package  com.mindorks.editdrawabletext 
22
33import  android.content.Context 
4+ import  android.content.res.TypedArray 
45import  android.graphics.Rect 
56import  android.graphics.drawable.Drawable 
7+ import  android.text.Editable 
8+ import  android.text.TextWatcher 
69import  android.util.AttributeSet 
710import  android.view.MotionEvent 
811import  android.widget.EditText 
912import  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+  private  fun  parseAttributes (obtainStyledAttributes :  TypedArray ) {
36+  isDrawableShownWhenTextIsEmpty =  obtainStyledAttributes.getBoolean(R .styleable.EditDrawableText_isDrawableShownWhenTextIsEmpty , isDrawableShownWhenTextIsEmpty);
37+  obtainStyledAttributes.recycle()
38+  hasDrawable(isDrawableShownWhenTextIsEmpty)
39+  }
40+ 41+  fun  hasDrawable (value :  Boolean ) {
42+  isDrawableShownWhenTextIsEmpty =  value
43+  if  (! isDrawableShownWhenTextIsEmpty) this .setCompoundDrawablesWithIntrinsicBounds(0 , 0 , 0 , 0 )
44+  invalidate()
45+  }
2546
2647 override  fun  setCompoundDrawables (leftDrawable :  Drawable ? ,
2748 topDrawable :  Drawable ? ,
@@ -33,106 +54,129 @@ class EditDrawableText : EditText {
3354 if  (bottomDrawable !=  null ) drawableBottom =  bottomDrawable
3455 super .setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable)
3556 }
36- 
57+ 3758 override  fun  onTouchEvent (event :  MotionEvent ): Boolean  {
3859 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
60+  val  editText =  this 
61+  this .addTextChangedListener(object  :  TextWatcher  {
62+  override  fun  afterTextChanged (p0 :  Editable ? ) {
4763
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()
54- 55-  xClickPosition =  positionX
56-  yClickPosition =  positionY
64+  }
5765
58-  if  (! bounds!! .contains(positionX, positionY)) {
59-  /* * Gives some extra space for tapping. */ 
60-  xClickPosition =  positionX -  extraClickArea
61-  yClickPosition =  positionY -  extraClickArea
66+  override  fun  beforeTextChanged (p0 :  CharSequence? , p1 :  Int , p2 :  Int , p3 :  Int ) {
67+  }
6268
63-  if  (xClickPosition <=  0 ) xClickPosition =  positionX
64-  if  (yClickPosition <=  0 ) yClickPosition =  positionY
69+  override  fun  onTextChanged (char :  CharSequence , p1 :  Int , p2 :  Int , p3 :  Int ) {
70+  if  (char.isEmpty()) {
71+  if  (! isDrawableShownWhenTextIsEmpty) editText.setCompoundDrawablesWithIntrinsicBounds(0 , 0 , 0 , 0 )
72+  } else  editText.setCompoundDrawables(drawableLeft, drawableTop, drawableRight, drawableBottom)
73+  }
6574
66-  /* * Creates square from the smallest value from x or y*/ 
67-  if  (xClickPosition <  yClickPosition) yClickPosition =  xClickPosition
68-  }
6975
70-  if  (bounds.contains(xClickPosition, yClickPosition)  &&  onDrawableClickListener  != null ) { 
71-   onDrawableClickListener !! .onClick( DrawablePosition . LEFT ) 
72-  event.action  = MotionEvent . ACTION_CANCEL 
73-  return false 
76+  }) 
77+  if  (event.action  == MotionEvent . ACTION_DOWN ) { 
78+  positionX  = event.x.toInt() 
79+  positionY  =  event.y.toInt() 
7480
75-  }
81+  //  this works for left since container shares 0,0 origin with bounds
82+  if  (drawableLeft !=  null ) {
83+  bounds =  drawableLeft?.bounds
84+  setupDrawableLeftClick(bounds, event)
7685 }
77- 
86+ 7887 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)
88+  bounds =  drawableRight?.bounds
89+  setupDrawableRightClick(bounds, event)
10790 }
10891
10992 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-  }
93+  bounds =  drawableTop?.bounds
94+  setupDrawableTopClick(bounds, event)
11795 }
11896
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-  }
97+  if  (drawableBottom !=  null ) {
98+  bounds =  drawableBottom?.bounds
99+  setupDrawableBottomClick(bounds, event)
129100 }
130101
131102
132103 }
133104 return  super .onTouchEvent(event)
134105 }
135106
107+  private  fun  setupDrawableBottomClick (bounds :  Rect ? , event :  MotionEvent ) {
108+  val  extraClickingArea =  13 
109+  if  (abs((width -  paddingLeft -  paddingRight) /  2  +  paddingLeft -  positionX) <=  bounds!! .width() /  2  +  extraClickingArea) {
110+  onDrawableClickListener?.onClick(DrawablePosition .BOTTOM )
111+  event.action =  MotionEvent .ACTION_CANCEL 
112+  }
113+  }
114+ 115+  private  fun  setupDrawableTopClick (bounds :  Rect ? , event :  MotionEvent ) {
116+  val  extraClickingArea =  13 
117+  if  (abs((width -  paddingLeft -  paddingRight) /  2  +  paddingLeft -  positionX) <=  bounds!! .width() /  2  +  extraClickingArea) {
118+  onDrawableClickListener?.onClick(DrawablePosition .TOP )
119+  event.action =  MotionEvent .ACTION_CANCEL 
120+  }
121+  }
122+ 123+  private  fun  setupDrawableLeftClick (bounds :  Rect ? , event :  MotionEvent ) {
124+  var  xClickPosition:  Int 
125+  var  yClickPosition:  Int 
126+  /* 
127+  * @return pixels into dp 
128+  */  
129+  val  extraClickArea =  (13  *  resources.displayMetrics.density +  0.5 ).toInt()
130+ 131+  xClickPosition =  positionX
132+  yClickPosition =  positionY
133+ 134+  if  (! bounds!! .contains(positionX, positionY)) {
135+  /* * Gives some extra space for tapping. */ 
136+  xClickPosition =  positionX -  extraClickArea
137+  yClickPosition =  positionY -  extraClickArea
138+ 139+  if  (xClickPosition <=  0 ) xClickPosition =  positionX
140+  if  (yClickPosition <=  0 ) yClickPosition =  positionY
141+ 142+  /* * Creates square from the smallest value from x or y*/ 
143+  if  (xClickPosition <  yClickPosition) yClickPosition =  xClickPosition
144+  }
145+ 146+  if  (bounds.contains(xClickPosition, yClickPosition) &&  onDrawableClickListener !=  null ) {
147+  onDrawableClickListener?.onClick(DrawablePosition .LEFT )
148+  event.action =  MotionEvent .ACTION_CANCEL 
149+ 150+  }
151+  }
152+ 153+  private  fun  setupDrawableRightClick (bounds :  Rect ? , event :  MotionEvent ) {
154+  var  xClickPosition:  Int 
155+  var  yClickPosition:  Int 
156+  val  extraClickingArea =  13 
157+ 158+  xClickPosition =  positionX +  extraClickingArea
159+  yClickPosition =  positionY -  extraClickingArea
160+ 161+  /* *
162+  * 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. 
163+  */  
164+  xClickPosition =  width -  xClickPosition
165+  if  (xClickPosition <=  0 ) xClickPosition + =  extraClickingArea
166+ 167+  /*  If after calculating for extra clickable area is negative.
168+  * assign the original value so that after subtracting 
169+  * extra clicking area value doesn't go into negative value. 
170+  */  
171+ 172+  if  (yClickPosition <=  0 ) yClickPosition =  positionY
173+ 174+  /* *If drawable bounds contains the x and y points then move ahead. */ 
175+  if  (bounds!! .contains(xClickPosition, yClickPosition) &&  onDrawableClickListener !=  null ) {
176+  onDrawableClickListener?.onClick(DrawablePosition .RIGHT )
177+  event.action =  MotionEvent .ACTION_CANCEL 
178+  }
179+  }
136180
137181 fun  setDrawableClickListener (OnDrawableClickListener :  OnDrawableClickListener ) {
138182 this .onDrawableClickListener =  OnDrawableClickListener 
0 commit comments