Estou apenas começando com o desenvolvimento de aplicativos Android e me deparei com um erro estranho ao implementar um arquivo OnClickListener
. Comecei com uma "Atividade de visualizações vazias" no Android Studio. Adicionei, entre outros elementos da interface do usuário, a Button
, an EditText
e a ScrollView
contendo a TextView
. Defino um OnClickListener
no botão para que uma mensagem logcat seja emitida.
Quando clico no botão, ele emite a mensagem logcat conforme o esperado. No entanto, assim que clico no campo de texto, o botão deixa de responder pelo restante da vida útil do aplicativo. O estranho é que tudo funciona perfeitamente se eu remover o arquivo ScrollView
.
Aqui está meu MRE:
atividade_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/startErrorText"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="160dp"
android:text="Start"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textField" />
<EditText
android:id="@+id/textField"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="80dp"
android:layout_marginTop="48dp"
android:layout_marginEnd="80dp"
android:ems="10"
android:hint="Enter some text"
android:inputType="text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:id="@+id/scrollView"
android:layout_width="409dp"
android:layout_height="585dp"
android:layout_marginStart="1dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="2dp"
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/startButton"
app:layout_constraintVertical_bias="1.0">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/logView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package com.example.test
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.View.OnClickListener
import android.widget.Button
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button: Button = findViewById(R.id.startButton)
button.setOnClickListener(object : OnClickListener {
override fun onClick(v: View?) {
Log.i("MyApp", "Button pressed")
}
})
}
}
Aqui está a saída do logcat:
ziparchive com.example.test W Unable to open '/data/data/com.example.test/code_cache/.overlay/base.apk/classes3.dm': No such file or directory
ziparchive com.example.test W Unable to open '/data/app/~~6ohH-jaL6kb5-3S5sLz1rw==/com.example.test-21xtpoSa2I8lnFAMirvZRA==/base.dm': No such file or directory
ziparchive com.example.test W Unable to open '/data/app/~~6ohH-jaL6kb5-3S5sLz1rw==/com.example.test-21xtpoSa2I8lnFAMirvZRA==/base.dm': No such file or directory
nativeloader com.example.test D Configuring clns-6 for other apk /data/app/~~6ohH-jaL6kb5-3S5sLz1rw==/com.example.test-21xtpoSa2I8lnFAMirvZRA==/base.apk. target_sdk_version=34, uses_libraries=, library_path=/data/app/~~6ohH-jaL6kb5-3S5sLz1rw==/com.example.test-21xtpoSa2I8lnFAMirvZRA==/lib/arm64, permitted_path=/data:/mnt/expand:/data/user/0/com.example.test
GraphicsEnvironment com.example.test V Currently set values for:
GraphicsEnvironment com.example.test V angle_gl_driver_selection_pkgs=[]
GraphicsEnvironment com.example.test V angle_gl_driver_selection_values=[]
GraphicsEnvironment com.example.test V ANGLE GameManagerService for com.example.test: false
GraphicsEnvironment com.example.test V com.example.test is not listed in per-application setting
GraphicsEnvironment com.example.test V Neither updatable production driver nor prerelease driver is supported.
libEGL com.example.test D loaded /vendor/lib64/egl/libEGL_emulation.so
AppCompatDelegate com.example.test D Checking for metadata for AppLocalesMetadataHolderService : Service not found
libEGL com.example.test D loaded /vendor/lib64/egl/libGLESv1_CM_emulation.so
libEGL com.example.test D loaded /vendor/lib64/egl/libGLESv2_emulation.so
om.example.test com.example.test W Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (unsupported, reflection, allowed)
om.example.test com.example.test W Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (unsupported, reflection, allowed)
Compatibil...geReporter com.example.test D Compat change id reported: 210923482; UID 10191; state: ENABLED
Compatibil...geReporter com.example.test D Compat change id reported: 171228096; UID 10191; state: ENABLED
Compatibil...geReporter com.example.test D Compat change id reported: 237531167; UID 10191; state: DISABLED
OpenGLRenderer com.example.test W Unknown dataspace 0
OpenGLRenderer com.example.test W Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
OpenGLRenderer com.example.test W Failed to initialize 101010-2 format, error = EGL_SUCCESS
Gralloc4 com.example.test I mapper 4.x is not supported
OpenGLRenderer com.example.test E Unable to match the desired swap behavior.
AutofillManager com.example.test D notifyViewEnteredForFillDialog:1073741824
EGL_emulation com.example.test D app_time_stats: avg=145.48ms min=0.87ms max=1433.47ms count=10
EGL_emulation com.example.test D app_time_stats: avg=181.58ms min=13.65ms max=2822.69ms count=17
MyApp com.example.test I Button pressed
ProfileInstaller com.example.test D Installing profile for com.example.test
EGL_emulation com.example.test D app_time_stats: avg=39.13ms min=0.77ms max=1255.29ms count=48
Compatibil...geReporter com.example.test D Compat change id reported: 163400105; UID 10191; state: ENABLED
ImeTracker com.example.test I com.example.test:39ecb7d6: onRequestShow at ORIGIN_CLIENT_SHOW_SOFT_INPUT reason SHOW_SOFT_INPUT
InputMethodManager com.example.test D showSoftInput() view=androidx.appcompat.widget.AppCompatEditText{4a6450d VFED..CL. .F.P..ID 250,132-830,256 #7f0801f9 app:id/textField aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT
AssistStructure com.example.test I Flattened final assist data: 1492 bytes, containing 1 windows, 8 views
InsetsController com.example.test D show(ime(), fromIme=true)
InteractionJankMonitor com.example.test D Build configuration failed!
java.lang.IllegalArgumentException: Must pass in a valid surface control if only instrument surface;
at com.android.internal.jank.InteractionJankMonitor$Configuration.validate(InteractionJankMonitor.java:1259)
at com.android.internal.jank.InteractionJankMonitor$Configuration.<init>(InteractionJankMonitor.java:1217)
at com.android.internal.jank.InteractionJankMonitor$Configuration.<init>(Unknown Source:0)
at com.android.internal.jank.InteractionJankMonitor$Configuration$Builder.build(InteractionJankMonitor.java:1197)
at com.android.internal.jank.InteractionJankMonitor.begin(InteractionJankMonitor.java:611)
at android.view.inputmethod.ImeTracker$ImeJankTracker.onRequestAnimation(ImeTracker.java:717)
at android.view.InsetsController$InternalAnimationControlListener$2.onAnimationStart(InsetsController.java:448)
at android.animation.Animator$AnimatorListener.onAnimationStart(Animator.java:695)
at android.animation.Animator$AnimatorCaller$$ExternalSyntheticLambda0.call(Unknown Source:4)
at android.animation.Animator.callOnList(Animator.java:669)
at android.animation.Animator.notifyListeners(Animator.java:608)
at android.animation.Animator.notifyStartListeners(Animator.java:625)
at android.animation.ValueAnimator.startAnimation(ValueAnimator.java:1334)
at android.animation.ValueAnimator.start(ValueAnimator.java:1149)
at android.animation.ValueAnimator.start(ValueAnimator.java:1173)
at android.view.InsetsController$InternalAnimationControlListener.onReady(InsetsController.java:470)
at android.view.InsetsAnimationThreadControlRunner.lambda$new$0(InsetsAnimationThreadControlRunner.java:129)
at android.view.InsetsAnimationThreadControlRunner.$r8$lambda$3zGKYd3XPzPnvMO2hiF8a88M6T0(Unknown Source:0)
at android.view.InsetsAnimationThreadControlRunner$$ExternalSyntheticLambda2.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.os.HandlerThread.run(HandlerThread.java:67)
ImeTracker com.example.test I com.example.test:39ecb7d6: onShown
EGL_emulation com.example.test D app_time_stats: avg=213.12ms min=0.85ms max=500.33ms count=5
EGL_emulation com.example.test D app_time_stats: avg=500.68ms min=499.36ms max=502.83ms count=3
Isso java.lang.IllegalArgumentException
ocorre apenas algumas vezes, mas o bug geral ocorre sempre.
Executei seu código no meu Android Studio: as
ScrollView
sobreposições estão nabutton
metade. Se eu substituir naactivity_main.xml
seção<ScrollView
a linhapor
tudo funciona. Em geral, porém, você poderia programar
activity_main.xml
de forma muito mais simples e clara.Quando você clica em
EditText
, o teclado aparece e há menos espaço paraScrollView
. Como vocêScrollView
tem tamanho fixo, ele se sobrepõe ao botão. Você pode ver isso emLayout Inspector
Eu fiz uma captura de tela para você:SOLUÇÃO: Você precisa definir
ScrollView
a altura como0dp
.ConstraintLayout
interpreta como "preencher todo o espaço disponível". E quando o teclado aparecer, ele ocupará apenas o espaço disponível e não se sobreporá ao botão.Basta copiar este xml e funcionará bem:
Esta é a aparência do seu ScrollView agora (verifique o espaço que ele usa):
CONSELHOS: Se você usar,
ConstraintLayout
tente não codificar tamanhos e confie em restrições, se possível.