Android瓷砖位图
我正在尝试在Android中加载我想要平铺的位图。 我目前在我的视图中使用以下来显示一个位图:
canvas.drawBitmap(bitmap, srcRect, destRect, null)
我基本上想要在我的应用程序中使用此位图作为背景图像,并希望在X和Y方向上重复位图。
我已经看到了BitmapShader类的TileMode.REPEAT常量,但是我不确定这是否与重复他的实际位图有关,或者是否需要对位图应用filter。
你会在xml而不是java代码中做到这一点。 我自己并没有尝试过,但是我find了这个例子。
<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/backrepeat" >
然后在一个叫做backrepeat.xml的xml中
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/back" android:tileMode="repeat" />
参考
想出了代码版本:
BitmapDrawable TileMe = new BitmapDrawable(MyBitmap); TileMe.setTileModeX(Shader.TileMode.REPEAT); TileMe.setTileModeY(Shader.TileMode.REPEAT); ImageView Item = new ImageView(this); Item.setBackgroundDrawable(TileMe);
那么如果你有一个可绘制的tile,可以使用这个来创buildBitmapDrawable:
BitmapDrawable TileMe = new BitmapDrawable(BitmapFactory.decodeResource(getResources(), R.drawable.tile));
上面的backrepeat.xml是越野车
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/tile" android:tileMode="repeat" android:dither="true" />
看来有些人有兴趣在onDraw方法中使用View。 以下代码已经为我工作:
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; }
<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" >
这对我来说工作得很好。 我不必单独创build位图。 我在布局中使用了tileMode属性。
只要把这一行代码放在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);
如果只想垂直重复背景,则可以将布局的宽度设置为“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>
/* 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); }
}