Фон
У меня довольно сложная компоновка, показываемая пользователю в действии.
Одно из видов - это EditText.
Так как мне пришлось сделать одно из видов, оставшихся за мягкой клавиатурой, но все остальное над ним, мне пришлось прислушиваться к изменениям вида-макета (написано об этом здесь).
Проблема
Я заметил, что всякий раз, когда EditText имеет фокус и показывает свой карет, вся иерархия представлений получает ре-макет.
Вы можете увидеть это, просмотрев журнал созданного слушателя или включив "show surface updates" через настройки разработчиков.
Это приводит к плохой производительности на некоторых устройствах, особенно если компоновка активности сложна или имеет фрагменты, которые имеют сложные макеты.
Код
Я не буду показывать исходный код, но есть простой способ воспроизвести проблему:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.user.myapplication.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="just some text"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone"
android:text="write here"
android:textSize="18dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="just some text 2"/>
</LinearLayout>
</FrameLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(android.R.id.content).getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
Log.d("AppLog", "onPreDraw");
return true;
}
});
}
}
Что я пробовал
При отключении каретки (используя "cursorVisible", который по какой-то причине называется "курсором" ), я вижу, что проблема не существует.
Я попытался найти альтернативу встроенному поведению каретки, но я не могу найти. Единственное, что я нашел, это этот пост, но он кажется статическим, и я не уверен, насколько хорошо он выполняет (производительность и совместимость с обычным кареткой).
Я попытался установить размер EditText принудительно, так что ему не нужно будет вызывать недействительность макета, содержащего его. Это не сработало.
Я также заметил, что в исходном приложении журналы могут (по какой-то причине) продолжать писать, даже когда приложение переходит в фоновый режим.
Я сообщил об этой проблеме (включая образец и видео) здесь, надеясь, что Google покажет что неправильно или исправить это.
Вопрос
Есть ли способ избежать повторной компоновки всей иерархии представлений? Способ, который все равно позволит EditText иметь одинаковый внешний вид и нормальный EditText?
Может быть, способ настроить, как EditText ведет себя с каретой?