diff --git a/app/build.gradle b/app/build.gradle
index e925a11..36faca2 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,7 +7,7 @@ apply plugin: 'kotlin-android-extensions'
ext {
PUBLISH_GROUP_ID = 'com.poovam'
PUBLISH_ARTIFACT_ID = 'pin-edittext-field'
- PUBLISH_VERSION = '1.0.9'
+ PUBLISH_VERSION = '1.1.0'
}
android {
diff --git a/app/src/main/java/com/poovam/pinedittextfield/CirclePinField.kt b/app/src/main/java/com/poovam/pinedittextfield/CirclePinField.kt
index 8094378..ed7a5ff 100644
--- a/app/src/main/java/com/poovam/pinedittextfield/CirclePinField.kt
+++ b/app/src/main/java/com/poovam/pinedittextfield/CirclePinField.kt
@@ -5,6 +5,8 @@ import android.graphics.Canvas
import android.graphics.Paint
import android.support.v4.content.ContextCompat
import android.util.AttributeSet
+import android.view.View
+import android.view.ViewGroup
/**
* Created by poovam-5255 on 5/23/2018.
@@ -14,7 +16,7 @@ import android.util.AttributeSet
*/
class CirclePinField: PinField{
- var fillerColor = ContextCompat.getColor(context,R.color.accent)
+ var fillerColor = ContextCompat.getColor(context,R.color.pinFieldLibraryAccent)
set(value){
field = value
fillerPaint.color = fillerColor
@@ -46,6 +48,7 @@ class CirclePinField: PinField{
try {
circleRadiusDp = a.getDimension(R.styleable.CirclePinField_circleRadius, circleRadiusDp)
fillerColor = a.getColor(R.styleable.CirclePinField_fillerColor, fillerColor)
+ if(distanceInBetween == DEFAULT_DISTANCE_IN_BETWEEN) distanceInBetween = Util.dpToPx(30f)
} finally {
a.recycle()
}
@@ -55,36 +58,80 @@ class CirclePinField: PinField{
fillerPaint.strokeWidth = circleRadiusDp
}
- override fun getDefaultDistanceInBetween(): Float{
- return (singleFieldWidth - (circleRadiusDp*2))*2
+ override fun getViewWidth(desiredWidth:Int, widthMeasureSpec: Int): Int {
+
+ val widthMode = View.MeasureSpec.getMode(widthMeasureSpec)
+ val widthSize = View.MeasureSpec.getSize(widthMeasureSpec)
+ val viewWidth = getCircleDiameterWithPadding() * numberOfFields
+ //Measure Width
+ return when (widthMode) {
+ MeasureSpec.EXACTLY -> widthSize
+ MeasureSpec.AT_MOST -> Math.min(viewWidth, widthSize)
+ MeasureSpec.UNSPECIFIED -> viewWidth
+ else -> viewWidth
+ }
+ }
+
+ private fun getCircleDiameterWithPadding():Int{
+ val diameter = circleRadiusDp*2
+ return Math.round(diameter + getThickness() + getPadding())
+ }
+
+ /**
+ * This will return thickness based on the chosen mode
+ * there will be a small padding even if distanceInBetween = 0dp if there is a highlight
+ * this is to make sure when highlighting there is no overlap
+ */
+ private fun getThickness(): Int{
+ return Math.round(if(isHighlightEnabled)highLightThickness else lineThickness)
+ }
+
+ private fun getPadding(): Float{
+ return if (distanceInBetween!= DEFAULT_DISTANCE_IN_BETWEEN) distanceInBetween else getDefaultDistanceInBetween()/2
}
override fun onDraw(canvas: Canvas?) {
for (i in 0 until numberOfFields){
+ var startingX = (width - (getCircleDiameterWithPadding()*numberOfFields))/2
- val padding = (if (distanceInBetween!= defDistanceInBetweenValue) distanceInBetween else getDefaultDistanceInBetween())/2
+ startingX = if(startingX > 0) startingX else 0
- val x1 = (padding+(circleRadiusDp*2))*i
+ val x1 = (getCircleDiameterWithPadding().toFloat() * i) + getCircleDiameterWithPadding()/2 + startingX
val character:Char? = text?.getOrNull(i)
+ val y1 = getViewHeight(height)
+
if(isHighlightEnabled && !highlightSingleFieldMode && hasFocus()){
- canvas?.drawCircle(x1+(singleFieldWidth/2).toFloat(),(height/2).toFloat(),circleRadiusDp, highlightPaint)
+ canvas?.drawCircle(x1,y1,circleRadiusDp, highlightPaint)
}else{
- canvas?.drawCircle(x1+(singleFieldWidth/2).toFloat(),(height/2).toFloat(),circleRadiusDp, fieldPaint)
+ canvas?.drawCircle(x1,y1,circleRadiusDp, fieldPaint)
}
if(character!=null) {
- canvas?.drawCircle(x1+(singleFieldWidth/2).toFloat(),(height/2).toFloat(),(circleRadiusDp/2)-highLightThickness, fillerPaint)
+ canvas?.drawCircle(x1,y1,(circleRadiusDp/2)-highLightThickness, fillerPaint)
}
if(hasFocus() && i == text?.length ?: 0){
if(isHighlightEnabled && highlightSingleFieldMode){
- canvas?.drawCircle(x1+(singleFieldWidth/2).toFloat(),(height/2).toFloat(),circleRadiusDp, highlightPaint)
+ canvas?.drawCircle(x1,y1,circleRadiusDp, highlightPaint)
}
}
}
}
+ /**
+ * This is a dirty hack since the height provided by Android framework seems same
+ * but drawing it on canvas seems to draw out of frame
+ * Need to look into this more
+ */
+ private fun getViewHeight(height: Int): Float{
+ if(!isCustomBackground && this.layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT
+ && getPadding() < circleRadiusDp){
+ return (height - getPadding()*1.5).toFloat()
+ }
+ return height/2.toFloat()
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/poovam/pinedittextfield/LinePinField.kt b/app/src/main/java/com/poovam/pinedittextfield/LinePinField.kt
index 8505d5d..76a04c8 100644
--- a/app/src/main/java/com/poovam/pinedittextfield/LinePinField.kt
+++ b/app/src/main/java/com/poovam/pinedittextfield/LinePinField.kt
@@ -15,24 +15,40 @@ class LinePinField : PinField {
private val cursorBottomPadding = Util.dpToPx(2f)
+ var bottomTextPaddingDp = 0f
+
+
constructor(context: Context): super(context)
- constructor(context: Context, attr: AttributeSet) : super(context,attr)
+ constructor(context: Context, attr: AttributeSet) : super(context,attr){
+ initParams(attr)
+ }
- constructor(context: Context, attr: AttributeSet, defStyle: Int) : super(context,attr,defStyle)
+ constructor(context: Context,attr: AttributeSet,defStyle: Int) : super(context,attr,defStyle){
+ initParams(attr)
+ }
+
+ private fun initParams(attr: AttributeSet){
+ val a = context.theme.obtainStyledAttributes(attr, R.styleable.LinePinField, 0,0)
+ try {
+ bottomTextPaddingDp = a.getDimension(R.styleable.LinePinField_bottomTextPaddingDp,bottomTextPaddingDp)
+ } finally {
+ a.recycle()
+ }
+ }
override fun onDraw(canvas: Canvas?) {
for (i in 0 until numberOfFields){
val x1 = (i*singleFieldWidth)
- val padding = (if (distanceInBetween!= defDistanceInBetweenValue) distanceInBetween else getDefaultDistanceInBetween())/2
+ val padding = (if (distanceInBetween!= DEFAULT_DISTANCE_IN_BETWEEN) distanceInBetween else getDefaultDistanceInBetween())/2
val paddedX1 = (x1 + padding)
val paddedX2 = ((x1+singleFieldWidth)-padding)
val paddedY1 = height - yPadding
val textX = ((paddedX2-paddedX1)/2)+paddedX1
- val textY = (paddedY1- lineThickness)-(textPaint.textSize/4)
- val character:Char? = text?.getOrNull(i)
+ val textY = (paddedY1- lineThickness)-(textPaint.textSize/4)-bottomTextPaddingDp
+ val character:Char? = transformationMethod?.getTransformation(text,this)?.getOrNull(i) ?: text.getOrNull(i)
if(isHighlightEnabled && !highlightSingleFieldMode && hasFocus()){
canvas?.drawLine(paddedX1,paddedY1,paddedX2,paddedY1, highlightPaint)
@@ -46,7 +62,7 @@ class LinePinField : PinField {
if(hasFocus() && i == text?.length ?: 0){
if(isCursorEnabled){
- val cursorY1 = paddedY1 - cursorBottomPadding - highLightThickness
+ val cursorY1 = paddedY1 - cursorBottomPadding - highLightThickness - bottomTextPaddingDp
val cursorY2 = cursorTopPadding
drawCursor(canvas,textX ,cursorY1,cursorY2,highlightPaint)
}
diff --git a/app/src/main/java/com/poovam/pinedittextfield/PinField.kt b/app/src/main/java/com/poovam/pinedittextfield/PinField.kt
index 5241b57..0d384e1 100644
--- a/app/src/main/java/com/poovam/pinedittextfield/PinField.kt
+++ b/app/src/main/java/com/poovam/pinedittextfield/PinField.kt
@@ -20,9 +20,11 @@ open class PinField : AppCompatEditText {
private val defaultWidth = Util.dpToPx(60f).toInt()
- protected val defDistanceInBetweenValue = -1f
+ companion object {
+ val DEFAULT_DISTANCE_IN_BETWEEN = -1f
+ }
- protected var distanceInBetween:Float = defDistanceInBetweenValue
+ protected var distanceInBetween:Float = DEFAULT_DISTANCE_IN_BETWEEN
set(value) {
field = value
requestLayout()
@@ -53,7 +55,7 @@ open class PinField : AppCompatEditText {
invalidate()
}
- var highlightPaintColor = ContextCompat.getColor(context,R.color.accent)
+ var highlightPaintColor = ContextCompat.getColor(context,R.color.pinFieldLibraryAccent)
set(value){
field = value
highlightPaint.color = field
@@ -87,7 +89,7 @@ open class PinField : AppCompatEditText {
var isCustomBackground = false
set(value) {
if(!value){
- setBackgroundResource(R.color.transparent)
+ setBackgroundResource(R.color.pinFieldLibraryTransparent)
}
field = value
}
@@ -136,7 +138,7 @@ open class PinField : AppCompatEditText {
try {
numberOfFields = a.getInt(R.styleable.PinField_noOfFields, numberOfFields)
lineThickness = a.getDimension(R.styleable.PinField_lineThickness, lineThickness)
- distanceInBetween = a.getDimension(R.styleable.PinField_distanceInBetween, defDistanceInBetweenValue)
+ distanceInBetween = a.getDimension(R.styleable.PinField_distanceInBetween, DEFAULT_DISTANCE_IN_BETWEEN)
fieldColor = a.getColor(R.styleable.PinField_fieldColor,fieldColor)
highlightPaintColor = a.getColor(R.styleable.PinField_highlightColor,highlightPaintColor)
isHighlightEnabled = a.getBoolean(R.styleable.PinField_highlightEnabled,isHighlightEnabled)
@@ -149,36 +151,35 @@ open class PinField : AppCompatEditText {
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ val width = getViewWidth(defaultWidth * numberOfFields,widthMeasureSpec)
+ singleFieldWidth = width/numberOfFields
+ setMeasuredDimension(width, getViewHeight(singleFieldWidth,heightMeasureSpec))
+ }
- val desiredWidth = (defaultWidth * numberOfFields)
+ open protected fun getViewWidth(desiredWidth:Int, widthMeasureSpec: Int): Int{
val widthMode = View.MeasureSpec.getMode(widthMeasureSpec)
val widthSize = View.MeasureSpec.getSize(widthMeasureSpec)
- val width: Int
//Measure Width
- width = when (widthMode) {
- View.MeasureSpec.EXACTLY -> widthSize
- View.MeasureSpec.AT_MOST -> Math.min(desiredWidth, widthSize)
- View.MeasureSpec.UNSPECIFIED -> desiredWidth
+ return when (widthMode) {
+ MeasureSpec.EXACTLY -> widthSize
+ MeasureSpec.AT_MOST -> Math.min(desiredWidth, widthSize)
+ MeasureSpec.UNSPECIFIED -> desiredWidth
else -> desiredWidth
}
- singleFieldWidth = width/numberOfFields
-
+ }
- val desiredHeight = singleFieldWidth
+ open protected fun getViewHeight(desiredHeight: Int, heightMeasureSpec: Int): Int{
val heightMode = View.MeasureSpec.getMode(heightMeasureSpec)
val heightSize = View.MeasureSpec.getSize(heightMeasureSpec)
- val height: Int
//Measure Height
- height = when (heightMode) {
+ return when (heightMode) {
View.MeasureSpec.EXACTLY -> heightSize
View.MeasureSpec.AT_MOST -> Math.min(desiredHeight, heightSize)
View.MeasureSpec.UNSPECIFIED -> desiredHeight
else -> desiredHeight
}
-
- setMeasuredDimension(width, height)
}
override fun onSelectionChanged(selStart: Int, selEnd: Int) {
@@ -232,6 +233,9 @@ open class PinField : AppCompatEditText {
}
interface OnTextCompleteListener {
+ /**
+ * @return return true if keyboard should be closed after text is entered
+ */
fun onTextComplete(enteredText: String): Boolean
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/poovam/pinedittextfield/SquarePinField.kt b/app/src/main/java/com/poovam/pinedittextfield/SquarePinField.kt
index a9025f4..95ce93b 100644
--- a/app/src/main/java/com/poovam/pinedittextfield/SquarePinField.kt
+++ b/app/src/main/java/com/poovam/pinedittextfield/SquarePinField.kt
@@ -2,6 +2,8 @@ package com.poovam.pinedittextfield
import android.content.Context
import android.graphics.Canvas
+import android.graphics.Paint
+import android.os.Build
import android.util.AttributeSet
/**
@@ -12,21 +14,39 @@ import android.util.AttributeSet
class SquarePinField : PinField{
+ private var cornerRadius = 0f
+ set(value) {
+ field = value
+ invalidate()
+ }
+
private val cursorPadding = Util.dpToPx(5f)
constructor(context: Context): super(context)
- constructor(context: Context, attr: AttributeSet) : super(context,attr)
+ constructor(context: Context, attr: AttributeSet) : super(context,attr){
+ initParams(attr)
+ }
- constructor(context: Context, attr: AttributeSet, defStyle: Int) : super(context,attr,defStyle)
+ constructor(context: Context, attr: AttributeSet, defStyle: Int) : super(context,attr,defStyle){
+ initParams(attr)
+ }
+ private fun initParams(attr: AttributeSet){
+ val a = context.theme.obtainStyledAttributes(attr, R.styleable.SquarePinField, 0,0)
+ try {
+ cornerRadius = a.getDimension(R.styleable.SquarePinField_cornerRadius, cornerRadius)
+ } finally {
+ a.recycle()
+ }
+ }
override fun onDraw(canvas: Canvas?) {
for (i in 0 until numberOfFields){
val x1 = (i*singleFieldWidth)
- val padding = (if (distanceInBetween!= defDistanceInBetweenValue) distanceInBetween else getDefaultDistanceInBetween())/2
+ val padding = (if (distanceInBetween!= DEFAULT_DISTANCE_IN_BETWEEN) distanceInBetween else getDefaultDistanceInBetween())/2
val paddedX1 = (x1 + padding)
val paddedX2 = ((x1+singleFieldWidth)-padding)
val squareHeight = paddedX2-paddedX1
@@ -34,12 +54,12 @@ class SquarePinField : PinField{
val paddedY2 = (height/2)+(squareHeight/2)
val textX = ((paddedX2-paddedX1)/2)+paddedX1
val textY = ((paddedY2-paddedY1)/2+paddedY1)+ lineThickness +(textPaint.textSize/4)
- val character:Char? = text?.getOrNull(i)
+ val character:Char? = transformationMethod?.getTransformation(text,this)?.getOrNull(i) ?: text.getOrNull(i)
if(isHighlightEnabled && !highlightSingleFieldMode && hasFocus()){
- canvas?.drawRect(paddedX1,paddedY1,paddedX2,paddedY2, highlightPaint)
+ drawRect(canvas,paddedX1,paddedY1,paddedX2,paddedY2, highlightPaint)
}else{
- canvas?.drawRect(paddedX1,paddedY1,paddedX2,paddedY2, fieldPaint)
+ drawRect(canvas,paddedX1,paddedY1,paddedX2,paddedY2, fieldPaint)
}
if(character!=null) {
@@ -54,9 +74,17 @@ class SquarePinField : PinField{
drawCursor(canvas,textX,cursorY1,cursorY2,highlightPaint)
}
if(isHighlightEnabled && highlightSingleFieldMode){
- canvas?.drawRect(paddedX1,paddedY1,paddedX2,paddedY2, highlightPaint)
+ drawRect(canvas,paddedX1,paddedY1,paddedX2,paddedY2, highlightPaint)
}
}
}
}
+
+ private fun drawRect(canvas: Canvas?,paddedX1:Float,paddedY1:Float,paddedX2:Float,paddedY2:Float,paint: Paint){
+ if(cornerRadius>0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
+ canvas?.drawRoundRect(paddedX1,paddedY1,paddedX2,paddedY2,cornerRadius,cornerRadius, paint)
+ }else{
+ canvas?.drawRect(paddedX1,paddedY1,paddedX2,paddedY2, paint)
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index 61f06a6..3808b3b 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -12,6 +12,14 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 02f0ac6..1a56559 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -1,6 +1,6 @@
- #FF4081
+ #FF4081
#808080
- #00000000
+ #00000000
diff --git a/sample/build.gradle b/sample/build.gradle
index 339d606..9404fff 100644
--- a/sample/build.gradle
+++ b/sample/build.gradle
@@ -34,5 +34,6 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
- compile 'com.poovam:pin-edittext-field:1.0.9'
+ compile 'com.poovam:pin-edittext-field:1.1.0'
+ //compile project(':app') //for library development purpose please ignore this line
}
diff --git a/sample/src/main/res/layout/activity_sample.xml b/sample/src/main/res/layout/activity_sample.xml
index 1f357e9..25b05d3 100644
--- a/sample/src/main/res/layout/activity_sample.xml
+++ b/sample/src/main/res/layout/activity_sample.xml
@@ -25,6 +25,7 @@
app:isCursorEnabled="true"
app:highlightSingleFieldMode="true"
android:id="@+id/squareField"
+ app:cornerRadius="10dp"
android:layout_marginTop="15dp"/>