2011-05-27 99 views
35

有誰知道我如何設置邊距到自定義對話框?我在問,因爲我有一個自定義對話框,但是在顯示時會拉伸以填充父對象,即使我在佈局參數上明確設置了WRAP_CONTENT。如何將頁邊距設置爲自定義對話框?

基本上,對話框包含一個listview,其元素必須向下滾動,例如元素爲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> 

回答

71

頁邊距沒有爲對話框工作,我想象中的頂層窗口的觀點是不支持邊距的佈局類型。我已經看過帖子說,當定義爲對話框的樣式(而不是頂層視圖元素)時,邊距將起作用,但這似乎也不起作用。

解決此問題需要做的事情是使用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參數傳遞給您的Dialog的構造函數,如new Dialog(context, R.style.Dialog);

+2

如果在對話框樣式中使用dialog_background_inset drawable作爲windowBackground,並且不使用背景作爲對話框佈局,則不必擔心在佈局中包含額外的填充以允許插入。 – ChrisJD 2012-09-05 06:08:01

+3

@ChrisJD我無法得到它的工作。無論如何,pospi解決方案正在工作。有時真的很奇怪Android需要多少奇怪的代碼來實現非常簡單的事情。 – Piotr 2012-09-27 10:45:30

+1

@pospi你是否知道如何在對話框內容之外點擊時取消它?因爲它無法使用您的解決方案。 – Piotr 2012-09-27 11:29:47

10

保證金看起來不適用於對話框的自定義佈局,但是可以使用填充工作。嘗試在頂層線性佈局上設置填充。

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

一種解決方法可以這樣做:

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

它只對dialog.show();,如下設置它:WindowManager .LayoutParams params = dialog.getWindow()。getAttributes(); params.height =(int)(Utils.getDeviceMetrics(LoginActivity.this).height * 0.8); dialog.getWindow()。setAttributes(params); – 2018-01-24 22:28:17

-1

一個簡單的解決方案,爲我工作是包裝在另一個我的整個景觀一個,並設置現在的內部視圖的邊緣。

<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內想利潤率奏效。不涉及屏幕。

+0

所以你可以添加填充而不是將其包裹在另一個佈局中 – arekolek 2017-02-28 14:58:48

+0

根視圖本身的填充不起作用請在測試代碼之前測試它,這是錯誤的,並降低了它的效果。 – 2017-03-01 17:02:41

1

這是一個直接的,程序化的方式來設置我的對話框的邊緣位置和大小。

我測試了我的一個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 answers中解釋。

這個Gist包含支持沉浸模式的擴展版本。

6

我有同樣的問題,我解決它通過設置一個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的所有邊緣的利潤率出現。

+0

它在較新的API上工作,但是當我在API 16上測試時,它在AlertDialog周圍顯示一個黑色邊框。 – 2018-01-24 19:57:41

相關問題