2009-08-21 238 views
45

我想在Android中加載位圖,我想瓷磚。我目前使用在我看來,下面顯示位圖:Android瓷磚位圖

canvas.drawBitmap(bitmap, srcRect, destRect, null) 

我基本上是想用這個圖作爲我的應用程序的背景圖像,想重複位圖在X和Y兩個方向。

我已經看到了BitmapShader類的TileMode.REPEAT常量,但我不確定這是用於重複實際位圖還是用於將過濾器應用於位圖。

+0

任何人都知道如何在不使用xml的情況下在java代碼中執行此操作? – endryha 2010-09-28 05:46:00

回答

123

您可以在xml而不是java代碼中執行此操作。我自己並沒有嘗試過,但我確實找到了這個例子。

​​3210

然後在XML稱爲backrepeat.xml

<bitmap xmlns:android="http://schemas.android.com/apk/res/android" 
    android:src="@drawable/back" 
    android:tileMode="repeat" /> 

reference

+2

只是要添加,backrepeat.xml進入「可繪製」文件夾 – 2010-01-10 05:24:58

+2

這不會用於繪製到畫布,雖然... – stealthcopter 2010-04-30 21:12:24

+0

可能是在這裏迂腐,但第一行應該閱讀 - <?xml version =「1.0」 encoding =「utf-8」?> – Neil 2012-10-12 16:09:20

15

上述backrepeat.xml是手推車

<bitmap 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:src="@drawable/tile" 
    android:tileMode="repeat" 
    android:dither="true" /> 
+17

爲什麼它錯誤,這是如何解決它? – 2012-04-29 16:16:22

+0

這一個增加:android:dither =「true」,如果瓦片不能很好地開始,它什麼也不做。 – 2015-04-03 22:14:13

34

想出代碼版本:

BitmapDrawable TileMe = new BitmapDrawable(MyBitmap); 
    TileMe.setTileModeX(Shader.TileMode.REPEAT); 
    TileMe.setTileModeY(Shader.TileMode.REPEAT); 

    ImageView Item = new ImageView(this); 
    Item.setBackgroundDrawable(TileMe); 

然後,如果你有一個可繪製的瓷磚,這可以用來代替使BitmapDrawable:

BitmapDrawable TileMe = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.tile)); 
+0

這很好,但你會如何只重複它垂直?我嘗試刪除setTileModeX,但它甚至根本不工作。 – 2012-07-25 15:05:58

+0

@WilliamL。奇。 [docs](http://developer.android.com/reference/android/graphics/drawable/BitmapDrawable.html#setTileModeX(android.graphics.Shader.TileMode))似乎表示它應該只與其中的一個一起工作。最好的猜測是嘗試['Shader.TileMode.CLAMP'](http://developer.android.com/reference/android/graphics/Shader.TileMode.html),然後看看會發生什麼。 – Izkata 2012-07-25 15:57:17

+0

如果我只水平重複它,但不是垂直只有它可以工作。而CLAMP與之前沒有設置拼貼模式的功能相同。 – 2012-07-25 16:03:48

5

看來,有些人有興趣在視圖中這樣做,在的onDraw方法。下面的代碼爲我工作:

bgTile = BitmapFactory.decodeResource(context.getResources(), R.drawable.bg_tile); 

float left = 0, top = 0; 
float bgTileWidth = bgTile.getWidth(); 
float bgTileHeight = bgTile.getHeight(); 

while (left < screenWidth) { 
    while (top < screenHeight) { 
     canvas.drawBitmap(bgTile, left, top, null); 
     top += bgTileHeight; 
    } 
    left += bgTileWidth; 
    top = 0; 
} 
+0

它將填滿所有區域。最後一個圖塊可能不完整,屏幕右側/底部的空間仍然會被繪製。 – kgiannakakis 2011-06-05 16:26:48

+0

我只是將這段代碼用於我的畫布而不是全部,所以顯然你會得到額外的繪製,然後寬度和高度不能被圖片大小整除。我刪除了我的評論,因爲它與問題無關。抱歉! – stealthcopter 2011-06-05 18:02:50

+0

在這種情況下,您將使用BitmapDrawable.setBounds和BitmapDrawable.draw(Canvas) – tactoth 2012-12-03 05:38:02

4
<xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    android:id="@+id/MainLayout" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" 
    android:background="@drawable/back" 
    android:tileMode="repeat" 
> 

這對我工作的罰款。我不必單獨創建位圖。我在佈局中使用了tileMode屬性。

+0

謝謝,我發現這是最簡單的方法。 – patrickandroid 2014-08-08 01:16:54

0

如果您只想垂直重複背景,則可以將佈局的寬度設置爲「wrap_content」,而如果要將背景設置爲水平重複,請將高度設置爲「wrap_content」。如果高度和寬度均設置爲「fill_parent」,則它將在X和Y方向上平鋪。

例如,下面的代碼會重複你的背景垂直:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="fill_parent" 
    android:background="@drawable/news_detail_activity_bg"> 
</LinearLayout> 
1

只是把此行代碼在OnCreate(): -

final Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.actionbar_bg); 
final BitmapDrawable bitmapDrawable = new BitmapDrawable(bmp); 
bitmapDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 
final ActionBar bar = getSupportActionBar(); 
bar.setBackgroundDrawable(bitmapDrawable); 
0
/* Tiled Layer Bitmap*/ 


public class TiledLayer { 
private int cellWidth; 
private int cellHeight; 
private int yPosition = 0, xPosition = 0; 
private int[][] grid; 
private Image image; 
private int[] tileXPositions; 
private int[] tileYPositions; 
private ArrayList animatedTiles; 
private int numberOfTiles; 
private int numberOfColumns; 
private int numberOfRows; 
private int gridColumns; 
private int gridRows, width, height; 

public TiledLayer(Image image, int columns, int rows, int tileWidth, 
     int tileHeight, int width, int height) { 
    this.grid = new int[columns][rows]; 
    this.gridColumns = columns; 
    this.gridRows = rows; 
    this.width = columns * tileWidth; 
    this.height = rows * tileHeight; 
    this.animatedTiles = new ArrayList(); 
    setStaticTileSet(image, tileWidth, tileHeight); 
    } 

public void setStaticTileSet(Image image, int tileWidth, int tileHeight) { 
    this.image = image; 
    this.cellWidth = tileWidth; 
    this.cellHeight = tileHeight; 
    int columns = 64;//image.getWidth()/tileWidth; 
    int rows =40;// image.getHeight()/tileHeight; 
    this.tileXPositions = new int[columns]; 
    int pos = 0; 
    for (int i = 0; i < columns; i++) { 
     this.tileXPositions[i] = pos; 
     pos += tileWidth; 
    } 
    this.tileYPositions = new int[rows]; 
    pos = 0; 
    for (int i = 0; i < rows; i++) { 
     this.tileYPositions[i] = pos; 
     pos += tileHeight; 
    } 

    if (columns * rows < this.numberOfTiles) { 
     // clear the grid, when there are not as many tiles as in the 
     // previous set: 
     for (int i = 0; i < this.grid.length; i++) { 
      for (int j = 0; j < this.grid[i].length; j++) { 
       this.grid[i][j] = 0; 
      } 
     } 
    } 
    this.numberOfTiles = columns * rows; 
    this.numberOfColumns = columns; 
    this.numberOfRows = rows; 
    } 

    public int createAnimatedTile(int staticTileIndex) { 
    if (staticTileIndex >= this.numberOfTiles) { 

     throw new IllegalArgumentException("invalid static tile index: " 
       + staticTileIndex + " (there are only [" 
       + this.numberOfTiles + "] tiles available."); 

    } 
    this.animatedTiles.add(new Integer(staticTileIndex)); 
    return -1 * (this.animatedTiles.size() - 1); 
} 

public void setAnimatedTile(int animatedTileIndex, int staticTileIndex) { 
    if (staticTileIndex >= this.numberOfTiles) { 

    } 
    int animatedIndex = (-1 * animatedTileIndex) - 1; 
    this.animatedTiles.set(animatedIndex, new Integer(staticTileIndex)); 
    } 

public int getAnimatedTile(int animatedTileIndex) { 
    int animatedIndex = (-1 * animatedTileIndex) - 1; 
    Integer animatedTile = (Integer) this.animatedTiles.get(animatedIndex); 
    return animatedTile.intValue(); 
} 
public void setCell(int col, int row, int tileIndex) { 
    if (tileIndex >= this.numberOfTiles) { 

     throw new IllegalArgumentException("invalid static tile index: " 
       + tileIndex + " (there are only [" + this.numberOfTiles 
       + "] tiles available."); 

    } 
    this.grid[col][row] = tileIndex; 
} 

public int getCell(int col, int row) { 
    return this.grid[col][row]; 
} 

public void fillCells(int col, int row, int numCols, int numRows, 
     int tileIndex) { 
    if (tileIndex >= this.numberOfTiles) { 

     throw new IllegalArgumentException("invalid static tile index: " 
       + tileIndex + " (there are only [" + this.numberOfTiles 
       + "] tiles available."); 

    } 
    int endCols = col + numCols; 
    int endRows = row + numRows; 
    for (int i = col; i < endCols; i++) { 
     for (int j = row; j < endRows; j++) { 
      this.grid[i][j] = tileIndex; 
     } 
    } 
} 

    public final int getCellWidth() { 
    return this.cellWidth; 
} 

    public final int getCellHeight() { 
    return this.cellHeight; 
} 

public final int getColumns() { 
    return this.gridColumns; 
} 

public final int getRows() { 
    return this.gridRows; 
} 

public final void paint(Graphics g) { 
    int clipX = 0;// g.getClipX(); 
    int clipY = 0;// g.getClipY(); 
    int clipWidth = width;// g.getClipWidth(); 
    int clipHeight = height;// g.getClipHeight(); 

    // jmt restore clip to previous state 

    int x = this.xPosition; 
    int y = this.yPosition; 
    int[][] gridTable = this.grid; 
    for (int i = 0; i < this.gridColumns; i++) { 
     int[] gridRow = gridTable[i]; 
     for (int j = 0; j < gridRow.length; j++) { 
      int cellIndex = gridRow[j]; 
      if (cellIndex != 0) { 
       // okay this cell needs to be rendered: 
       int tileIndex; 
       if (cellIndex < 0) { 
        Integer tile = (Integer) this.animatedTiles 
          .get((-1 * cellIndex) - 1); 
        tileIndex = tile.intValue() - 1; 
       } else { 
        tileIndex = cellIndex - 1; 
       } 
       // now draw the tile: 
       g.save(Canvas.CLIP_SAVE_FLAG); 
       // jmt: clear the screen 
       Rect r = new Rect(0, 0, cellWidth, cellHeight); 
       g.clipRect(r); 
       g.setClip(x, y, this.cellWidth, this.cellHeight); 
       int column = tileIndex % this.numberOfColumns; 
       int row = tileIndex/this.numberOfColumns; 
       int tileX = x - this.tileXPositions[column]; 
       int tileY = y - this.tileYPositions[row]; 

       g.drawImage(this.image, tileX, tileY); 
       g.restore(); 
      } 
      y += this.cellHeight; 
     } // for each row 
     y = this.yPosition; 
     x += this.cellWidth; 
    } // for each column 

    // reset original clip: 
    g.setClip(clipX, clipY, clipWidth, clipHeight); 
} 

}