我是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" />
我必须以编程方式分配课程吗?不幸的是,我真的不知道如何解决这个问题,因为调试器甚至不会进入该类。对此可能有什么问题的任何形式的输入,将不胜感激。
答案 0 :(得分:1)
根据View.setWillNotDraw,应从构造函数中删除setWillNotDraw(true)
:
如果此视图本身不进行任何绘制,则将此标志设置为允许 进一步优化。默认情况下,未在View上设置此标志,但是 可以在某些View子类(例如ViewGroup)上设置。通常,如果 您重写onDraw(android.graphics.Canvas)应该清除此 标记。
答案 1 :(得分:1)
@ Giulio Colleluori再次检查您的包名称,通过包名称访问该类的效果不佳。