看了几个网上的数独的游戏,感觉设计上,总是比较麻烦。特别一些是通过绘图函数来实现数独的,对新手来说不太友好。于是乎想到了用GridLayout去实现一个简单的数独。
本文涉及的内容
一个基本的数独包含了数独界面设计,题目的生成,数独的填入,结果的判断
这里只涉及数独界面的设计和数独的填入。
主要代码
布局设计
利用动态生成9x9的textView,插入到GridLayout控件里面。这里控件要设置为水平优先,即插入的控件首先在水平方向上逐个分布,直到超出最大列数。这两个按钮的功能这里没有去实现,可以忽略。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<GridLayout
android:id="@+id/gl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"></GridLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:text="检查结果" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:text="自动完成" />
</LinearLayout>
</LinearLayout>
代码逻辑
onCreate事件里面生成TextView数组tile,并设置上下文菜单。这个菜单是通过长按textview控件会自动跳出的。内置一个int[][] suduku数组,作为数独的题目。0表示空格,程序只在这些位置上设置相应textview的上下文菜单。最后,利用setLayoutParams去实现数独格子之间的间隔,还要注意宫格之间的间隔要宽一些,具体参考下面的代码
实现代码
public class MainActivity extends AppCompatActivity {
private GridLayout mGl;
private TextView[][] tile = new TextView[9][9];
private TextView mCurrTextView = null;
private final String[] TxtMenu = {" ", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
//内置的数独题目
private int[][] suduku = {{0, 1, 5, 2, 6, 8, 7, 9, 3},
{3, 2, 9, 7, 4, 1, 5, 6, 8},
{6, 7, 8, 3, 5, 9, 2, 1, 4},
{0, 3, 2, 5, 7, 4, 1, 8, 6},
{8, 5, 4, 9, 1, 6, 3, 7, 2},
{1, 6, 7, 8, 3, 2, 4, 5, 9},
{5, 8, 3, 6, 2, 0, 0, 4, 1},
{2, 9, 1, 4, 0, 5, 6, 3, 7},
{7, 4, 6, 1, 9, 3, 8, 2, 5}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGl = (GridLayout) findViewById(R.id.gl);
mGl.setColumnCount(9);
mGl.setRowCount(9);
mGl.setBackgroundColor(Color.BLUE);
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
tile[i][j] = new TextView(this);
tile[i][j].setText(TxtMenu[suduku[i][j]]);//txt[(9*i+j)%10]
tile[i][j].setTag(9 * i + j);
if (suduku[i][j] == 0) {
tile[i][j].setTextColor(Color.BLUE);
registerForContextMenu(tile[i][j]);
}
GridLayout.LayoutParams para = new GridLayout.LayoutParams();
para.width = 118;
para.height = para.width;
para.setMargins(1, 1, 1, 1);
if (i % 3 == 2 && j % 3 == 2) {
para.setMargins(1, 1, 8, 8);
}
tile[i][j].setLayoutParams(para);
tile[i][j].setGravity(Gravity.CENTER);
tile[i][j].setBackgroundColor(Color.WHITE);
tile[i][j].setTextSize(36);
tile[i][j].setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
mGl.addView(tile[i][j]);
}
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater menuInflater = new MenuInflater(this);
int col = (int) (v.getTag()) % 9;
int row = (int) (v.getTag()) / 9;
mCurrTextView = tile[row][col];
for (int i = 0; i < TxtMenu.length; i++) {
menu.add(TxtMenu[i] == " " ? "X" : TxtMenu[i]);
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
//Log.i("onContextItemSelected",item.getTitle().toString());
String str = item.getTitle().toString();
mCurrTextView.setText(str == "X" ? " " : str);
int tag = (int) mCurrTextView.getTag();
int row = tag / 9;
int col = tag % 9;
suduku[row][col] = str == "X" ? 0 : Integer.parseInt(str);
return super.onContextItemSelected(item);
}
}
实现效果
总结
这是一个极简单的数独设计,代码非常少。不过,代码不是按照面向对象的思路设计的,所以要复用比较麻烦。既然求简,那就这样吧