2016-04-20 62 views
4

我需要創建一個模式設置爲某些觀點的背景下,和我需要的模式是這樣的:Android的 - 可繪製重複形狀創建模式

pattern

我不想要導入任何可繪製的圖像,但是我想創建自己的形狀,圖層列表和最終目標模式作爲背景。

是否可以實現這一點,而不必導入任何外部圖像?

+0

[Android:如何從模式創建背景?](http://stackoverflow.com/questions/1700099/android-how-to-create-a-background-from-pattern) – 0X0nosugar

+0

您建議使用的解決方案和外部圖像。我想創建我現在的矩形,就像一起使用它們來創建一個模式。 – Bugdr0id

+0

另一種解決方案需要一個drawable,我認爲你可以從xml創建你自己的drawable(例如每個圖層可繪製一個小矩形的圖層列表),然後繼續上面提到的解決方案。 IMO更大的問題是重複模式。 – 0X0nosugar

回答

5

通過創建自定義View和覆蓋onDraw(),您可以基於形狀可繪製來獲得重複圖塊的圖案。

首先讓我們來創建作爲瓷磚形狀製成可繪製的圖層列表,在這種情況下,黑白相間的方格:

my_background.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
<item> 
    <layer-list> 
     <item > 
      <shape > 
       <solid android:color="#ffffff"/> 
       <size 
        android:height="8dp" 
        android:width="8dp" 
        /> 
      </shape> 
     </item> 
     <item android:left="4dp" android:top="4dp" android:bottom="0dp" android:right="0dp" > 
      <shape > 
       <solid android:color="#ff000000"/> 
       <size 
        android:height="4dp" 
        android:width="4dp" 
        /> 

      </shape> 
     </item> 
     <item android:left="0dp" android:top="0dp" android:bottom="4dp" android:right="4dp"> 
      <shape> 
       <solid android:color="#ff000000"/> 
       <size 
        android:height="4dp" 
        android:width="4dp" 
        /> 
      </shape> 
     </item> 
    </layer-list> 
</item> 

你需要一個方法drawableToBitmap()來將磁貼轉換成位圖,如here

覆蓋onDraw()

@Override 
protected void onDraw(Canvas canvas) 
{ 
    super.onDraw(canvas); 
    Drawable d = getResources().getDrawable(R.drawable.my_background); 
    if (d != null) 
    { 
     Bitmap b = drawableToBitmap(d); 
     BitmapDrawable bm = new BitmapDrawable(getResources(), b); 
     bm.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 

     bm.setBounds(canvas.getClipBounds()); 
     bm.draw(canvas); 
    } 
} 

取決於View的類型,您可能需要採取額外的步驟。

  • 延長某種Layout,爲了在android:background屬性設置爲任何顏色,以觸發呼叫onDraw()
  • 對於許多View s時,有可能更容易實現自定義View,並在同一時間更好表現將您的自定義View定位在其他View以下(例如,作爲RelativeLayout中的兩個孩子)並使尺寸匹配。
  • 如果您想從ImageView延伸,您需要在背景圖案上繪製可繪製的前景。在這種情況下,您可以修改onDraw()如下:

的onDraw()保留前景繪製:

@Override 
protected void onDraw(Canvas canvas) 
{ 
    super.onDraw(canvas); 

    // preserve foreground drawable if there is one: 
    Drawable fd = getDrawable(); 

    Drawable d = getResources().getDrawable(R.drawable.my_background); 
    if (d != null) 
    { 
     Bitmap b = drawableToBitmap(d); 
     BitmapDrawable bm = new BitmapDrawable(getResources(), b); 
     bm.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 

     bm.setBounds(canvas.getClipBounds()); 
     bm.draw(canvas); 
    } 

    if (fd == null) 
     return; 

    // set bounds as needed 
    fd.setBounds(0, 0, 100, 100); 
    fd.draw(canvas); 
} 

編輯

正如上面提到的,在某些情況下(如TextViewProgressBar)您可能想要使用一種解決方法:

  • 使您的View背景透明。
  • 使用該模式作爲背景創建自定義佈局。
  • View包裝在自定義佈局中(將佈局寬度和高度設置爲wrap_content)。
+0

偉大的答案!還有一個問題。我正在嘗試將此自定義背景設置爲進度條。我無法保留前景,所以我看不到進展,只看到它自身的背景。你能給我一些關於onDraw()方法的提示嗎? – Bugdr0id

+0

我已經創建了一個新問題,與我的問題的下一步有關。請檢查http://stackoverflow.com/questions/36765444/android-progressbar-with-custom-background-foreground – Bugdr0id

+1

@ Bugdr0id - 這是我認爲它實際上更容易使用某些解決方法的情況之一。例如,您可以使用FrameLayout或RelativeLayout(寬度和高度與ProgressBar大小相匹配)的背景圖案,然後將Progressbar(具有透明背景)作爲此佈局的唯一子區域。 – 0X0nosugar

相關問題