Открытие настраиваемого диалогового окна со счетчиком TimePicker внутри пользовательских настроек приводит к появлению полосы прокрутки внутри TimePicker.

У меня есть пользовательский диалог с TimePicker в режиме счетчика, который я показываю с помощью пользовательских настроек на экране настроек. Когда всплывает пользовательское диалоговое окно, рядом с окном выбора времени spinner_mode появляется полоса прокрутки. Затем эта полоса прокрутки исчезнет. (скриншот, сделанный до исчезновения полосы прокрутки) (gif полосы прокрутки, появляющейся в диалоговом окне) Это происходит только тогда, когда пользовательское диалоговое окно отображается на экране настроек (Пользовательские настройки). Я использовал этот же диалог в других местах приложения, и он отлично работает.

Как сделать так, чтобы он не отображался?

Прикрепление всех пользовательских классов ниже.

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>

person nightfury    schedule 07.07.2020    source источник
comment
Он сразу проходит или как исчезает? Возможно, попробуйте ConstraintLayout для custom_dialog_layout и временно удалите кнопки, чтобы посмотреть, изменит ли это что-нибудь.   -  person einUsername    schedule 07.07.2020
comment
@einUsername В вопрос добавлена ​​картинка исчезающей серой области. Также попробовал Constraint Layout и удаление кнопок без везения.   -  person nightfury    schedule 08.07.2020
comment
Просто наблюдение: эти строки выглядят как полосы прокрутки. Они исчезают примерно с одинаковой скоростью, и логично, что второй меньше, потому что у него больше цифр. Возможно, стиль полосы прокрутки изменился в результате действия предпочтений. androidopentutorials.com/android-vertical-scrollbar-styling Или вы можете попробовать обычный НомерПикер тоже.   -  person einUsername    schedule 08.07.2020
comment
@einUsername Похоже, это полоса прокрутки.!!!! Я разместил NumberPicker, и в нем происходит то же самое. Мне удалось удалить полосу прокрутки из NumberPicker, но у TimePicker нет свойства полосы прокрутки. Пробовал многие свойства, используя Без изменений для полосы прокрутки TimePicker. Я обновил вопрос, изменив серую область на полосу прокрутки.   -  person nightfury    schedule 08.07.2020


Ответы (2)


Если вы знаете, как исправить это с помощью NumberPicker, то это должно быть легко и с TimerPicker.
Они состоят из 2 LinearLayout, 3 NumberPickers и 1 MaterialTextView.
Вы можете использовать метод getChild() для прокрутите их и проверьте с помощью instanceof, на каком из них вы находитесь.

Из этого сообщения:

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);
        }
    }
}
person einUsername    schedule 08.07.2020
comment
Для TimePicker есть только 1 дочерний элемент, который представляет собой линейный макет. Таким образом, строка if (v instanceof NumberPicker) всегда ложна. Редактировать: я рекурсивно искал детей и, наконец, нашел два элемента timePicker. Думаю, я просто назову эти два элемента. вместо того, чтобы перебирать все подряд. Спасибо, что указали мне правильное направление. Я опубликовал ответ, который использовал для решения, как отдельное решение, на случай, если кто-то столкнется с той же проблемой и ему понадобится помощь. - person nightfury; 08.07.2020

Это то, что наконец убрало полосы прокрутки

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

Размещен внутри CustomDialog.java

Это специально установит для полосы прокрутки часов и минут NumberPicker внутри TimePicker значение none.

Спасибо @einUsername за то, что указал мне правильное направление.

person nightfury    schedule 08.07.2020