SeekBar setProgress сбрасывает вторичный прогресс

У меня первичный и вторичный прогресс растут одновременно, вторичный прогресс растет быстрее, чем первичный. Каждый раз, когда я обновляю первичный прогресс, вторичный теряется (как будто он равен нулю или меньше, чем первичный). Это вызывает неприятное мерцание.

Единственный обходной путь, который я нашел, - установить вторичный файл на себя после установки основного. Я добавил «+1», так как SeekBar имеет проверку и не перерисовывается, если я устанавливаю то же значение.

        mSeekBar.setProgress(newPosition);
        mSeekBar.setSecondaryProgress(mSeekBar.getSecondaryProgress()+1); // WTF?

Вторая строка может исправить это, но это выглядит нелепо и, я думаю, тоже неэффективно.

Это происходит на Lollipop (5.0.1) - API 21. Раньше все работало нормально - не могу понять, почему.

Если я строю для уровня API 19, он работает нормально. (видео: API19Seekbar)

targetSdkVersion 19
compile 'com.android.support:appcompat-v7:19.+'

Если я строю для уровня API 21, он мерцает. (видео: API21SeekBar)

targetSdkVersion 21
compile 'com.android.support:appcompat-v7:21.+'

Ниже приведен полный пример кода действия:

int delay1 = 1000;
int delay2 = 200;
int primaryProgress;
int secondaryProgress;

boolean mStarted;
Button mButton;
SeekBar mSeekBar;
Handler h1 = new Handler();
Handler h2 = new Handler();

Runnable primary = new Runnable() {
    @Override
    public void run() {
        primaryProgress = (primaryProgress + 1) % 100;
        mSeekBar.setProgress(primaryProgress);
        h1.postDelayed(primary, delay1);
    }
};

Runnable secondary = new Runnable() {
    @Override
    public void run() {
        secondaryProgress = (secondaryProgress + 1) % 100;
        mSeekBar.setSecondaryProgress(secondaryProgress);
        h2.postDelayed(secondary, delay2);
    }
};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mButton = (Button)findViewById(R.id.button);
    mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            buttonClick();
        }
    });
    mSeekBar = (SeekBar)findViewById(R.id.seekBar);
}

private void buttonClick() {
    mStarted = !mStarted;
    if (mStarted) {
        mButton.setText("Started");
        h1.postDelayed(primary, delay1);
        h2.postDelayed(secondary, delay2);
    } else {
        mButton.setText("Stopped");
        h1.removeCallbacks(primary);
        h2.removeCallbacks(secondary);
    }

}

person RumburaK    schedule 03.02.2015    source источник
comment
Сообщите об ошибке в системе отслеживания проблем AOSP. Вероятно, это проблема с фреймворком или приложением.   -  person alanv    schedule 04.02.2015
comment
Спасибо Алан! Я буду. Как вы думаете, я могу как-то замаскировать это, используя другую тему или что-то в этом роде?   -  person RumburaK    schedule 04.02.2015
comment
Таким образом, проблема в том, что SeekBar по умолчанию progressDrawable имеет <selector> в качестве корня, но корень должен быть <layer-list>. Лучшим способом, вероятно, было бы скопировать scrubber_progress_horizontal_material.xml и его 9-патч PNG из ресурсов SDK, а затем переставить теги так, чтобы <layer-list> был в корне. Если вам не нужно отключенное состояние, это так же просто, как удалить внешний элемент и дополнительный элемент отключенного состояния.   -  person alanv    schedule 05.02.2015
comment
Вы нашли способ постоянного способа исправить это?   -  person Yuri Heupa    schedule 27.04.2016
comment
проверьте ответ на ваш другой комментарий (в решении)   -  person RumburaK    schedule 28.04.2016


Ответы (1)


Это было исправлено в следующем выпуске Android, но лучшим обходным решением на данный момент, вероятно, будет копирование scrubber_progress_horizontal_material.xml и его 9-исправлений PNG из ресурсов SDK (<sdk-root>/platforms/android-21/data/res/...), а затем перестановка тегов так, чтобы <layer-list> был в корне.

Вот как должен выглядеть пересмотренный XML:

drawable-v21/scrubber_progress_horizontal_material_fixed.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <nine-patch
            android:src="@drawable/scrubber_track_mtrl_alpha"
            android:tint="?android:attr/colorControlNormal" />
    </item>
    <item android:id="@android:id/secondaryProgress">
        <scale android:scaleWidth="100%">
            <selector>
                <item android:state_enabled="false">
                    <color android:color="@android:color/transparent" />
                </item>
                <item>
                    <nine-patch
                        android:src="@drawable/scrubber_primary_mtrl_alpha"
                        android:tint="?android:attr/colorControlNormal" />
                </item>
            </selector>
        </scale>
    </item>
    <item android:id="@android:id/progress">
        <scale android:scaleWidth="100%">
            <selector>
                <item android:state_enabled="false">
                    <color android:color="@android:color/transparent" />
                </item>
                <item>
                    <nine-patch
                        android:src="@drawable/scrubber_primary_mtrl_alpha"
                        android:tint="?android:attr/colorControlActivated" />
                </item>
            </selector>
        </scale>
    </item>
</layer-list>

А затем внесите соответствующие изменения в values-v21/styles.xml и/или XML вашего макета, чтобы вы использовали этот фон по умолчанию в API 21+. Я могу включить примеры для тех, если они вам нужны.

person alanv    schedule 05.02.2015
comment
Спасибо, Алан, я попробую это в ближайшее время. Нужен ли баг в этом случае? - person RumburaK; 05.02.2015
comment
У меня все та же проблема с API21+, инструменты сборки версии 23.0.2. - person Grace Coder; 06.04.2016
comment
Да, это исправлено. Перестаньте искать обходные пути и используйте последние SDK и библиотеки поддержки:compileSdkVersion 23 / targetSdkVersion - doesn't matter (19, 21, 23 etc) / compile 'com.android.support:appcompat-v7:23.3.0' Я поделился мини-проектом, который вы можете использовать для тестирования: github.com/rumburake/TestSeekBar - person RumburaK; 28.04.2016