自定义AppCompatEditText组件未初始化

时间:2018-11-06 06:00:10

标签: java android android-layout kotlin

我是Kotlin的新手,我正在尝试实现自定义图钉输入文本编辑字段,如this教程中所述。 我在Kotlin中重新编写了PinEntryEditText,并且没有抛出任何错误。我还添加了XML布局文件,并在MainActivity页面中使用了它。它运行并且不会引发任何错误。但是,它不会按预期显示。我开始尝试对其进行调试,并在每个类构造函数上设置3个断点。调试器不会在任何一个处停止,这使我认为它甚至永远也不会从那里消失。

现在,这是我的课程:

class PinEntryEditText : AppCompatEditText {
    private var mSpace = 24f //24 dp by default, space between the lines
    private var mCharSize: Float = 0.toFloat()
    private var mNumChars = 4f
    private var mLineSpacing = 8f //8dp by default, height of the text from our lines
    private var mMaxLength = 4f
    val XML_NAMESPACE_ANDROID = "http://schemas.android.com/apk/res/android"

    var mClickListener: View.OnClickListener? = null

    private var mLineStroke = 1f //1dp by default
    private var mLineStrokeSelected = 2f //2dp by default
    private var mLinesPaint: Paint? = null


    var mStates = arrayOf(intArrayOf(android.R.attr.state_selected), // selected
            intArrayOf(android.R.attr.state_focused), // focused
            intArrayOf(-android.R.attr.state_focused))// unfocused

    var mColors = intArrayOf(Color.GREEN, Color.BLACK, Color.GRAY)

    var mColorStates = ColorStateList(mStates, mColors)


    constructor(context: Context) : super(context) {
        this.setWillNotDraw(false)
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        this.setWillNotDraw(false)
        init(context, attrs)
    }

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
        this.setWillNotDraw(false)
        init(context, attrs)
    }

    private fun init(context: Context, attrs: AttributeSet) {
        val multi = context.resources.displayMetrics.density
        mLineStroke = (multi * mLineStroke)
        mLineStrokeSelected = (multi * mLineStrokeSelected)
        mLinesPaint = Paint(paint)
        mLinesPaint?.strokeWidth = mLineStroke.toFloat()
        if (!isInEditMode) {
            val outValue = TypedValue()
            context.theme.resolveAttribute(colorControlActivated,
                    outValue, true)
            val colorActivated = outValue.data
            mColors[0] = colorActivated

            context.theme.resolveAttribute(colorPrimaryDark,
                    outValue, true)
            val colorDark = outValue.data
            mColors[1] = colorDark

            context.theme.resolveAttribute(colorControlHighlight,
                    outValue, true)
            val colorHighlight = outValue.data
            mColors[2] = colorHighlight
        }
        setBackgroundResource(0)
        mSpace = (multi * mSpace) //convert to pixels for our density
        mLineSpacing = (multi * mLineSpacing) //convert to pixels for our density
        mMaxLength = attrs.getAttributeIntValue(XML_NAMESPACE_ANDROID, "maxLength", 4).toFloat()
        mNumChars = mMaxLength

        //Disable copy paste
        super.setCustomSelectionActionModeCallback(object : ActionMode.Callback {
            override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
                return false
            }

            override fun onDestroyActionMode(mode: ActionMode) {}

            override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
                return false
            }

            override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
                return false
            }
        })
        // When tapped, move cursor to end of text.
        super.setOnClickListener { v ->
            setSelection(text!!.length)
            if (mClickListener != null) {
                mClickListener?.onClick(v)
            }
        }

    }

    override fun setOnClickListener(l: View.OnClickListener?) {
        mClickListener = l
    }

    override fun setCustomSelectionActionModeCallback(actionModeCallback: ActionMode.Callback) {
        throw RuntimeException("setCustomSelectionActionModeCallback() not supported.")
    }

    override fun onDraw(canvas: Canvas) {
        //super.onDraw(canvas)
        val availableWidth = width - paddingRight - paddingLeft
        if (mSpace < 0) {
            mCharSize = availableWidth / (mNumChars * 2 - 1)
        } else {
            mCharSize = (availableWidth - mSpace * (mNumChars - 1)) / mNumChars
        }

        var startX = paddingLeft.toFloat()
        val bottom = height - paddingBottom

        //Text width
        val text = text
        val textLength = text!!.length
        val textWidths = FloatArray(textLength)
        paint.getTextWidths(getText(), 0, textLength, textWidths)


        for (i in 0..mNumChars.toInt()) {
            updateColorForLines(i == textLength)
            canvas.drawLine(startX.toFloat(), bottom.toFloat(), startX.toFloat() + mCharSize, bottom.toFloat(), paint)
            if (text.length > i) {
                val middle = startX + mCharSize / 2
                canvas.drawText(text, i,i + 1, middle - textWidths[0] / 2, (bottom - mLineSpacing).toFloat(), paint)
            }

            if (mSpace < 0) {
                startX += mCharSize * 2
            } else {
                startX += mCharSize + mSpace
            }
        }
    }

    private fun getColorForState(vararg states: Int): Int {
        return mColorStates.getColorForState(states, Color.GRAY)
    }

    private fun updateColorForLines(next: Boolean) {
        if (isFocused) {
            mLinesPaint?.strokeWidth = mLineStrokeSelected.toFloat()
            mLinesPaint?.color = getColorForState(android.R.attr.state_focused)
            if (next) {
                mLinesPaint?.color = getColorForState(android.R.attr.state_selected)
            }
        } else {
            mLinesPaint?.strokeWidth = mLineStroke.toFloat()
            mLinesPaint?.color = getColorForState(-android.R.attr.state_focused)
        }
    }
}

这是我的组件XML:

<com.myapp.app.myapp.PinEntryEditText
    android:id="@+id/pin_entry_edit"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:cursorVisible="false"
    android:digits="1234567890"
    android:inputType="number"
    android:maxLength="4"
    android:textIsSelectable="false"
    android:textSize="20sp" />

我必须以编程方式分配课程吗?不幸的是,我真的不知道如何解决这个问题,因为调试器甚至不会进入该类。对此可能有什么问题的任何形式的输入,将不胜感激。

2 个答案:

答案 0 :(得分:1)

根据View.setWillNotDraw,应从构造函数中删除setWillNotDraw(true)

  

如果此视图本身不进行任何绘制,则将此标志设置为允许   进一步优化。默认情况下,未在View上设置此标志,但是   可以在某些View子类(例如ViewGroup)上设置。通常,如果   您重写onDraw(android.graphics.Canvas)应该清除此   标记

答案 1 :(得分:1)

@ Giulio Colleluori再次检查您的包名称,通过包名称访问该类的效果不佳。