动态创建图像按钮 C#

Create Imagebutton Dynamically C#

我已经用 C# (xamarin) 为 Android 完成了经典的 Tic Tac Toe 游戏,现在我必须添加一个新的 "modality" 考虑到玩家的选择,应用程序必须创建一个 nxn 网格(例如,如果玩家输入是“5”,我必须创建一个 5x5 的网格)。在应用程序的另一个 "modality" 中,我使用 LinearLayout 和一个 Imagebutton 数组处理网格(对于经典模式,我有 3 个 LinearLayout,每个 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>

我会为每个按钮分配一个 Tag,告诉您它们属于哪个 Row/Column,然后将所有按钮的 Click event 分配给同一事件,然后您可以在其中找出 Tag 以查看点击了哪一个。

在你的情况下,我可能还会动态生成行的布局,因为你可以有 N 行和 N 列。

在以下代码中,屏幕截图中的绿色区域将是 root

创建按钮方法

首先我定义了一个 CreateButton 方法,它从 rowcolumn 创建每个按钮,根据您的喜好修改它,使它们看起来像您想要的:

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 个按钮。 Return 作为列表。

添加到我们的rows/columns视图中

正如我上面提到的,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);

此处唯一重要的是 rootLinearLayout 方向设置为 Vertical,因此行向下流动。

响应按钮点击

现在让我们找出 Button click!这里发生了一些转换,因为我将 row/column 转换为 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" />

然后在您的 OnCreateActivity 中的方法或 Fragment 中的 OnCreateView 取决于您使用的是什么 添加:

var root = FindViewById<LinearLayout>(Resource.Id.mainLayout);

然后只需添加代码即可在之后生成按钮:

var children = CreateLayouts(4);
foreach (var child in children)
    root.AddView(child);