在Android上,AlertDialog中的EditText扩展得太慢了

10

简化一个更复杂的问题。

我有一个AlertDialog,它有一个名为dialog.xml的视图(我可能错了,这个问题可能与AlertDialog无关,但与一般的视图相关):

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal">

  // <ImageView 48dp x 48dp/> ImageView for profile photo

  <EditText
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    android:layout_gravity="top"
    android:maxLines="5"
    android:inputType="textMultiLine"
    android:scrollbars="vertical"
    android:scrollHorizontally="false"/>

  // <ImageView 48dp x 48dp> ImageView for a send button.

</LinearLayout>

我希望整个对话框都位于底部,在键盘的正上方,这样就类似于聊天程序的界面。我需要它作为浮动对话框,因为它不会固定在父视图的任何一个位置。

为了实现这一点(在客户端代码中),我这样做:

dialog.show();  // above dialog
Window window dialog.getWindow();
window.setGravity(Gravity.BOTTOM);
window.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

现在当我输入时,编辑框正确地展开到5行(从下往上)。但如果我输入得太快(按回车键快速创建新行),对话框的展开动画(高度向下增加)比对话框向上移动的动画慢。这导致在对话框出现时有1-2秒钟的时间它似乎漂浮在空中,其下边框和键盘之间存在一个小间隙。

我该如何防止这种情况发生(消除两者之间的空隙)?或让动画变为0秒?

澄清一下:我不需要禁用对话框弹出/关闭的动画。当窗口扩展得太快时(例如通过创建新行),窗口会向上移动,而高度没有足够快地补偿移动,留下了一个短暂的(1-2秒)间隙在对话框和键盘之间。这可能是浮动视图普遍面临的基本问题(我尝试使用PopupWindow也有同样的效果)。

带有间隙的对话框: 带有间隙的对话框

等展开动画最终赶上时1-2秒后,变成这样: 没有间隙的对话框


澄清一下:我不需要禁用对话框弹出/关闭的动画。我需要禁用对话框向下移动和高度扩展的动画。这可能是浮动视图普遍存在的基本问题(我尝试使用PopupWindow,但效果相同)。 - vtlinh
2个回答

5

在Stack Overflow上搜索很久,但没有找到答案,最终我自己解决了问题。

思路是首先将整个对话框展开到全屏,但是使用透明遮罩视图覆盖空白部分。

现在dialog.xml看起来像这样:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

  <!-- Transparent view that extends over entire screen and push comment view to the bottom -->
  <View
      android:id="@+id/overlay"
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_weight="1"
      android:background="@color/transparent"/>

  <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:background="@android:color/white"
      android:orientation="horizontal">

    // <ImageView 48dp x 48dp/> ImageView for profile photo

    <EditText
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:maxLines="5"
        android:inputType="textMultiLine"
        android:scrollbars="vertical"
        android:scrollHorizontally="false"/>

    // <ImageView 48dp x 48dp> ImageView for a send button.

  </LinearLayout>
</LinearLayout>

对于Java代码:

public void showDialog() {
  View content = activity.getLayoutInflater().inflate(R.layout.dialog, null, false);

  // This makes top LinearLayout background transparent, without this, 
  // it will be all white covering fullscreen.
  content.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));        

  Dialog dialog = new AlertDialog.Builder(context)
    .setView(content).create();
  dialog.show(); // needs to be done before window changes
  Window window dialog.getWindow();
  window.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
  window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
  window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

  View overlay = content.findViewById(R.id.overlay);
  overlay.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
      if (dialog.isShowing()) {
        dialog.cancel();
      }
    }
  });
}

3

要移除动画,按照以下步骤进行操作:

  1. Adds a no_anim.xml to /res/anim, the key is to set duration to 0

    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="0" />
    
  2. Define a custom style using the 0-duration animation:

<style name="NoAnimation">
    <item name="android:windowEnterAnimation">@anim/no_anim</item>
    <item name="android:windowExitAnimation">@anim/no_anim</item>
</style>
应用样式到您的AlertDialog:
将样式应用到AlertDialog中:
dialog.getWindow().getAttributes().windowAnimations = R.style.NoAnimation;

我尝试过这个,但它不能帮助对话框扩展动画的持续时间。 - vtlinh
你按照所有步骤操作了吗?我已经测试过,对话框立即显示,没有任何动画效果。 - Kai
我的问题不是对话框没有动画弹出。我的问题是当EditText创建新行时,对话框没有动画展开。展开的动画是这样的:将对话框移动到上方->增加对话框的高度以适应EditText的增高。因为这两个步骤不是同时进行的,而是按顺序进行的,所以在对话框和键盘之间存在一个短暂的小间隙。 - vtlinh
你意识到你的标题极具误导性了吗? - Kai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接