多个 Android Drawable shape 组合画田字格

Android Drawable Shape 组合画田字格

我们常用Android Drawable Shape来创建Android的背景、圆角边框、分隔线等图形。这样的教程网上有许多。象下面的

我也常在项目中使用。但最近想做一个田字格背景,用上面的方法就不行了。


以前我对Android Drawable shape的了解并不深入,经过在网上不断寻找,最后找到了个较全面的文档

看过这个文档后,对Android Drawable shape的理解较透了。原来Android Drawable shape不仅可以画简单图形,还可以做动画,还可以加入图片,当然还有我需要的功能,多个Shape组合,构建较复杂的图形。


使用layer-list组合多个Shap

话不多说,把我弄的代码贴出来

<?xml version="1.0" encoding="utf-8"?>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <size
                android:width="96dp"
                android:height="96dp"></size>
            <stroke
                android:width="1dp"
                android:color="#FF0000" />
        </shape>
    </item>
    
    <item>
        <rotate
            android:fromDegrees="90"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="90">
            <shape android:shape="line">
                <stroke
                    android:width="1dp"
                    android:color="#FF0000"
                    android:dashGap="3dp"
                    android:dashWidth="1dp" />
            </shape>
        </rotate>
    </item>
    
    <item>
        <shape android:shape="line">
            <stroke
                android:width="1dp"
                android:color="#FF0000"
                android:dashGap="3dp"
                android:dashWidth="1dp" />
        </shape>
    </item>
</layer-list>
画出的田字格图形如下
多个shape组合画田字格

上面的代码也很简单,使用了一个标签layer-list,中间套着多个item,每个item中加一个shape。

上面的代码还有两点需要说一下:

1、必须设置宽高,不然竖线只能画和宽度一样长。

2、画竖线的方法就是横线加旋转。那个旋转的设置还是比较麻烦的。旋转的代码如下

<rotate
            android:fromDegrees="90"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="90">
            <shape android:shape="line">
                <stroke
                    android:width="1dp"
                    android:color="#FF0000"
                    android:dashGap="3dp"
                    android:dashWidth="1dp" />
            </shape>
        </rotate>

下面介绍一下那四个属性

android:fromDegrees="90"  开始的角度
android:toDegrees="90"      结束的角度

开始和结束都是90度,就竖起来了

android:pivotX="50%"   旋转中心点X座标,可以使用百分比设置
android:pivotY="50%"   旋转中心点Y座标,可以使用百分比设置
都设成50%就是在中心旋转。


关于 Android Drawable shape 的更从介绍可以看文档:Android Drawable XML Documentation

要生成四个田字格,可以使用Android Studio进行开发,具体实现方式如下: ```java //Java代码 public class MainActivity extends AppCompatActivity { private int[][] block = new int[4][4]; //定义一个4*4的数组,用于存储方块 private int[][][] blocks = new int[][][]{ //定义七种不同的方块 { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 1, 1, 0}, {0, 1, 1, 0} }, { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 1, 1} }, { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 1, 1, 1}, {0, 0, 0, 1} }, { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 1, 1, 1}, {0, 1, 0, 0} }, { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 1, 1, 1}, {0, 0, 1, 0} }, { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1} }, { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 1, 1}, {0, 1, 1, 0} } }; private int currentBlock = 0; //当前方块的编号 private int currentX = 0; //当前方块的横坐标 private int currentY = 0; //当前方块的纵坐标 private int score = 0; //得分 private boolean isOver = false; //游戏是否结束 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initBlock(); //初始化方块 new Thread(new Runnable() { //开启一个新线程,用于控制方块的下落 @Override public void run() { while (!isOver) { //游戏未结束时不断循环 try { Thread.sleep(1000); //每隔1秒钟方块下落一格 } catch (InterruptedException e) { e.printStackTrace(); } if (canMoveDown()) { //如果方块可以向下移动 currentY++; //纵坐标加1 } else { //否则 mergeBlock(); //将方块合并到底部的方块中 checkFullLine(); //检查是否有满行 newBlock(); //生成新的方块 if (!canMoveDown()) { //如果新的方块无法向下移动 isOver = true; //游戏结束 } } runOnUiThread(new Runnable() { //在UI线程中更新界面 @Override public void run() { updateUI(); //更新界面 } }); } } }).start(); } private void initBlock() { //初始化方块 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { block[i][j] = 0; //将方块数组中的所有元素都设为0 } } } private void newBlock() { //生成新的方块 currentBlock = (int) (Math.random() * 7); //随机生成一个方块编号 currentX = 3; //将横坐标设为3 currentY = 0; //将纵坐标设为0 if (!canMoveDown()) { //如果新的方块无法向下移动 isOver = true; //游戏结束 } } private boolean canMoveDown() { //判断方块是否可以向下移动 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (blocks[currentBlock][i][j] != 0) { //如果方块的这个位置有方块 if (currentY + i == 19) { //如果方块已经到达底部 return false; //返回false } if (block[currentY + i + 1][currentX + j] != 0) { //如果方块下面已经有方块 return false; //返回false } } } } return true; //否则返回true } private void mergeBlock() { //将方块合并到底部的方块中 for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { if (blocks[currentBlock][i][j] != 0) { //如果方块的这个位置有方块 block[currentY + i][currentX + j] = currentBlock + 1; //将方块的颜色值赋给底部的方块 } } } } private void checkFullLine() { //检查是否有满行 for (int i = 19; i >= 0; i--) { //从下往上遍历每一行 boolean isFull = true; //假设这一行是满行 for (int j = 0; j < 10; j++) { //遍历这一行的每一个方块 if (block[i][j] == 0) { //如果这个方块为空 isFull = false; //这一行不是满行 break; //跳出循环 } } if (isFull) { //如果这一行是满行 score += 10; //得分加10分 for (int k = i; k > 0; k--) { //将这一行上面的所有行都向下移动一行 for (int j = 0; j < 10; j++) { block[k][j] = block[k - 1][j]; } } i++; //重新检查这一行 } } } private void updateUI() { //更新界面 TextView tvScore = findViewById(R.id.tv_score); //得分文本框 tvScore.setText("得分:" + score); //显示得分 GridLayout glBlock = findViewById(R.id.gl_block); //方块布局 glBlock.removeAllViews(); //清空方块布局 for (int i = 0; i < 20; i++) { //遍历每一行 for (int j = 0; j < 10; j++) { //遍历每一列 ImageView ivBlock = new ImageView(this); //创建一个ImageView ivBlock.setLayoutParams(new GridLayout.LayoutParams()); //设置布局参数 ivBlock.setScaleType(ImageView.ScaleType.CENTER_INSIDE); //设置缩放类型 ivBlock.setPadding(2, 2, 2, 2); //设置内边距 switch (block[i][j]) { //根据方块的颜色值设置不同的图片 case 0: ivBlock.setImageResource(R.drawable.block_empty); break; case 1: ivBlock.setImageResource(R.drawable.block_blue); break; case 2: ivBlock.setImageResource(R.drawable.block_cyan); break; case 3: ivBlock.setImageResource(R.drawable.block_green); break; case 4: ivBlock.setImageResource(R.drawable.block_magenta); break; case 5: ivBlock.setImageResource(R.drawable.block_orange); break; case 6: ivBlock.setImageResource(R.drawable.block_red); break; case 7: ivBlock.setImageResource(R.drawable.block_yellow); break; } glBlock.addView(ivBlock); //将ImageView添加到方块布局中 } } } } ``` 在布局文件中添加一个GridLayout,用于显示方块: ```xml <!--XML代码--> <GridLayout android:id="@+id/gl_block" android:layout_width="match_parent" android:layout_height="match_parent" android:columnCount="10" android:rowCount="20" android:background="#000000" android:layout_margin="10dp" android:padding="2dp" android:layout_centerInParent="true"> </GridLayout> ``` 然后在MainActivity中初始化方块数组、生成新的方块、开启一个新线程用于控制方块的下落、判断方块是否可以向下移动、将方块合并到底部的方块中、检查是否有满行、更新界面等操作。最后在updateUI()方法中根据方块的颜色值设置不同的图片,并将ImageView添加到方块布局中。运行程序即可生成四个田字格
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值