Высота всплывающего окна Android PopupWindow не отображается

Android Popwindow не показывает тени при установке высоты. Он, похоже, поддерживает его из документации. Я использую 5.0 Lollipop.

Создание всплывающего окна следующим образом:

    popupWindow = new PopupWindow(context);
    popupWindow.setOutsideTouchable(true);
    popupWindow.setFocusable(true);
    popupWindow.setElevation(10);
    popupWindow.setContentView(rootView);
    popupWindow.showAtLocation(anchorView, Gravity.NO_GRAVITY, xPos, yPos);

Ответ 1

Как ответил разработчик Android.

Если надутое представление не имеет фонового набора или всплывающее окно само окно не имеет фонового набора (или имеет прозрачный фон), тогда вы не получите тени.

который был моим делом и кажется вашим, поскольку вы не используете setBackgroundDrawable.

Это сработало для меня

popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));

Я открыл новую проблему, предлагая обновить документацию (https://code.google.com/p/android/issues/detail?id=174919)

Ответ 2

Для тех, кто посещает этот ответ и пропустил то, что уже было у ОП, вы должны установить высоту, чтобы создать тень:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    popupWindow.setElevation(20);
}

PopupWindow with shadow

В зависимости от того, как выглядит ваш контент, вам также может понадобиться установить фон для рисования, хотя это не всегда необходимо. При необходимости вы можете сделать, как предложено @Maragues:

popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));

Для поддержки устройств до Lollipop вы можете использовать 9-патч или изображение, содержащее тень внутри него.

Код

Это код для изображения выше.

LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = inflater.inflate(R.layout.popup_window, null);
int width = LinearLayout.LayoutParams.WRAP_CONTENT;
int height = LinearLayout.LayoutParams.WRAP_CONTENT;
boolean focusable = true;
final PopupWindow popupWindow = new PopupWindow(popupView, width, height, focusable);
popupView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        popupWindow.dismiss();
        return true;
    }
});

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    popupWindow.setElevation(20);
}

popupWindow.showAtLocation(anyView, Gravity.CENTER, 0, 0);

Замечания:

Высота указывается в пикселях, если задано в коде, но обычно в dp, если задано в xml. Вы должны преобразовать значение dp в пиксели при установке его в коде.

Ответ 3

  • setElevation не показывал тень, потому что мой контейнер был прозрачным
  • Мой контейнер был прозрачным, потому что мне нужно было заполнить каждую сторону

Снимок экрана с кодом ниже

  • Я сделал три контейнера
  • Внешний самый контейнер прозрачный
  • Следующий контейнер внутри имеет нарисованный фон с тенью
  • Следующий контейнер содержит фактическое содержимое
  • Минимальная ширина кнопки внутри xml помогает определять ширину. То же самое со 2-м контейнером 12дп прокладки.

Пользовательский класс Popup Window, написанный на Kotlin:

class CustomPopupWindow(
    private val context: Context
) : PopupWindow(context) {

  init {
    val view = LayoutInflater.from(context).inflate(R.layout.popup_window_layout, null)
    contentView = view

    height = ListPopupWindow.WRAP_CONTENT
    width = ListPopupWindow.MATCH_PARENT
    isOutsideTouchable = true

    setTouchDismissListener()

    // set the background of the second container to the drawable
    // with the shadow to get our shadow
    contentView.findViewById<LinearLayout>(R.id.outer_content_container).setBackgroundDrawable(context.resources.getDrawable(R.drawable.background_shadow))
  }

  // Add a listener to dismiss the popup Window when someone
  // clicks outside of it
  private fun setTouchDismissListener() {
    setTouchInterceptor { _, event ->
      if (event != null && event.action == MotionEvent.ACTION_OUTSIDE) {
        dismiss()
        [email protected] true
      }
      false
    }
  }

  // this anchor view can be ANY view
  fun show(anchor: View) {

    // Remove the default background that is annoying
    setBackgroundDrawable(BitmapDrawable())

    // Grab the pixel count for how far down you want to put it.
    // toolbar_height is 56dp for me
    val yOffSetInPixels = context.resources.getDimensionPixelSize(R.dimen.toolbar_height)

    // Animation to make it appear and disappear like a Dialog
    animationStyle = android.R.style.Animation_Dialog

    // Show it
    showAtLocation(anchor, Gravity.TOP, 0, yOffSetInPixels)
  }
}

  • XML для Custom PopupWindow:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="@android:color/transparent"
  android:orientation="vertical">

  <android.support.constraint.ConstraintLayout
    android:id="@+id/transparent_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@android:color/transparent"
    android:padding="12dp">

    <LinearLayout
      android:id="@+id/outer_content_container"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/white"
      android:orientation="vertical"
      app:layout_constraintBottom_toBottomOf="@+id/transparent_container"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/transparent_container">

      <LinearLayout
        android:id="@+id/content_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="12dp">

        <TextView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:text="Header" />

        <LinearLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:layout_gravity="center_vertical"
          android:layout_marginTop="8dp"
          android:orientation="horizontal">

          <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:paddingEnd="0dp"
            android:paddingStart="8dp"
            android:text="Message" />

        </LinearLayout>

        <TextView
          android:id="@+id/add_to_bag_button"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_marginTop="16dp"
          android:height="48dp"
          android:background="@color/gray"
          android:gravity="center"
          android:minWidth="350dp"
          android:text="BUTTON"
          android:textAllCaps="true" />

      </LinearLayout>

    </LinearLayout>

  </android.support.constraint.ConstraintLayout>

</LinearLayout>

  • Custom Drawable, который показывает тень:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

  <!-- Drop Shadow Stack -->
  <item>
    <shape>
      <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="0dp" />

      <solid android:color="#00CCCCCC" />

      <corners android:radius="3dp" />
    </shape>
  </item>
  <item>
    <shape>
      <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="0dp" />

      <solid android:color="#10CCCCCC" />

      <corners android:radius="3dp" />
    </shape>
  </item>
  <item>
    <shape>
      <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="0dp" />

      <solid android:color="#20CCCCCC" />

      <corners android:radius="3dp" />
    </shape>
  </item>
  <item>
    <shape>
      <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="0dp" />

      <solid android:color="#30CCCCCC" />

      <corners android:radius="3dp" />
    </shape>
  </item>
  <item>
    <shape>
      <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="0dp" />

      <solid android:color="#50CCCCCC" />

      <corners android:radius="3dp" />
    </shape>
  </item>

  <!-- Background -->
  <item>
    <shape>
      <solid android:color="@android:color/white" />

      <corners android:radius="0dp" />
    </shape>
  </item>

</layer-list>

  • Используя все это:
val popupWindow = CustomPopupWindow(activity);
popupWindow.show(anyViewInYourActivity);