it-roy-ru.com

Android PopupWindow высота не показывает тень

Android Всплывающее окно не отображает тени при установке высоты. Похоже, чтобы поддержать это из документации. Я использую 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);
23
Patrick

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

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

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

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

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

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

19
Maragues

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

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 в пиксели при установке его в коде.

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

Скриншот приведенного ниже кода

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

Пользовательский класс 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);
0
caseta