Skip to content

Commit

Permalink
优化 OperationEditTextLayout 属性名称
Browse files Browse the repository at this point in the history
新增 OperationEditText控件 增加多种选择
  • Loading branch information
ooftf committed Jan 5, 2018
1 parent e6e957c commit 1788013
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 55 deletions.
28 changes: 12 additions & 16 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,22 @@
<com.ooftf.operation.OperationEditTextLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:delOperationEnabled="true"
app:maskOperationEnabled="true"
app:oprationPaddingRight="10dp">
app:oetl_delEnabled="true"
app:oetl_maskEnabled="true"
app:oetl_oprationPaddingRight="10dp">

<EditText
android:hint="请输入密码"
android:paddingLeft="16dp"
android:layout_width="match_parent"
android:layout_height="48dp" />
android:layout_height="48dp"
android:hint="请输入密码"
android:paddingLeft="16dp" />
</com.ooftf.operation.OperationEditTextLayout>

<com.ooftf.operation.OperationEditTextLayout
<com.ooftf.operation.OperationEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:delOperationEnabled="true"
app:maskOperationEnabled="true">

<EditText
android:paddingLeft="16dp"
android:layout_width="match_parent"
android:layout_height="48dp" />
</com.ooftf.operation.OperationEditTextLayout>
android:layout_height="48dp"
android:paddingLeft="16dp"
app:oet_delEnabled="true"
app:oet_drawableMargin="8dp"
app:oet_maskEnabled="false" />
</LinearLayout>
178 changes: 178 additions & 0 deletions lib/src/main/java/com/ooftf/operation/OperationEditText.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package com.ooftf.operation

import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.text.method.PasswordTransformationMethod
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.EditText

/**
* Created by 99474 on 2018/1/5 0005.
*/
class OperationEditText : EditText {
private var drawableShowId = R.drawable.vector_drawable_attention_fill
private var drawableHideId = R.drawable.vector_drawable_attention_forbid_fill
private var drawableDelId = R.drawable.vector_icon_del
private var maskEnabled = false
private var delEnabled = false
private var drawableMaskSize = dip2px(context, 24f)
private var drawableDelSize = dip2px(context, 20f)
private var drawableMargin = dip2px(context, 8f)

constructor(context: Context?) : super(context)

constructor(context: Context?, attrs: AttributeSet) : super(context, attrs) {
obtainAttrs(attrs)
}

constructor(context: Context?, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
obtainAttrs(attrs)
}

constructor(context: Context?, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {
obtainAttrs(attrs)
}

private fun obtainAttrs(attrs: AttributeSet) {
val attrsArray = context.obtainStyledAttributes(attrs, R.styleable.OperationEditText)
drawableShowId = attrsArray.getResourceId(R.styleable.OperationEditText_oet_drawableShow, drawableShowId)
drawableHideId = attrsArray.getResourceId(R.styleable.OperationEditText_oet_drawableHide, drawableHideId)
drawableDelId = attrsArray.getResourceId(R.styleable.OperationEditText_oet_drawableDel, drawableDelId)
maskEnabled = attrsArray.getBoolean(R.styleable.OperationEditText_oet_maskEnabled, maskEnabled)
delEnabled = attrsArray.getBoolean(R.styleable.OperationEditText_oet_delEnabled, delEnabled)
drawableMaskSize = attrsArray.getDimension(R.styleable.OperationEditText_oet_maskDrawableSize, drawableMaskSize)
drawableDelSize = attrsArray.getDimension(R.styleable.OperationEditText_oet_delDrawableSize, drawableDelSize)
drawableMargin = attrsArray.getDimension(R.styleable.OperationEditText_oet_drawableMargin, drawableMargin)
attrsArray.recycle()
maskPassword()
}

override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
drawDel(canvas)
drawMask(canvas)
}

private fun drawDel(canvas: Canvas) {
if (!delEnabled) return
if (length() == 0) return
val drawable = context.resources.getDrawable(drawableDelId)
drawable.setBounds(getDelDrawRect())
drawable.draw(canvas)
}

private fun drawMask(canvas: Canvas) {
if (!maskEnabled) return
if (length() == 0) return
val drawable = if (isMaskPssword()) {
context.resources.getDrawable(drawableHideId)
} else {
context.resources.getDrawable(drawableShowId)
}
drawable.setBounds(getMaskDrawRect())
drawable.draw(canvas)
}

fun getDelDrawRect(): Rect {
val left = width - paddingRight - drawableDelSize
val top = height / 2 - drawableDelSize / 2
val right = width - paddingRight
val bottom = height / 2 + drawableDelSize / 2
return Rect(left.toInt(), top.toInt(), right, bottom.toInt())
}

fun getMaskDrawRect() =
if (delEnabled) {
val left = width - paddingRight - drawableDelSize - drawableMargin - drawableMaskSize
val top = height / 2 - drawableMaskSize / 2
val right = width - paddingRight - drawableDelSize - drawableMargin
val bottom = height / 2 + drawableMaskSize / 2
Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
} else {
val left = width - paddingRight - drawableMaskSize
val top = height / 2 - drawableMaskSize / 2
val right = width - paddingRight
val bottom = height / 2 + drawableMaskSize / 2
Rect(left.toInt(), top.toInt(), right, bottom.toInt())
}

fun getDelTouchRect(): Rect {
val left = width - paddingRight - drawableDelSize - drawableMargin / 2
val top = height / 2 - drawableDelSize / 2 - drawableMargin / 2
val right = width - paddingRight + drawableMargin / 2
val bottom = height / 2 + drawableDelSize / 2 + drawableMargin / 2
return Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
}

fun getMaskTouchRect() =
if (delEnabled) {
val left = width - paddingRight - drawableDelSize - drawableMargin - drawableMaskSize - drawableMargin / 2
val top = height / 2 - drawableMaskSize / 2 - drawableMargin / 2
val right = width - paddingRight - drawableDelSize - drawableMargin + drawableMargin / 2
val bottom = height / 2 + drawableMaskSize / 2 + drawableMargin / 2
Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
} else {
val left = width - paddingRight - drawableMaskSize - drawableMargin / 2
val top = height / 2 - drawableMaskSize / 2 - drawableMargin / 2
val right = width - paddingRight + drawableMargin / 2
val bottom = height / 2 + drawableMaskSize / 2 + drawableMargin / 2
Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
}

fun isMaskPssword() = transformationMethod != null
private fun maskPassword() {
if (!maskEnabled) return
transformationMethod = PasswordTransformationMethod.getInstance()
}

private fun unmaskPassword() {
if (!maskEnabled) return
transformationMethod = null
}

var clickMask = false
var clickDel = false
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
clickMask = maskEnabled && getMaskTouchRect().contains(event.getX().toInt(), event.getY().toInt())
clickDel = delEnabled && getDelTouchRect().contains(event.getX().toInt(), event.getY().toInt())
}
MotionEvent.ACTION_MOVE -> {
clickMask = clickMask && getMaskTouchRect().contains(event.getX().toInt(), event.getY().toInt())
clickDel = clickDel && getDelTouchRect().contains(event.getX().toInt(), event.getY().toInt())
}
MotionEvent.ACTION_UP -> {
if (clickMask && getMaskTouchRect().contains(event.getX().toInt(), event.getY().toInt())) {
performMaskClick()
}
if (clickDel && getDelTouchRect().contains(event.getX().toInt(), event.getY().toInt())) {
performDelClick()
}
}
}
return super.onTouchEvent(event)
}

private fun performDelClick() {
text.clear()
}

private fun performMaskClick() {
if (isMaskPssword()) {
unmaskPassword()
} else {
maskPassword()
}
}

/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
fun dip2px(context: Context, dpValue: Float): Float {
val scale = context.resources.displayMetrics.density
return dpValue * scale
}
}
52 changes: 20 additions & 32 deletions lib/src/main/java/com/ooftf/operation/OperationEditTextLayout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,34 +32,34 @@ class OperationEditTextLayout : RelativeLayout {
obtainAttrs(attrs)
}

private var iconShowId = R.drawable.vector_drawable_attention_fill
private var iconHideId = R.drawable.vector_drawable_attention_forbid_fill
private var iconDelId = R.drawable.vector_icon_del
private var drawableShowId = R.drawable.vector_drawable_attention_fill
private var drawableHideId = R.drawable.vector_drawable_attention_forbid_fill
private var drawableDelId = R.drawable.vector_icon_del
private var maskOperationEnabled = false
private var delOperationEnabled = false
private var editTextId = -1;
private var oprationPaddingRight = 0f;
private lateinit var editText: EditText
private fun obtainAttrs(attrs: AttributeSet) {
val attrsArray = context.obtainStyledAttributes(attrs, R.styleable.OperationEditTextLayout)
iconShowId = attrsArray.getResourceId(R.styleable.OperationEditTextLayout_icon_show, R.drawable.vector_drawable_attention_fill)
iconHideId = attrsArray.getResourceId(R.styleable.OperationEditTextLayout_icon_hide, R.drawable.vector_drawable_attention_forbid_fill)
iconDelId = attrsArray.getResourceId(R.styleable.OperationEditTextLayout_icon_del, R.drawable.vector_icon_del)
maskOperationEnabled = attrsArray.getBoolean(R.styleable.OperationEditTextLayout_maskOperationEnabled, false)
delOperationEnabled = attrsArray.getBoolean(R.styleable.OperationEditTextLayout_delOperationEnabled, false)
editTextId = attrsArray.getResourceId(R.styleable.OperationEditTextLayout_editTextId, -1)
oprationPaddingRight = attrsArray.getDimension(R.styleable.OperationEditTextLayout_oprationPaddingRight,0f)
drawableShowId = attrsArray.getResourceId(R.styleable.OperationEditTextLayout_oetl_drawableShow, drawableShowId)
drawableHideId = attrsArray.getResourceId(R.styleable.OperationEditTextLayout_oetl_drawableHide, drawableHideId)
drawableDelId = attrsArray.getResourceId(R.styleable.OperationEditTextLayout_oetl_drawableDel, drawableDelId)
maskOperationEnabled = attrsArray.getBoolean(R.styleable.OperationEditTextLayout_oetl_maskEnabled, maskOperationEnabled)
delOperationEnabled = attrsArray.getBoolean(R.styleable.OperationEditTextLayout_oetl_delEnabled, delOperationEnabled)
editTextId = attrsArray.getResourceId(R.styleable.OperationEditTextLayout_oetl_editTextId, editTextId)
oprationPaddingRight = attrsArray.getDimension(R.styleable.OperationEditTextLayout_oetl_oprationPaddingRight, oprationPaddingRight)
attrsArray.recycle()

}

override fun onFinishInflate() {
super.onFinishInflate()
if(editTextId != -1){
if (editTextId != -1) {
editText = findViewById(editTextId)
}else if(getChildAt(0) is EditText){
} else if (getChildAt(0) is EditText) {
editText = getChildAt(0) as EditText
}else{
} else {
throw IllegalAccessException("OperationEditTextLayout 未找到EditText节点")
}
initViews()
Expand Down Expand Up @@ -96,7 +96,7 @@ class OperationEditTextLayout : RelativeLayout {
}

private fun toggleMaskState() {
if (maskPassword) {
if (isMaskPassword()) {
unmaskPassword()
} else {
maskPassword()
Expand All @@ -109,18 +109,11 @@ class OperationEditTextLayout : RelativeLayout {
} else {
maskView.visibility = View.GONE
}
calculatePadding()
}

private fun calculatePadding() {
/* if (delView.left > 0) {
editText.setPadding(editText.paddingLeft, editText.paddingTop, editText.width - delView.left, editText.paddingBottom)
}*/
}

fun hideMaskOperation() {
maskView.visibility = View.GONE
calculatePadding()
}

fun showDelOperation() {
Expand All @@ -129,31 +122,28 @@ class OperationEditTextLayout : RelativeLayout {
} else {
delView.visibility = View.GONE
}
calculatePadding()
}

fun hideDelOperation() {
delView.visibility = View.GONE
calculatePadding()
}


lateinit var delView: ImageView
lateinit var maskView: ImageView
var maskPassword = true
private fun initViews() {
LayoutInflater.from(context).inflate(R.layout.layout_edit_operation, this)
var container = findViewById<ViewGroup>(R.id.container)
container.setPadding(container.left,container.top,oprationPaddingRight.toInt(),container.bottom);
container.setPadding(container.left, container.top, oprationPaddingRight.toInt(), container.bottom);
delView = findViewById(R.id.del)
maskView = findViewById(R.id.mask)
delView.setImageResource(iconDelId)
maskView.setImageResource(iconHideId)
delView.setImageResource(drawableDelId)
maskView.setImageResource(drawableHideId)
visibleControl()
maskPassword = editText.transformationMethod != null
maskPassword()
}

fun isMaskPassword() = editText.transformationMethod != null
private fun visibleControl() {
if (editText.text.isNotEmpty()) {
showMaskOperation()
Expand All @@ -166,17 +156,15 @@ class OperationEditTextLayout : RelativeLayout {

private fun maskPassword() {
if (!maskOperationEnabled) return
maskPassword = true
maskView.setImageResource(iconHideId)
maskView.setImageResource(drawableHideId)
var selection = editText.selectionStart
editText.transformationMethod = PasswordTransformationMethod.getInstance()
editText.setSelection(selection)
}

private fun unmaskPassword() {
if (!maskOperationEnabled) return
maskPassword = false
maskView.setImageResource(iconShowId)
maskView.setImageResource(drawableShowId)
var selection = editText.selectionStart
editText.transformationMethod = null
editText.setSelection(selection)
Expand Down
25 changes: 18 additions & 7 deletions lib/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="OperationEditTextLayout">
<attr name="icon_hide" format="reference"/>
<attr name="icon_show" format="reference"/>
<attr name="icon_del" format="reference"/>
<attr name="oprationPaddingRight" format="dimension"/>
<attr name="maskOperationEnabled" format="boolean"/>
<attr name="delOperationEnabled" format="boolean"/>
<attr name="editTextId" format="reference"/>
<attr name="oetl_drawableHide" format="reference" />
<attr name="oetl_drawableShow" format="reference" />
<attr name="oetl_drawableDel" format="reference" />
<attr name="oetl_oprationPaddingRight" format="dimension" />
<attr name="oetl_maskEnabled" format="boolean" />
<attr name="oetl_delEnabled" format="boolean" />
<attr name="oetl_editTextId" format="reference" />
</declare-styleable>
<declare-styleable name="OperationEditText">
<attr name="oet_drawableHide" format="reference" />
<attr name="oet_drawableShow" format="reference" />
<attr name="oet_drawableDel" format="reference" />
<attr name="oet_delDrawableSize" format="dimension" />
<attr name="oet_maskDrawableSize" format="dimension" />
<attr name="oet_drawableMargin" format="dimension" />
<attr name="oet_maskEnabled" format="boolean" />
<attr name="oet_delEnabled" format="boolean" />

</declare-styleable>
</resources>

0 comments on commit 1788013

Please sign in to comment.