and*_*per 16 android android-layout android-edittext
我在活动中向用户显示了相当复杂的布局.
其中一个视图是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>
Run Code Online (Sandbox Code Playgroud)
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;
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
当禁用插入符号时(使用"cursorVisible",由于某种原因,它被称为"游标"),我可以看到问题不存在.
我试图找到内置插入符号行为的替代方法,但我找不到.我发现的唯一的东西就是这篇文章,但它似乎让它变得静止,我不确定它的表现如何(性能和兼容性与普通插入符号相比).
我试图强制设置EditText的大小,这样就不需要导致包含它的布局失效.它没用.
我还注意到,在原始应用程序上,即使应用程序进入后台,日志也可以(出于某种原因)继续写入.
我已经报过这个问题(包括样品和视频)这里,希望谷歌将展示什么是错还是对这个修复.
有没有办法避免重新布局整个视图层次结构?仍然让EditText具有与普通EditText相同的外观和感觉的方法?
也许一种方法来自定义EditText与插入符号的行为方式?
我注意到,每当 EditText 获得焦点并显示其插入符号时,整个视图层次结构就会重新布局。
这不是真的。EditText 的大小和位置是恒定的 - 没有重新布局。您可以使用下面的代码进行检查。
findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Log.d("AppLog", "Layout phase");
}
});
Run Code Online (Sandbox Code Playgroud)
由于闪烁的插入符号 - EditText 不断调用invalidate()。这会强制 GPU 再次绘制 EditText。
在我的 Nexus 5(棉花糖)上,我看到只有 EditText 被重绘(显示 GPU 视图更新 - 已启用)。
| 归档时间: |
|
| 查看次数: |
687 次 |
| 最近记录: |