【问题标题】:EditText expands too slow inside AlertDialog on androidEditText 在 android 上的 AlertDialog 内扩展太慢
【发布时间】:2015-04-27 23:49:38
【问题描述】:

简化更复杂的问题。

我有一个带有这个视图 dialog.xml 的 AlertDialog(我可能错了,这个问题与 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)。

标签: android dialog android-animation android-alertdialog


【解决方案1】:

在大量挖掘堆栈溢出答案但没有结果后,我自己找到了解决方案。

这个想法是首先将整个对话框扩展到全屏,但有一个透明的覆盖视图覆盖空白部分。

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();
      }
    }
  });
}

【讨论】:

    【解决方案2】:

    要删除动画,请按照以下步骤操作:

    1. /res/anim中添加一个no_anim.xml,关键是将duration设置为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. 使用 0-duration 动画定义自定义样式:

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

    【讨论】:

    • 我试过这个,但它对对话框扩展动画持续时间没有帮助。
    • 您是否遵循了所有步骤?我已经测试过了,对话框立即显示,没有动画。
    • 我的问题不在于没有动画的对话框。我的问题是对话框在没有动画的情况下不会展开(当在 EditText 中创建新行时)。展开的动画是这样的:向上移动对话框 -> 增加对话框的高度以适应增加的 EditText 高度。因为这两者不是并行工作,而是连续工作,所以对话框和键盘之间会在很短的时间内出现一小段间隙。
    • 您确实意识到您的标题极具误导性
    猜你喜欢
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 2017-07-09
    • 2020-12-06
    • 2020-05-10
    • 2012-03-09
    • 1970-01-01
    相关资源
    最近更新 更多