РЕДАКТИРОВАТЬ Ошибка по-прежнему отображается даже без копирования и вставки.
Я пытаюсь создать простое приложение-конвертер, и все работает нормально, но я обнаружил проблему, которую, похоже, не могу найти способ вперед. Вот logcat:
2020-01-22 22:45:50.905 15060-15060/com.example.unitconverter E/may be Problem: 10.220462
2020-01-22 22:45:50.911 15060-15060/com.example.unitconverter E/text: 4.635924 //shows the text is set correctly
2020-01-22 22:45:50.924 15060-15060/com.example.unitconverter E/AndroidRuntime: FATAL EXCEPTION:
main
Process: com.example.unitconverter, PID: 15060
java.lang.IndexOutOfBoundsException
at android.graphics.Paint.getRunAdvance(Paint.java:2861)
at android.text.TextLine.getRunAdvance(TextLine.java:848)
at android.text.TextLine.handleText(TextLine.java:897)
at android.text.TextLine.handleRun(TextLine.java:1144)
at android.text.TextLine.measureRun(TextLine.java:531)
at android.text.TextLine.measure(TextLine.java:327)
at android.text.Layout.getHorizontal(Layout.java:1199)
at android.text.Layout.getHorizontal(Layout.java:1177)
at android.text.Layout.getPrimaryHorizontal(Layout.java:1148)
at android.text.Layout.getCursorPath(Layout.java:1816)
at android.widget.TextView.getUpdatedHighlightPath(TextView.java:7784)
at android.widget.TextView.onDraw(TextView.java:8091)
at android.view.View.draw(View.java:21875)
at android.view.View.updateDisplayListIfDirty(View.java:20748)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4542)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4514)
at android.view.View.updateDisplayListIfDirty(View.java:20703)
at android.view.View.draw(View.java:21601)
at android.view.ViewGroup.drawChild(ViewGroup.java:4558)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4333)
at android.view.View.draw(View.java:21878)
at com.google.android.material.textfield.TextInputLayout.draw(TextInputLayout.java:3614)
at android.view.View.updateDisplayListIfDirty(View.java:20748)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4542)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4514)
at android.view.View.updateDisplayListIfDirty(View.java:20703)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4542)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4514)
at android.view.View.updateDisplayListIfDirty(View.java:20703)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4542)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4514)
at android.view.View.updateDisplayListIfDirty(View.java:20703)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4542)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4514)
at android.view.View.updateDisplayListIfDirty(View.java:20703)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4542)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4514)
at android.view.View.updateDisplayListIfDirty(View.java:20703)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4542)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4514)
at android.view.View.updateDisplayListIfDirty(View.java:20703)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4542)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4514)
at android.view.View.updateDisplayListIfDirty(View.java:20703)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4542)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4514)
at android.view.View.updateDisplayListIfDirty(View.java:20703)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:725)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:731)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:840)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3951)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3725)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3034)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1897)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8516)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:986)
at android.view.Choreographer.doCallbacks(Choreographer.java:764)
at android.view.Choreographer.doFrame(Choreographer.java:699)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:965)
2020-01-22 22:45:50.925 15060-15060/com.example.unitconverter E/AndroidRuntime: at
android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7099)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Поскольку прикрепленные ссылки не указывают на мой код (большинство из них указывают на блоки комментариев в исходном коде android), я не уверен, какой код для публикации ..
Вот файл XML, содержащий действие.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/convert_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DD9911"
app:layoutDescription="@xml/convert_scene"
app:motionProgress="1"
tools:context=".ConvertActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/convert_app_bar"
android:layout_width="match_parent"
android:layout_height="66dp"
android:elevation="4dp"
android:gravity="center"
android:paddingStart="0dp"
android:paddingEnd="8dp"
android:paddingBottom="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:layout_constraintBottom_toTopOf="@id/convertScroll"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="@style/ThemeOverlay.AppCompat.DayNight" />
<TextView
android:id="@+id/convert_header"
android:layout_width="0dp"
android:layout_height="50dp"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:lineSpacingMultiplier="0.88"
android:text="@string/angularAcceleration"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textColor="#030303"
android:textSize="38sp" />
<TextView
android:id="@+id/app_bar_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
android:text="@string/mass"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="#030303"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="@+id/convert_app_bar"
tools:layout_editor_absoluteY="219dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/convert_app_barGuideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.3" />
<com.example.unitconverter.subclasses.ConvertScrollView
android:id="@+id/convertScroll"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/rounded_front"
android:theme="@style/Theme.MaterialComponents.Light.NoActionBar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/convert_app_bar">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/convert_inner"
android:layout_width="match_parent"
android:splitMotionEvents="false"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/topGuide"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.1" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/firstBox"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:boxCornerRadiusBottomEnd="10dp"
app:boxCornerRadiusBottomStart="10dp"
app:boxCornerRadiusTopEnd="10dp"
app:boxCornerRadiusTopStart="10dp"
app:boxStrokeColor="#F8BBD0"
app:hintTextColor="@android:color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/topGuide"
app:layout_constraintWidth_percent="0.85">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/firstEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:letterSpacing="0.06"
android:paddingStart="17dp"
android:paddingEnd="52dp"
android:textSize="18sp" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/secondBox"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
app:boxCornerRadiusBottomEnd="10dp"
app:boxCornerRadiusBottomStart="10dp"
app:boxCornerRadiusTopEnd="10dp"
app:boxCornerRadiusTopStart="10dp"
app:boxStrokeColor="#F8BBD0"
app:boxStrokeErrorColor="@color/design_default_color_primary_dark"
app:hintTextColor="@android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/firstBox"
app:layout_constraintWidth_percent="0.85">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/secondEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:letterSpacing="0.06"
android:paddingStart="17dp"
android:paddingEnd="52dp"
android:textSize="18sp" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/topTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:maxWidth="43dp"
app:layout_constraintBottom_toBottomOf="@+id/firstBox"
app:layout_constraintEnd_toEndOf="@+id/firstBox"
app:layout_constraintHorizontal_bias="0.97"
app:layout_constraintStart_toStartOf="@id/firstBox"
app:layout_constraintTop_toTopOf="@+id/firstBox"
app:layout_constraintVertical_bias="0.52" />
<TextView
android:id="@+id/bottomTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:maxWidth="43dp"
app:layout_constraintBottom_toBottomOf="@+id/secondBox"
app:layout_constraintEnd_toEndOf="@id/secondBox"
app:layout_constraintHorizontal_bias="0.97"
app:layout_constraintStart_toStartOf="@id/secondBox"
app:layout_constraintTop_toTopOf="@+id/secondBox"
app:layout_constraintVertical_bias="0.49" />
<com.google.android.material.button.MaterialButton
android:id="@+id/top_button"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="42dp"
android:layout_height="52dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:insetLeft="2dp"
android:insetRight="0dp"
android:paddingLeft="-7dp"
android:paddingTop="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
app:cornerRadius="12dp"
app:icon="@drawable/arrow_down"
app:layout_constraintBottom_toBottomOf="@+id/firstBox"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/firstBox"
app:layout_constraintTop_toTopOf="@id/topGuide"
app:strokeWidth="2dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/bottom_button"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="42dp"
android:layout_height="52dp"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:insetLeft="2dp"
android:insetRight="0dp"
android:paddingLeft="-7dp"
android:paddingTop="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp"
app:cornerRadius="12dp"
app:icon="@drawable/arrow_down"
app:layout_constraintBottom_toBottomOf="@+id/secondBox"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/secondBox"
app:layout_constraintTop_toTopOf="@id/secondBox"
app:strokeWidth="2dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.example.unitconverter.subclasses.ConvertScrollView>
</androidx.constraintlayout.motion.widget.MotionLayout>
Вот фильтр, используемый для редактирования текста
//filters
fun filters(comma: Char, fullStop: Char, editText: TextInputEditText): Array<InputFilter> {
val filter = InputFilter { source, start, end, _, _, _ ->
val stringBuilder = StringBuilder(end - start)
var count = 0
for (i in start until end) {
if (source[i].isDigit() ||
source[i] == comma ||
source[i] == fullStop
) {
if (source[i] == fullStop) {
// ensures only one decimal separator is in the text
count++
if (count >= 2) continue
if (source.length > 1 && editText.isFocused) {
val text = editText.text
if (text != null
&& text.contains(fullStop)
) continue
}
}
stringBuilder.append(source[i])
}
}
stringBuilder
}
val lengthFilter = InputFilter.LengthFilter(50)
return arrayOf(filter, lengthFilter)
}
И затем в деятельности.kt
class ConvertActivity : AppCompatActivity(), ConvertFragment.ConvertDialogInterface {
private var swap = false
private var randomColor = -1
private var viewId = -1
private lateinit var dialog: ConvertFragment
private var isPrefix = false
private val bundle = Bundle()
lateinit var function: (String) -> String
var groupingSeparator by Delegates.notNull<Char>()
var decimalSeparator by Delegates.notNull<Char>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_convert)
setSupportActionBar(convert_app_bar)
supportActionBar?.apply {
setDisplayHomeAsUpEnabled(true)
setDisplayShowTitleEnabled(false)
}
setSeparators()
firstEditText.apply {
setRawInputType(Configuration.KEYBOARD_12KEY)
filters = filters(groupingSeparator, decimalSeparator,this)
}
secondEditText.apply {
filters = filters(groupingSeparator, decimalSeparator,this)
setRawInputType(Configuration.KEYBOARD_12KEY)
}
getTextWhileTyping()
}
... // other methods
inner class CommonWatcher(editText: EditText, private val secondEditText: EditText) :
SeparateThousands(editText, groupingSeparator, decimalSeparator) {
override fun afterTextChanged(s: Editable?) {
super.afterTextChanged(s)
s?.toString()?.apply {
this.removeCommas(decimalSeparator)?.also {
Log.e("may be Problem", it)
secondEditText.setText(callBack(function, it))
Log.e("text","${secondEditText.text}")
}
}
}
}// end of inner class
private fun getTextWhileTyping() {
firstEditText.apply {
firstWatcher = CommonWatcher(this, secondEditText)
setOnFocusChangeListener { _, hasFocus ->
firstBoolean = hasFocus
if (hasFocus) {
addTextChangedListener(firstWatcher)
secondEditText.removeTextChangedListener(secondCommonWatcher)
reverse = false
}
}
}
secondEditText.apply {
secondCommonWatcher = CommonWatcher(this, firstEditText)
setOnFocusChangeListener { _, hasFocus ->
secondBoolean = hasFocus
if (hasFocus) {
addTextChangedListener(secondCommonWatcher)
firstEditText.removeTextChangedListener(firstWatcher)
reverse = true
}
}
}
}
}