2011-06-13 63 views
2

我需要在我的ListView行中將覆蓋圖像繪製到SeekBar上。這並不難,而且這個問題中的代碼通過在位圖中繪製行號並將其放置爲可繪製的進度來完成該操作。SeekBar drawable在被適配器重新使用後沒有繪製

我遇到的問題是,這隻能工作一次。當視圖被回收用於另一行時,可繪製消失。

enter image description here

前10次(位置0到9)的工作。之後的一切都失敗了。沒有錯誤或例外。 Android只是停止繪製該圖層。如果我向下滾動然後備份,它們都不起作用(因爲它們全部被回收)。

如何讓Android始終繪製此疊加圖像?我想我需要執行某種緩存或失效,但我只是不知道它是什麼。

public class ViewTest extends ListActivity { 
    // replace the progress drawable with my custom drawable 
    public void setSeekBarOverlay(SeekBar seekBar, String overlayText) { 
     Bitmap bitmap = Bitmap.createBitmap(100, 12, Bitmap.Config.ARGB_4444); 
     new Canvas(bitmap).drawText(overlayText, 10, 12, new Paint()); 

     Drawable d = new BitmapDrawable(bitmap); 
     ((LayerDrawable) seekBar.getProgressDrawable()).setDrawableByLayerId(android.R.id.progress, d); 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     setListAdapter(new ListAdapter() { 

      // return the view. Recycle them if possible. 
      public View getView(int pos, View v, ViewGroup vg) { 
       if (v == null) { 
        v = View.inflate(ViewTest.this, R.layout.seekbar, null); 
       } 

       String s = String.valueOf(pos); 
       ((TextView) v.findViewById(android.R.id.text1)).setText(s); 
       setSeekBarOverlay((SeekBar) v.findViewById(R.id.seekbar), s); 
       return v; 
      } 

      ... cut ... 
     }); 
    } 
} 

main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<ListView 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/list" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"/> 

seekbar.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="wrap_content" 
    android:gravity="center_vertical" 
    android:minHeight="?android:attr/listPreferredItemHeight"> 

    <TextView 
     android:id="@android:id/text1" 
     android:textAppearance="?android:attr/textAppearanceLarge" 
     android:layout_width="0dp" 
     android:layout_weight="1" 
     android:gravity="center" 
     android:layout_height="wrap_content" /> 
    <SeekBar 
     android:id="@+id/seekbar" 
     android:layout_width="0dp" 
     android:layout_weight="1" 
     android:layout_height="wrap_content" /> 
</LinearLayout> 

回答

4

這是一個艱難的一個,我不認爲會得到多少流量,所以我打算自我找到解決方案後自己回答。

另一個SO問題/答案,Android ProgressBar.setProgressDrawable only works once?,讓我有一半在那裏,但解決方案沒有爲我工作。在另一個問題中,代碼試圖取代整個progressDrawable(setProgressDrawable())。我沒有這樣做,因爲我只是更新現有的progressDrawable中的圖層。在玩過一些類似的方法後,我發現了一些可行的方法。你必須得到正在更新的drawable的邊界(在這種情況下是其中的一個圖層),並且稍後設置邊界。

似乎在平臺中的錯誤,但是這種解決方法似乎使它工作。希望這有助於別人。

public void setSeekBarOverlay(SeekBar seekBar, String overlayText) { 
    LayerDrawable layerDrawable = (LayerDrawable) seekBar.getProgressDrawable(); 
    Drawable overlayDrawable = layerDrawable.findDrawableByLayerId(android.R.id.progress); 
    Rect bounds = overlayDrawable.getBounds(); 

    Bitmap bitmap = Bitmap.createBitmap(100, 12, Bitmap.Config.ARGB_4444); 
    new Canvas(bitmap).drawText(overlayText, 10, 12, new Paint()); 
    overlayDrawable = new BitmapDrawable(bitmap); 

    overlayDrawable.setBounds(bounds); 
    layerDrawable.setDrawableByLayerId(android.R.id.progress, overlayDrawable); 
} 
+0

我不認爲你只限於一次,但你應該只需要調用它一次。在你膨脹之後,它已經被設置。 – schwiz 2011-06-14 00:52:10

+0

我正在嘗試做幾乎完全相同的事情(我爲我的ProgressBar設置了不同的顏色條),但它不起作用。它們一開始顯示得很好,但是當我的數據集發生變化並且列表再次繪製其視圖時,可繪製的進度消失。 – Karakuri 2012-07-23 20:46:43

+1

非常感謝你,你的回答對於類似問題的幫助非常大:setDrawableByLayerId(index,BitmapDrawable)在OS <10時不起作用 – VinceFR 2013-05-31 08:33:14

相關問題