我用C#(xamarin)为Android做过经典的Tic Tac Toe游戏,现在我必须添加一个新的"模态"考虑到玩家的选择,应用程序必须创建一个网格nxn(例如,如果玩家输入是" 5",我必须创建一个网格5x5)。在另一个"模态"在应用程序中,我使用LinearLayout处理网格和Imagebutton数组(对于经典模式,我有3个LinearLayout,每个有3个图像按钮)。现在我如何创建一个n的网格并处理触摸?我试过用" for"但显然图像按钮都在同一行......我不知道如何改变行
LinearLayout row1 = FindViewById<LinearLayout>(Resource.Id.linearLayout1);
int n = 4;
for (int j = 0; j < n; j++)
{
ImageButton button = new ImageButton(this);
button.SetImageResource(Resource.Drawable.Icon);
row1.AddView(button);
}
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="6"
android:background="#c7efb1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="385.0dp"
android:layout_weight="1.4"
android:orientation="horizontal"
android:weightSum="3"
android:id="@+id/mainLayout"
android:minWidth="25px"
android:minHeight="25px" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50.0dp"
android:layout_marginRight="1dp"
android:layout_weight="0.45"
android:background="#fff4f4f4"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:layout_marginTop="0.0dp"
android:paddingTop="10dp"
android:id="@+id/linearLayout4">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="Team O"
android:textAllCaps="true"
android:textColor="#000"
android:textSize="20sp"
android:id="@+id/teamO" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="Team X"
android:textAllCaps="true"
android:textColor="#000"
android:textSize="20sp"
android:layout_marginLeft="72.0dp"
android:id="@+id/teamX" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="52.5dp"
android:layout_marginRight="1dp"
android:layout_weight="0.6"
android:background="#fff4f4f4"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:padding="13dp"
android:id="@+id/linearLayout5">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="0"
android:textAllCaps="true"
android:textColor="#000"
android:textSize="20sp"
android:id="@+id/punteggioO" />
<TextView
android:layout_width="15.0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="0"
android:textAllCaps="true"
android:textColor="#000"
android:textSize="20sp"
android:layout_marginLeft="145dp"
android:id="@+id/punteggioX" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_marginRight="0dp"
android:layout_height="55.0dp"
android:layout_weight="0.7"
android:background="#fff4f4f4"
android:orientation="horizontal"
android:id="@+id/linearLayout6">
<Button
android:text="Restart"
android:layout_width="150dp"
android:layout_height="match_parent"
android:id="@+id/restart"
android:layout_marginLeft="18dp"
android:layout_marginBottom="10dp" />
<Button
android:text="Reset"
android:layout_width="150dp"
android:layout_height="match_parent"
android:id="@+id/reset"
android:layout_marginLeft="25dp"
android:layout_marginBottom="10dp" />
</LinearLayout>
</LinearLayout>
答案 0 :(得分:0)
我会为每个按钮分配一个Tag
,告诉您他们属于哪个行/列,然后将所有按钮的Click
event
分配给同一个事件,其中然后你找出Tag
以查看点击了哪一个。
在您的情况下,我可能还会动态生成行的布局,因为您可以有N行和N列。
在以下代码中,屏幕截图中的绿色区域为root
。
创建按钮方法
首先,我定义了一个CreateButton
方法,该方法会创建row
,column
中的每个按钮,根据您的喜好对其进行修改,以便它们看起来如您所愿:
Button CreateButton(int row, int column)
{
var text = $"{row},{column}";
var button = new Button(this)
{
Tag = new Java.Lang.String(text),
Text = text,
LayoutParameters = new LinearLayout.LayoutParams(0,
ViewGroup.LayoutParams.MatchParent)
{ Weight = 1 }
};
button.Click += ButtonClicked;
return button;
}
这里需要注意的重要一点是,由于我使用LinearLayout
作为行布局,并且我希望按钮大小相等,我使用Weight
等于1.这也是为什么布局参数中Width
设置为0。
另一个重要的事情是我分配了Tag
。因为它期望Java.Lang.Object
我使用Java.Lang.String
包裹。
创建行方法
LinearLayout CreateRowLayout()
{
var row = new LinearLayout(this)
{
Orientation = Orientation.Horizontal,
LayoutParameters = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MatchParent,
ViewGroup.LayoutParams.WrapContent)
{ Weight = 1 }
};
return row;
}
非常简单LinearLayout
,再次将Weight
设置为1,使所有行都相等。
创建行和列方法
现在,我们可以通过创建n
行和n
列来填充视图。
IEnumerable<LinearLayout> CreateLayouts(int n)
{
var rows = new List<LinearLayout>();
for (var row = 0; row < n; row++)
{
var rowLayout = CreateRowLayout();
for (var column = 0; column < n; column++)
rowLayout.AddView(CreateButton(row, column));
rows.Add(rowLayout);
}
return rows;
}
这很简单,对于每一行,创建n
按钮。以列表形式返回。
将我们的行/列添加到视图
正如我上面提到的,在这种情况下,root
可能来自您的AXML
文件。调整以使其适合您的代码。
var root = new LinearLayout(this)
{
LayoutParameters = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent),
Orientation = Orientation.Vertical
};
var children = CreateLayouts(4);
foreach (var child in children)
root.AddView(child);
唯一重要的是LinearLayout
root
的方向设置为Vertical
,因此行向下流动。
点击按钮
现在让我们点击按钮点击!这里发生了一些演员,因为我将行/列转换为Java.Lang.String
以将其分配给Tag
。虽然不是很多巫术,只是咕噜咕噜的工作。
void ButtonClicked(object sender, EventArgs e)
{
var button = sender as Button;
if (button == null) return;
var tag = button.Tag.JavaCast<Java.Lang.String>();
var tagString = tag.ToString();
var tagParts = tagString.Split(',');
var row = tagParts[0];
var column = tagParts[1];
Toast.MakeText(this, $"{row},{column}", ToastLength.Short).Show();
// do something based on row/column
}
就是这样!我们现在有一个看起来像这样的布局:
按下每个按钮将显示Toast,但会根据您的喜好进行调整。
修改强>
将mainLayout的LinearLayout
更改为:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="385.0dp"
android:layout_weight="1.4"
android:orientation="vertical"
android:weightSum="3"
android:id="@+id/mainLayout"
android:minWidth="25px"
android:minHeight="25px" />
然后在您OnCreate
中的Activity
或方法或OnCreateView
Fragment
中,取决于您使用的内容:
var root = FindViewById<LinearLayout>(Resource.Id.mainLayout);
然后只需添加代码即可生成按钮:
var children = CreateLayouts(4);
foreach (var child in children)
root.AddView(child);