Пользовательский компонент AppCompatEditText не инициализируется - PullRequest
0 голосов
/ 06 ноября 2018

Я новичок в Kotlin, и я пытаюсь реализовать пользовательское поле для редактирования текста ввода, как это сделано в этом руководстве. Я переписал PinEntryEditText на Kotlin, и он не выдает никаких ошибок. Я также добавил в свой файл макета 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 голосов
/ 06 ноября 2018

@ Giulio Colleluori Дважды проверьте имя вашего пакета, ваш доступ к классу через имя пакета выглядит не очень хорошо.

0 голосов
/ 06 ноября 2018

Согласно View.setWillNotDraw , вы должны удалить setWillNotDraw(true) из ваших конструкторов:

Если этот вид не рисует сам по себе, установите этот флаг, чтобы дальнейшие оптимизации. По умолчанию этот флаг не установлен на View, но может быть установлен на некоторые подклассы View, такие как ViewGroup. Обычно , если вы переопределяете onDraw (android.graphics.Canvas), вы должны очистить это флаг .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...