0

I have a DialogFragment which consists of three parts, from up to down: the title, the central view which displays all the contents, and the bottom pane which holds the PositiveButton "OK":

public Dialog onCreateDialog(Bundle savedInstanceState)
{
FragmentActivity act = getActivity();
LayoutInflater inflater = act.getLayoutInflater();
AlertDialog.Builder builder = new AlertDialog.Builder(act);

// TITLE:
TextView title = (TextView) inflater.inflate(R.layout.dialog_title, null);
title.setText(R.string.updates);
builder.setCustomTitle(title);

// CENTRAL VIEW:
View view = inflater.inflate(R.layout.dialog_updates, null);
// ... customize it ... 
builder.setView(view);

// POSITIVE BUTTON:
builder.setPositiveButton( R.string.ok, new DialogInterface.OnClickListener()
  {
  @Override
  public void onClick(DialogInterface dialog, int which)
    {
    // something
    }
  });
}

The stuff that's shown by the central view is downloaded from the web. Initially, when a user pops up the dialog, the View shows just the "Downloading..." message:

enter image description here

When we get an answer, we create a ScrollView and keep adding vertically scrollable Panes to it like so:

enter image description here

(image above shows three such panes added so far)

The result is that the height of the dialog keeps changing, which is visually unpleasant. So I really want to keep the height of the whole Dialog constant, let's say pinned to 3/4 of the height of the screen. Let's do it then:

public void onResume()
{
super.onResume();

Window window = getDialog().getWindow();
Context context = getContext();

if( window!=null && context!=null )
  {
  DisplayMetrics metrics = context.getResources().getDisplayMetrics();
  final float height= metrics.heightPixels;

  WindowManager.LayoutParams params = window.getAttributes();
  params.width = WindowManager.LayoutParams.WRAP_CONTENT;
  params.height = (int)(0.75f*height);
  window.setAttributes(params);
  }
}

Result:

enter image description here

This does kind of work, as you can see though - it works by enlarging the lower pane with the 'OK' button, rather than the central View.

How to fix this?

EDIT: here's my dialog_title.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:textSize="20sp"
  android:gravity="center"
  android:padding="10dp"/>
Leszek
  • 1,181
  • 1
  • 10
  • 21

1 Answers1

1

One workaround for this issue is to use ConstrainedLayout for your whole dialog like this:

fragment_dialog layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:orientation="vertical">

   <TextView
      android:id="@+id/title"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:gravity="center"
      android:padding="10dp"
      android:text="Updates"
      android:textSize="20sp"
      app:layout_constraintTop_toTopOf="parent" />

   <TextView
      android:id="@+id/central_view"
      android:layout_width="match_parent"
      android:layout_height="0dp"
      android:layout_weight="1"
      android:text="Downloading"
      app:layout_constrainedHeight="true"
      app:layout_constraintBottom_toTopOf="@id/positive_action"
      app:layout_constraintHeight_percent="0.8"
      app:layout_constraintTop_toBottomOf="@id/title" />

   <androidx.appcompat.widget.AppCompatButton
      android:id="@+id/positive_action"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="end"
      android:layout_margin="8dp"
      android:text="OK"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

You can change the percentage of your central view with app:layout_constraintHeight_percent="0.8"

DialogFragment class:

public class LoadingDialog extends DialogFragment {

   @NonNull
   @Override
   public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
      FragmentActivity act = getActivity();
      LayoutInflater inflater = act.getLayoutInflater();
      View view = inflater.inflate(R.layout.fragment_dialog, null);
      AlertDialog.Builder builder = new AlertDialog.Builder(act).setView(view);

      // POSITIVE BUTTON:
      view.findViewById(R.id.positive_action).setOnClickListener(new View.OnClickListener() {

         @Override
         public void onClick(View v) {
            //something
         }
      });

      return builder.create();
   }

   @Override
   public void onResume() {
      super.onResume();
      getDialog().getWindow().setLayout(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
      );
   }
}

And you will get this result:

Result

hiddeneyes02
  • 2,562
  • 1
  • 31
  • 58
  • Thanks a lot hiddeneyes for such an indepth answer. Let me try this and I'll accept if I don't find any major issues ! – Leszek Jan 25 '22 at 14:51