Как установить поля для настраиваемого диалога? - PullRequest
46 голосов
/ 27 мая 2011

Кто-нибудь знает, как я могу установить поля для настраиваемого диалога? Я спрашиваю, потому что у меня есть настраиваемое диалоговое окно, но при отображении оно растягивается, чтобы заполнить родительский элемент, хотя я явно установил WRAP_CONTENT в параметрах макета.

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

Есть предложения? Я пробовал все возможные комбинации возможных решений без достижения удовлетворительных результатов

РЕДАКТИРОВАТЬ: Добавлена ​​раскладка диалога

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="50dip"   
    android:orientation="vertical"
    android:layout_gravity="top|center">

    <FrameLayout android:layout_width="fill_parent" android:layout_margin="5dip" android:layout_height="wrap_content">

            <TextView android:layout_width="wrap_content"        android:layout_height="wrap_content" 
                android:layout_gravity="center"
                android:textSize="20sp" android:textColor="@color/black"/>

            <Button android:layout_height="32dip" android:layout_width="32dip" 
                android:id="@+id/guide_dialog_cross_button"
                android:background="@drawable/button_cross_white"/>

        </FrameLayout>


    <ListView android:layout_width="fill_parent" android:layout_height="wrap_content" 
        android:fadingEdge="none"
        android:layout_margin="5dip"/>

    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_margin="5dip" />

</LinearLayout>

Ответы [ 8 ]

93 голосов
/ 05 октября 2011

Поля не работают для диалогов, я думаю, что окно верхнего уровня не является типом макета, который поддерживает поля.Я видел сообщения о том, что поля будут работать, когда они определены как стиль диалога (а не как элемент представления верхнего уровня), но это тоже не похоже на работу.

Что нужно сделать, чтобы обойти этопроблема в том, чтобы использовать inset drawable для фона Dialog, и настроить любой отступ, чтобы учесть дополнительную вставку фона.В приведенном ниже примере я просто установлю левые и правые поля.

Фон диалогового окна:

<?xml version="1.0" encoding="utf-8"?>
<!-- drawable is a reference to your 'real' dialog background -->
<!-- insetRight and insetLeft add the margins -->
<inset
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/dialog_background" 
    android:insetRight="10dp"
    android:insetLeft="10dp">
</inset>

Основной вид диалогового окна:

<?xml version="1.0" encoding="utf-8"?>
<!-- paddingTop / paddingBottom padding for the dialog -->
<!-- paddingLeft / paddingRight padding must add the additional inset space to be consistent -->
<!-- background references the inset background drawable -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingTop="5dp"
    android:paddingBottom="5dp"
    android:paddingLeft="15dp"
    android:paddingRight="15dp"
    android:background="@drawable/dialog_background_inset">

<!-- ...the rest of the layout... -->

Вы также можетенеобходимо установить цвет фона самого диалога прозрачным.Добавьте цветовой ресурс, например, так:

<color name="transparent">#00000000</color>

И установите для него цвет фона окна диалога (примечание: вы не можете назначить цвет напрямую, затмение будет жаловаться)

<style name="Dialog" parent="android:style/Theme.Dialog">
    <item name="android:windowBackground">@color/transparent</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">true</item>
</style>

Этот стиль должен быть передан конструктору вашего диалога в качестве аргумента theme, как в new Dialog(context, R.style.Dialog);

17 голосов
/ 21 августа 2017

У меня была та же проблема, и я решил ее, установив фон окна на InsetDrawable:

AlertDialog.Builder builder = new AlertDialog.Builder(context);
...
...
AlertDialog dialog = builder.create();

ColorDrawable back = new ColorDrawable(Color.TRANSPARENT);
InsetDrawable inset = new InsetDrawable(back, 20);
dialog.getWindow().setBackgroundDrawable(inset);

dialog.show();

В этом случае диалоговое окно появится с полем 20 для всех ребер.

16 голосов
/ 14 февраля 2015

Похоже, что поле не работает с пользовательским макетом для диалога, но заполнение работает.Попробуйте установить отступы на верхнем уровне Linear layout.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="4dp"
    android:paddingRight="4dp" >
7 голосов
/ 05 ноября 2015

Обходной путь можно сделать так:

dialog.getWindow().getAttributes().height = 
           (int) (getDeviceMetrics(context).heightPixels*0.8);

` getDeviceMetrics Метод:

public static DisplayMetrics getDeviceMetrics(Context context) {
    DisplayMetrics metrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    display.getMetrics(metrics);
    return metrics;
}
2 голосов
/ 23 февраля 2017

Это простой, программный способ установки позиции и размера моего диалога с полями.

Я проверил свой подход для DialogFragment, применив его в методе onCreateDialog:

public Dialog onCreateDialog( Bundle savedInstanceState )
{
    // create dialog in an arbitrary way
    Dialog dialog = super.onCreateDialog( savedInstanceState ); 
    DialogUtils.setMargins( dialog, 0, 150, 50, 75 );
    return dialog;
}

Этот метод применяет поля к диалоговому окну:

public static Dialog setMargins( Dialog dialog, int marginLeft, int marginTop, int marginRight, int marginBottom )
{
    Window window = dialog.getWindow();
    if ( window == null )
    {
        // dialog window is not available, cannot apply margins
        return dialog;
    }
    Context context = dialog.getContext();

    // set dialog to fullscreen
    RelativeLayout root = new RelativeLayout( context );
    root.setLayoutParams( new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) );
    dialog.requestWindowFeature( Window.FEATURE_NO_TITLE );
    dialog.setContentView( root );
    // set background to get rid of additional margins
    window.setBackgroundDrawable( new ColorDrawable( Color.WHITE ) );

    // apply left and top margin directly
    window.setGravity( Gravity.LEFT | Gravity.TOP );
    LayoutParams attributes = window.getAttributes();
    attributes.x = marginLeft;
    attributes.y = marginTop;
    window.setAttributes( attributes );

    // set right and bottom margin implicitly by calculating width and height of dialog
    Point displaySize = getDisplayDimensions( context );
    int width = displaySize.x - marginLeft - marginRight;
    int height = displaySize.y - marginTop - marginBottom;
    window.setLayout( width, height );

    return dialog;
}

Вот вспомогательные методы, которые я использовал:

@NonNull
public static Point getDisplayDimensions( Context context )
{
    WindowManager wm = ( WindowManager ) context.getSystemService( Context.WINDOW_SERVICE );
    Display display = wm.getDefaultDisplay();

    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics( metrics );
    int screenWidth = metrics.widthPixels;
    int screenHeight = metrics.heightPixels;

    // find out if status bar has already been subtracted from screenHeight
    display.getRealMetrics( metrics );
    int physicalHeight = metrics.heightPixels;
    int statusBarHeight = getStatusBarHeight( context );
    int navigationBarHeight = getNavigationBarHeight( context );
    int heightDelta = physicalHeight - screenHeight;
    if ( heightDelta == 0 || heightDelta == navigationBarHeight )
    {
        screenHeight -= statusBarHeight;
    }

    return new Point( screenWidth, screenHeight );
}

public static int getStatusBarHeight( Context context )
{
    Resources resources = context.getResources();
    int resourceId = resources.getIdentifier( "status_bar_height", "dimen", "android" );
    return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
}

public static int getNavigationBarHeight( Context context )
{
    Resources resources = context.getResources();
    int resourceId = resources.getIdentifier( "navigation_bar_height", "dimen", "android" );
    return ( resourceId > 0 ) ? resources.getDimensionPixelSize( resourceId ) : 0;
}

Вспомогательные методы описаны вдругой из моих SO ответов .

Этот Gist содержит расширенные версии, которые также поддерживают режим погружения.

0 голосов
/ 08 мая 2019

Если вы создаете собственный диалог с фоном, вы можете предпочесть следующие строки кода. Вы можете изменить свойство окна MATCH_PARENT для полного экрана.

Моя проблема заключалась в ширине обработки диалога с его родителем без полей

попробуйте следующий код согласно требованию

    Window window = event_dialog.getWindow();
    window.setGravity(Gravity.CENTER);
    WindowManager.LayoutParams wlp = window.getAttributes();
    wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
    wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
    wlp.flags &= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
    window.setAttributes(wlp);

установите эти свойства до dialog.show() ИЛИ вы можете установить LEFT,RIGHT,TOP,BOTTOM поле для вашего диалога, установив margin для вашего root макета и custom background для его дочернего макета, например

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
   <LinearLayout
    android:id="@+id/customLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/card_round_corner"
    android:orientation="vertical">

   </LinearLayout>
</RelativeLayout>
0 голосов
/ 03 мая 2018

1) измените высоту основного родительского макета match_content, как показано ниже:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_content"
    android:layout_margin="50dip"   
    android:orientation="vertical"
    android:layout_gravity="top|center">

2) теперь добавьте стиль в ваш styles.xml

<style name="dialogTheme" parent="Base.Theme.AppCompat.Light.Dialog.Alert"/>

3) теперь добавьте нижекод для отображения диалога:

Dialog dialog = new Dialog(DayActivity.this, R.style.dialogTheme);
dialog.setContentView(R.layout.dialog_custom_layout);
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
dialog.show();
0 голосов
/ 16 ноября 2016

Простое решение, которое сработало для меня, заключалось в том, чтобы обернуть весь мой вид в другой и установить поле, в котором теперь находится внутренний вид.1004 * в пределах мой AlertDialog.Не касается экрана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...