Как установить поля в пользовательский диалог?

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

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

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

EDIT: добавлен макет диалога

<?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>

Ответ 1

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

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

Диалоговый фон:

<?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);

Ответ 2

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

<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" >

Ответ 3

У меня была та же проблема, и я решил ее, установив фон окна на 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 для всех ребер.

Ответ 4

Обходное решение может быть выполнено следующим образом:

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

Ответ 5

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

Я опробовал свой подход для 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 содержит расширенные версии, которые также поддерживают режим immersve.

Ответ 6

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_margin="22dp"
        android:orientation="vertical"
        android:layout_width="220dp"
        android:layout_height="wrap_content">

    ... Buttons, TextViews, etc

    </LinearLayout>

</LinearLayout>

Наблюдатель: это сработало, когда мне хотелось получить поля внутри моего AlertDialog. Не касается экрана.

Ответ 7

1) измените высоту основного родительского макета match_content как 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();

Ответ 8

Если вы создаете собственный диалог с фоном, вы можете предпочесть следующие строки кода. Вы можете изменить свойство окна 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 для вашего диалогового окна, установив 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>