This is okay in other versions of ndroid but this error occurs in my android version 8 (Oreo) Samsung Experience 9.0.
Every time when I try to edit some existing data inside val lyricsEditor = view.findViewById<EditText>(R.id.lyrics_editor)
, it crashes giving the logcat report as below.
I Tried by changing the typecast as val lyricsEditor = view.findViewById<TextInputEditText>(R.id.lyrics_editor)
but the problem is same as before.
This okay when I start a new editor. But the problem occurs when I try to edit existing data
I couldn't figure out any issues. Please help me.
Logcat Shows
2023-01-30 14:03:54.222 AndroidRuntime E FATAL EXCEPTION: main
Process: com.rj.mysongbook, PID: 12196
java.lang.ArrayIndexOutOfBoundsException: length=9; index=-1
at android.text.DynamicLayout.getBlockIndex(DynamicLayout.java:646)
at android.widget.Editor.drawHardwareAccelerated(Editor.java:1820)
at android.widget.Editor.onDraw(Editor.java:1789)
at android.widget.TextView.onDraw(TextView.java:7779)
at android.view.View.draw(View.java:20370)
at android.view.View.updateDisplayListIfDirty(View.java:19315)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19306)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.draw(View.java:20373)
at com.google.android.material.textfield.TextInputLayout.draw(TextInputLayout.java:3906)
at android.view.View.updateDisplayListIfDirty(View.java:19315)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19306)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19306)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19306)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19306)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19306)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19306)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19306)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.updateDisplayListIfDirty(View.java:19306)
at android.view.View.draw(View.java:20093)
at android.view.ViewGroup.drawChild(ViewGroup.java:4421)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4207)
at android.view.View.draw(View.java:20373)
at com.android.internal.policy.DecorView.draw(DecorView.java:980)
at android.view.View.updateDisplayListIfDirty(View.java:19315)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:800)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3501)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3288)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2823)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1785)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7832)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:658)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
My Layout is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:hint="@string/lyrics_title"
android:textColorHint="#EF1AF6"
app:hintTextColor="@color/red">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/title_editor"
style="@style/lyricsTvStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/square_edittext"
android:textColor="@color/black" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:hint="@string/song_lyrics"
android:textColorHint="#EF1AF6"
app:hintTextColor="@color/red">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/lyrics_editor"
style="@style/lyricsTvStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/square_edittext"
android:textColor="@color/blue" />
</com.google.android.material.textfield.TextInputLayout
</LinearLayout>
And I am taking data from these to my server as
private fun showEditorNew(
songContainer: SongContainer,
isDelete: Boolean,
) {
var songNumber = songContainer.songNumber
val songTypes = songContainer.songType
val othersType = songContainer.othersType
val title = songContainer.title
val lyrics = songContainer.lyrics
val engLyrics = songContainer.engLyrics
val motherNode = songContainer.motherNode
val builder = AlertDialog.Builder(requireActivity(), R.style.DialogTheme)
val view = LayoutInflater.from(activity).inflate(R.layout.editor_layout, null)
view.keepScreenOn = true
val titleEditor = view.findViewById<EditText>(R.id.title_editor)
val lyricsEditor = view.findViewById<EditText>(R.id.lyrics_editor)
titleEditor.setText(title)
lyricsEditor.setText(lyrics)
lyricsEditor.textAlignment = View.TEXT_ALIGNMENT_TEXT_START
builder.setView(view)
builder.setCustomTitle(requireContext().setCustomTitle("Song Editor"))
builder.setCancelable(false)
var posButton = "Edit"
var snackMsg =
"Edited!!! if you want to update, Click Edit Again!!!\nOr Click Cancel to go back!!!"
if (isDelete) {
posButton = "Delete"
snackMsg =
"Are you Sure to Delete?, Click Delete Again!!!\nOr Click Cancel to go back!!!"
} else {
builder.setNeutralButton(
"Preview"
) { dialogInterface: DialogInterface?, i: Int -> }
}
builder.setPositiveButton(
posButton
) { dialogInterface: DialogInterface?, i: Int -> }
builder.setNegativeButton(
"Cancel"
) { dialogInterface: DialogInterface, i: Int -> dialogInterface.dismiss() }
val dialog = builder.create()
dialog.show()
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
if (isEditPermitted()) {
if (!IsInternetAvailable(requireContext()).isConnected()) {
showToast(getString(R.string.no_active_connection))
} /*else if (!isEdit[0]) {
showSnackBar(
snackMsg,
view,
true
)
isEdit[0] = true
lyricsEditor.isFocusable = true
}*/ else {
val newTitle = titleEditor.text.toString().trim()
val newLyrics = lyricsEditor.text.toString().trim()
showToast("Editing in the server!!!")
val songToDb =
HashMap<String, String>()
songToDb["title"] = newTitle
songToDb["lyrics"] = newLyrics
if (songTypes != "null") {
songToDb["songType"] = songTypes
}
if (othersType != "null") {
songToDb["othersType"] = othersType
}
if (songNumber.contains(".")) {
songNumber = songNumber.split(".")[0].trim()
}
if (songNumber != "null") {
songToDb["songNumber"] = songNumber
}
if (engLyrics != "null") {
songToDb["engLyrics"] = engLyrics
}
val previewConfirm = requireContext().showWebPreview(newTitle, newLyrics)
previewConfirm.setTitle("Are Sure to $posButton?")
.setIcon(R.drawable.ic_warning)
previewConfirm.setPositiveButton("OK") { _, _ ->
newEditDb(motherNode, songToDb, dialog, isDelete)
}
.setNegativeButton("Cancel", null)
.show()
}
}
}
dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener { view1: View? ->
if (titleEditor.text.isEmpty()) {
requireContext().showAlert("No Title?", "Please give a title for this song")
} else if (lyricsEditor.text.isEmpty()) {
requireContext().showAlert("No Lyrics?", "Please write some Lyrics or paste here")
} else {
requireContext().showWebPreview(
titleEditor.text.toString(),
lyricsEditor.text.toString()
)
.setPositiveButton("OK", null)
.show()
}
}
}
I have done some researches from your provided exception log, that is a known bug for Android 8.0.
WordPress for Android had also encountered similar issue on Android 8.0 or 8.1 before.
There is a version fix related to that:
Fix DynamicLayout block index calculation after edit
DynamicLayout made wrong adjustments to the block indices set to be redrawn. Every indice after the first change was being added the diff count in the blocks. However this meant when there are 2 deletes and an index as 1, it would become -1 (wrong array index). The change should be applied to indices outside of [firstBlock, lastBlock].
And that's only available from Android 9 onwards.
And one suggested fix provided, is to disable hardware acceleration on the targeted view.
In code:
lyricsEditor.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Or in XML:
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/lyrics_editor"
style="@style/lyricsTvStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/square_edittext"
android:textColor="@color/blue"
android:layerType="software" />