SeekBar setProgress trashes secondary progress

匿名 (未验证) 提交于 2019-12-03 01:20:02

问题:

I have primary and secondary progress growing in the same time, secondary progress grows faster than primary. Everytime I update the primary progress, the secondary one is lost (like it would be zero or less than primary). This produces a nasty flickering.

The only workaround I found is set the secondary to itself after setting the primary. I added "+1" as SeekBar has a check and doesn't redraw if I set the same value.

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

The second line may fix it, but it looks ridiculous and I guess inefficient too.

This happens on Lollipop (5.0.1) - API 21. It used to work fine before - can't figure out why.

If I build for API level 19 it works fine. (video: API19Seekbar)

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

If I build for API level 21 it flickers. (video: API21SeekBar)

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

Full example Activity code follows:

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);     }  } 

回答1:

This has been fixed for the next Android release, but the best workaround for now would probably be to copy scrubber_progress_horizontal_material.xml and its 9-patch PNGs from the SDK resources (<sdk-root>/platforms/android-21/data/res/...), then to rearrange the tags so that <layer-list> is at the root.

Here is what the revised XML should look like:

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> 

And then the appropriate changes in values-v21/styles.xml and/or your layout XML so that you use this background by default on API 21+. I can include examples for those if you need them.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!