nightfury
nightfury

Reputation: 19

Opening Custom Dialog with spinner TimePicker inside Custom Preference causes scrollbar to appear inside TimePicker

I have a Custom Dialog with a TimePicker in spinner mode, which I show using a Custom Preference inside a Preference Screen. When the Custom Dialog pops-up there is a scrollbar that appears near the spinner_mode Time Picker. This scrollbar will then fade out. (screenshot taken before scrollbar faded) (gif of scrollbar appearing in dialog) This only happens when the Custom Dialog is shown from the Preference Screen (Custom Preference). I have used this same dialog in other places of the app and it works fine.

How do I stop it from showing up?

Attaching all the custom classes below.

SettingsActivity.java

package com.example.testing;

import android.os.Bundle;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceFragmentCompat;

public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.settings_activity);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.settings, new SettingsFragment())
                .commit();
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
    }

    public static class SettingsFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey);
        }
    }
}

root_preferences.xml

<PreferenceScreen>
    <com.example.testing.CustomPreferenceCategory>
    </com.example.testing.CustomPreferenceCategory>
</PreferenceScreen>

CustomPreferenceCategory.java

package com.example.testing;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;

import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceViewHolder;

public class CustomPreferenceCategory extends PreferenceCategory {
    public CustomPreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public CustomPreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CustomPreferenceCategory(Context context, AttributeSet attrs) {
        super(context, attrs);
        setLayoutResource(R.layout.custom_preference_category_layout);
    }

    public CustomPreferenceCategory(Context context) {
        super(context);
    }

    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        Button button = (Button) holder.itemView.findViewById(R.id.button1);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Dialog customDialog = new CustomDialog(getContext());
                customDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        callChangeListener("Doesn't Matter");
                    }
                });
                customDialog.show();
            }
        });
    }
}

custom_preference_category_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_margin="12dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="TEST"
        android:textSize="22sp"
        android:layout_gravity="left|center_vertical"
        android:layout_weight="1"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        android:layout_gravity="right|center_vertical"
        android:layout_weight="0"
        android:id="@+id/button1"
        />
</LinearLayout>

CustomDialog.java

package com.example.testing;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class CustomDialog extends Dialog {
    public CustomDialog(@NonNull Context context) {
        super(context);
    }

    public CustomDialog(@NonNull Context context, int themeResId) {
        super(context, themeResId);
    }

    protected CustomDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_dialog_layout);

        Button okButton = (Button) findViewById(R.id.ok_button);
        Button cancelButton = (Button) findViewById(R.id.cancel_button);

        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });
        okButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });
    }
}

custom_dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <TimePicker
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:timePickerMode="spinner" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="right">

        <Button
            android:id="@+id/ok_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="OK" />


        <Button
            android:id="@+id/cancel_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="cancel" />
    </LinearLayout>
</LinearLayout>

Upvotes: 1

Views: 504

Answers (2)

nightfury
nightfury

Reputation: 19

This is what finally removed the scrollbars

(((LinearLayout) ((LinearLayout) timePicker.getChildAt(0)).getChildAt(0)).getChildAt(0)).setVerticalScrollBarEnabled(false);
(((LinearLayout) ((LinearLayout) timePicker.getChildAt(0)).getChildAt(0)).getChildAt(2)).setVerticalScrollBarEnabled(false);

Placed inside CustomDialog.java

This will specifically set the ScrollBar of the Hour and Minute NumberPicker inside the TimePicker to none.

Thanks to @einUsername for pointing me in the right direction.

Upvotes: 0

einUsername
einUsername

Reputation: 1619

If you know how to fix it with a NumberPicker than it should be easy with a TimerPicker too.
They are made of 2 LinearLayout, 3 NumberPickers and 1 MaterialTextView.
You can use the getChild() method to loop through them and check with instanceof which one you are at.

From this post:

TimePicker timePicker = findViewById(R.id.timePicker);
loopViews(timePicker);

...

private void loopViews(ViewGroup view) {
    for (int i = 0; i < view.getChildCount(); i++) {
        View v = view.getChildAt(i);
        Log.d("TAG", "loop " + i + " " + v.getClass());

        if (v instanceof NumberPicker) {
            ((NumberPicker)v).setMaxValue(1); //Do anything with this NumberPicker.

        } else if (v instanceof ViewGroup) {
            this.loopViews((ViewGroup) v);
        }
    }
}

Upvotes: 0

Related Questions