23

I would like to add a vertical scrollbar to an AlertDialog because my text is too long to display on 1 screen:

I have tried to use :

android:scrollbars="vertical" 
android:scrollbarAlwaysDrawVerticalTrack="true"

but the scrollbars don't even display ?

Here's the xml layout file I'm using:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:scrollbars="vertical"
    android:scrollbarAlwaysDrawVerticalTrack="true"
    android:id="@+id/instructions_view" >
    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="A LONG TEXT 1"/>

    <TextView 
        android:id="@+id/TextView02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="A LONG TEXT 2"/>

</LinearLayout>

I call the AlertsDialog with :

public void onClick(View v) {
  switch(v.getId()){

    case R.id.Button_Instructions: 
     InstructionsDialog();
    break;

    case R.id.Button_Exit: 
     ExitDialog();
    break;
    }
 }

public void InstructionsDialog(){

  AlertDialog.Builder ad = new AlertDialog.Builder(this);
  ad.setIcon(R.drawable.icon);
  ad.setTitle("Instructions ...");
  ad.setView(LayoutInflater.from(this).inflate(R.layout.instructions_dialog,null));

  ad.setPositiveButton("OK", 
    new android.content.DialogInterface.OnClickListener() {
     public void onClick(DialogInterface dialog, int arg1) {
      // OK, go back to Main menu
     }
    }
   );

   ad.setOnCancelListener(new DialogInterface.OnCancelListener(){
    public void onCancel(DialogInterface dialog) {
     // OK, go back to Main menu   
    }}
   );

  ad.show();
 }

I found the answer now=> IT WORKS NOW WITH THIS :

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ScrollView01"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        android:scrollbarAlwaysDrawVerticalTrack="true"
        android:id="@+id/instructions_view" >

        <TextView
            android:id="@+id/TextView01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="A LONG TEXT 1"/>

        <TextView
            android:id="@+id/TextView02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="A LONG TEXT 2"/>

    </LinearLayout>
</ScrollView>
S.R
  • 2,819
  • 2
  • 22
  • 49
Hubert
  • 16,012
  • 18
  • 45
  • 51

5 Answers5

43

In order for a view to scrollable, it must be nested inside of a ScrollView container:

<ScrollView>
    <LinearLayout android:orientation="vertical"
            android:scrollbars="vertical"
            android:scrollbarAlwaysDrawVerticalTrack="true">
        <TextView />
        <Button />
    </LinearLayout>
</ScrollView>

Note that a ScrollView container can only have one child layout view. It is not possible, for example, to place a TextView and Button in a ScrollView without the LinearLayout.

John Leehey
  • 22,052
  • 8
  • 61
  • 88
21
AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle("YOUR_TITLE")
                .setMessage("YOUR_MSG")
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .setIcon(android.R.drawable.ic_dialog_info)
                .show();
        TextView textView = (TextView) dialog.findViewById(android.R.id.message);
        textView.setMaxLines(5);
        textView.setScroller(new Scroller(this));
        textView.setVerticalScrollBarEnabled(true);
        textView.setMovementMethod(new ScrollingMovementMethod());
Melbourne Lopes
  • 4,817
  • 2
  • 34
  • 36
  • I had to remove this line to get the scrolling to work. `textView.setMaxLines(5);` – g2server Feb 19 '17 at 02:26
  • doesn't maky any sense with `textView.setMaxLines(5);` and you don't need to edit textview properties to get scrolling working, it works by default. Another question - how also make scrollbar visible? scrolling works but you can't see scrollbar – user924 Nov 13 '17 at 10:55
  • This really is a sweet approach! – George Mar 29 '18 at 21:29
  • 1
    thanks. worked like a charm. just like what i needed. – federico verchez Nov 24 '20 at 22:59
  • 1
    By the way, it did not work for me with AndroidX `AlertDialog`, only the framework one (`android.app.AlertDialog` rather than `androidx.appcompat.app.AlertDialog`). When using AndroidX I got weird behaviour with the scroll downwards getting stuck and not being able to scroll upwards. – Adam Burley Nov 30 '21 at 15:04
1

All code found here is deprecated.

You should now use (in the layout file for your dialog)

NestedScrollView

<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:fillViewport="true"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:padding="16dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.core.widget.NestedScrollView>

Besides, it is no more recommanded to use AlertDialog alone. You have to implement your own DialogFragment by extending DialogFragment.

See : https://developer.android.com/guide/topics/ui/dialogs

Then you can call your dialog fragment :

MyDialogFragment dialogFragment = MyDialogFragment.newInstance();
dialogFragment.show(fragment.getFragmentManager(), MyDialogFragment.TAG);
Zhar
  • 3,330
  • 2
  • 24
  • 25
0

Using this it works :

 .setScrollable(true)

Use this in your AlertDialogBox or MaterialStyledDialog.

 private void gettermsandconditions() {
    final MaterialStyledDialog dialogHeader_1 =
            new MaterialStyledDialog.Builder(this)
                    .setTitle("Terms and Conditions !")
                   // .setDescription("What can we improve? Your feedback is always welcome.")
                    .setDescription(R.string.Terms_and_condition)

                    .setIcon(R.drawable.bill_icon)
                    .setStyle(Style.HEADER_WITH_ICON)
                    .setHeaderColor(R.color.colorPrimary)
                    .withDarkerOverlay(true)
                    .setScrollable(true)
                    .onPositive(new MaterialDialog.SingleButtonCallback() {
                        @Override
                        public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                          //  startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + context.getPackageName())));
                        }
                    })
                    .setNegativeText("Ok")
                    .build();
    //.setStyle(Style.HEADER_WITH_TITLE)
    dialogHeader_1.show();

}
Hanisha
  • 849
  • 10
  • 8
  • A good solution, but please consider crediting the source. `MaterialStyledDialog` is a custom third-party class and not part of Android Material Components catalog, so some people might get confused. – CzarMatt Jul 06 '20 at 04:15
0

On Android Q the scrollbars can be made always visible.

After creating and showing the dialog, find the TextView holding the message and modify it like this. (BTW the call to setMaxLines(5) is just to limit the number of visible lines to demonstrate the scrolling. Set it as you will, or remove it):

    TextView textView = (TextView) dialog.findViewById(android.R.id.message);
    textView.setMaxLines(5);
    textView.setVerticalScrollBarEnabled(true);
    textView.setMovementMethod(new ScrollingMovementMethod());
    textView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        textView.setScrollbarFadingEnabled(false);
        textView.setVerticalScrollbarTrackDrawable(m_mainActivity.getResources().getDrawable(R.drawable.scrollbar_track_vertical));
        textView.setVerticalScrollbarThumbDrawable(m_mainActivity.getResources().getDrawable(R.drawable.scrollbar_thumb_vertical));
    }

Two drawables are needed.

For app/src/main/res/drawable/scrollbar_thumb_vertical.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient
        android:angle="0"
        android:endColor="#D8D8D8"
        android:startColor="#F7F7F7" />

    <corners android:radius="6dp" />

</shape>

And for app/src/main/res/drawable/scrollbar_thumb_vertical.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:angle="0"
        android:endColor="#757575"
        android:startColor="#A0A0A0" />

    <corners android:radius="6dp" />
</shape>
BitByteDog
  • 3,074
  • 2
  • 26
  • 39