Почему Dialog отображается как будто с Gravity.TOP, а необходимо по центру?

Снова обращаюсь к вам за помощью.

Необходимо показать AlertDialog c нестандартным фоном (в данном случае размытый фон, а вообще говоря, динамическое изображение в зависимости от того, что на экране).

Код xml для диалога, указанно android:layout_gravity="center":

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_gravity="center"
    xmlns:android="http://schemas.android.com/apk/res/android">

<SeekBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/seekBar"
        android:layout_gravity="center_horizontal"
        android:max="255"/>
</RelativeLayout>


Собственно, код DialogFragmenta:
public class CustomDialog extends DialogFragment implements  DialogInterface.OnClickListener {

   public Dialog onCreateDialog(Bundle savedInstanceState) {
		AlertDialog.Builder adb = new AlertDialog.Builder(getActivity())
               .setPositiveButton("yes", this)
               .setNegativeButton("no", this);
		LayoutInflater inflater = getActivity().getLayoutInflater();
		adb.setView(inflater.inflate(R.layout.slider_item, null));
		Dialog dialog = adb.create();
		Bitmap map=takeScreenShot(getActivity());
        Bitmap fast= FastBlur.doBlur(map, 10, true);
        final Drawable draw=new BitmapDrawable(getActivity().getResources(),fast);
        dialog.getWindow().setBackgroundDrawable(draw);
		// dialog.getWindow().getAttributes().gravity = Gravity.CENTER_VERTICAL;
//       WindowManager.LayoutParams wmlp = dialog.getWindow().getAttributes();
//       wmlp.gravity = Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL;
      
//		Window window = dialog.getWindow();
//		window.setLayout(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
//		window.setGravity(Gravity.CENTER);
		return dialog;
   }
    private static Bitmap takeScreenShot(Activity activity)
    {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap b1 = view.getDrawingCache();
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;
        int width = activity.getWindowManager().getDefaultDisplay().getWidth();
        int height = activity.getWindowManager().getDefaultDisplay().getHeight();

        Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height  - statusBarHeight);
        view.setDrawingCacheEnabled(false);
        return b;
    }

    @Override
    public void onClick(DialogInterface dialogInterface, int i) {

    }
}

но почему о показывает как на изображении.
8ab3fd38e95746baad69bae7ca59a027.png

Как видите, пробовал несколько вариантов настройки LayoutParams - закомментированное, ни один не помогает...
Без dialog.getWindow().setBackgroundDrawable(draw); показывает стандартный диалог, но мне как раз необходимо настраивать свой фон из изображения.

Подскажите, как можно решить проблему и в чем сама проблема?
  • Вопрос задан
  • 3145 просмотров
Решения вопроса 1
@Sekorashka Автор вопроса
В общем решение получилось достаточно криворуким, но таки решением.

Все на самом деле просто. Делаем dialog в DialogFragment из onCreateView():
1) Задаем layout с imageView как фон, блюрим скриншот экрана и вставляем фоном в imageView
2) Создаем любой alertDialog и показываем его, не забудьте на кнопки в диалоге поставить закрытие фрагмента, чтобы закрылся весь диалог, иначе фон останется
3) Затем вызываем диалог как обычный фрагмент, но в качестве контейнера подаем весь экран.

Проблемы:
1) чисто блюровская проблема с поворотом экрана - не сделать скриншот, во время поворота - не из чего(для меня не проблема - многие приложения жестко привязаны к ориентации)
2) мое незнание - как взять в качестве контейнера view вместе с actionBarом - про android.R.id.content знаю, но он берет только сам контейнер не включая actionbar + расстановка id для view(просто никогда не занимался этим)
предполагаю как то можно объединить android.R.id.content c android.R.id.action_bar_container и его дополнительными кнопками, но не знаю как, может кто поможет?

кому интересно код ниже:

DialogFragment(c парой костылей, связанных как раз с проблемой взятия экрана activity):

public class CustomAlertDialog extends DialogFragment implements  DialogInterface.OnClickListener {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.alert_custom_dialog, container, false);
		ImageView background = (ImageView) rootView.findViewById(R.id.image);
        Rect frame = new Rect();
        getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        params.setMargins(0, statusBarHeight, 0, 0);
        background.setLayoutParams(params);
        Bitmap map=takeScreenShot(getActivity());
        Bitmap fast= FastBlur.doBlur(map, 10, true);
        final Drawable draw=new BitmapDrawable(getActivity().getResources(),fast);
        background.setImageDrawable(draw);
        AlertDialog.Builder adb = new AlertDialog.Builder(getActivity())
                .setPositiveButton("yes", this)
                .setNegativeButton("no", this);
        LayoutInflater dialogInflater = getActivity().getLayoutInflater();
        adb.setView(dialogInflater.inflate(R.layout.slider_item, null)).show();
        return rootView;
    }

    private static Bitmap takeScreenShot(Activity activity)
    {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap b1 = view.getDrawingCache();
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;
        int width = activity.getWindowManager().getDefaultDisplay().getWidth();
        int height = activity.getWindowManager().getDefaultDisplay().getHeight();

        Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height  - statusBarHeight);
        view.setDrawingCacheEnabled(false);
        return b;
    }

    @Override
    public void onClick(DialogInterface dialogInterface, int i) {
        getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
    }
}


ну и вызов из другого фрагмента(может как раз тут подскажите как взять весь экран с actionbarом?)

public void showDialogFragment() {
        View v = getActivity().getWindow().getDecorView();
        v.setId(1);
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        DialogFragment newFragment = new CustomAlertDialog();
            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            transaction.add(1, newFragment)
                    .addToBackStack(null).commit();
    }


xml та же

и да картинка для привлечения внимания)
6cf21919baca46b18cc05f3dbd07b5ff.png
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Collosteam
@Collosteam
Android кодирую
Я обычно делаю так

<!--Обязательно в корневом Layout делаем wrap_content по width и height-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"
    android:gravity="center"
    android:layout_gravity="center">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:orientation="vertical"
        android:layout_gravity="center">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="64dp"
            android:background="@color/cp_yellow">
            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Title"
                android:textColor="@android:color/white"
                android:textSize="22sp" />
        </RelativeLayout>
        <ScrollView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center">
            <FrameLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:gravity="center">
                <ProgressBar
                    android:id="@android:id/progress"
                    style="?android:attr/progressBarStyleLarge"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:gravity="center" />
                <com.RichEditText.colorpicker.ColorPickerPalette
                    android:id="@id/color_picker"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:gravity="center"
                    android:visibility="gone" />
            </FrameLayout>
        </ScrollView>
    </LinearLayout>
</FrameLayout>


в FragmentDialog переопределяю onCreateView

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = LayoutInflater.from(getActivity()).inflate(R.layout.color_picker_dialog, null);  // Находим наш Layout
        this.mProgress = ((ProgressBar) view.findViewById(android.R.id.progress));
        this.mPalette = ((ColorPickerPalette) view.findViewById(R.id.color_picker));
        this.mPalette.init(this.mSize, this.mColumns, this);
        if (this.mColors != null)
            showPaletteView();
        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);  //Прячем стандартный Title
        return view;
    }


ZPe76Z8cmo0.jpg

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

По другому кастомизировать AlertDialog не получилось.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы