【问题标题】:Possibility to add parameters in button xml?可以在按钮 xml 中添加参数吗?
【发布时间】:2011-04-18 18:02:56
【问题描述】:

我目前有一个带有一些按钮的活动。

在我的 xml 中,按钮是这样定义的:

    <ImageButton (...) android:onClick="GoToPageX"/>

我在我的活动中:

public void GotoPageX() {
    startActivity(new Intent(this, PageX.class));
    finish();

}

问题是我有数百个按钮,不想写

<ImageButton (...) android:onClick="GoToPage1"/>
<ImageButton (...) android:onClick="GoToPage2"/>
<ImageButton (...) android:onClick="GoToPage3"/>
...
<ImageButton (...) android:onClick="GoToPage100"/>

以及所有的脚本。

我现在正在使用

public void GotoPage( int i) {
    startActivity(new Intent(getBaseContext(), activities.get(i)));
    finish();
}

并且想从xml中给出参数i,可以吗?

非常感谢您的帮助。

【问题讨论】:

  • 您的 XML 中有数百个按钮?你能准确地解释一下你想要完成的事情吗?肯定有更好的方法。似乎您可以简单地使用带有适配器的 ListView 或 GridView 设置为类似 PageButton 项的数组(例如,包含:int page、int drawableId)。
  • 一个布局中的数百个可能是我的夸张。事实上,我在每个活动中都有 4 个按钮,可以通向不同的页面(就像一本书,但有点不同)OcuS 的答案对我来说是完美的。

标签: android button android-activity


【解决方案1】:

这是不可能的。但是,也许您可​​以使用android:tag 来获取您的参数。

<ImageButton (...) android:onClick="goToPage" android:tag="25"/>

public void goToPage(View v) {
    String pageNumber = v.getTag().toString(); 
    /* ... */
}

【讨论】:

  • String pageNumber = v.getTag().toString();
【解决方案2】:

您也可以通过启用数据绑定并为 onClick 值使用 lambda 表达式来做到这一点。如果您计划使用不同类型的多个输入,这种方式特别有用。这是一个使用此策略的简单 MainActivity.xml 示例。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="main" type="com.example.android.myapp.MainActivity" />
    </data>
    <LinearLayout android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
        <ImageButton (...) android:onClick='@{() -> main.GotoPage(1,"one")}'/>
        <ImageButton (...) android:onClick='@{() -> main.GotoPage(2,"two")}'/>
        <ImageButton (...) android:onClick='@{() -> main.GotoPage(3,"three")}'/>
        ...
        <ImageButton (...) android:onClick='@{() -> main.GotoPage(100,"one hundred")}'/>
    </LinearLayout>
</layout>

MainActivity.java

public void GotoPage(int i, String otherVariable) {
    /** code using i and otherVariable **/
}

更新:对于那些不知道如何设置数据绑定的人,我将在这里解释一下,这样您就不必到处搜索了。首先,在 build.gradle 文件中启用dataBinding

android {
    ...
    dataBinding {
        enabled = true
    }
    ...
}

另外,请确保 jcenter() 在您的存储库中。

然后,转到将使用 onClick 的布局的 XML,并将其布局包装在带有 data 部分的 layout 标记中,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="main" type="com.example.android.yourapp.MainActivity" />
    </data>
    <YourLayout>
        ...
    </YourLayout>
</layout>

对于variable 标签的type 参数,您需要放置将包含onClick 指向的函数的类。在这个例子中,我将使用主活动类,在我的测试项目中命名为MainActivity

如上例所示,将布局包裹在 layout 标记中后,请在 Android Studio 中清理项目。您可能还需要使缓存/重启无效或关闭并重新打开 Android Studio。

接下来,如果您尝试为其设置数据绑定的带有onClick 的布局与您的主活动类中setContentView 设置的布局相同,请打开包含您的主活动类的文件。如果您尝试为其设置数据绑定的 onClick 布局以编程方式在不同的文件中膨胀,请打开其中布局膨胀的文件。

将这些导入添加到该文件中:

import com.example.android.yourapp.databinding.YourLayoutBinding;
import android.databinding.DataBindingUtil;

您要导入的第一个类是在您清理项目时生成的(并且可能必须使缓存/重新启动无效),并以您添加 layout 包装器的 XML 文件自动命名。如果布局文件名为your_layout.xml,则导入类将命名为YourLayoutBinding。确切的导入路径取决于您的应用名称和结构,但它始终位于 databinding 父类中。

下一步取决于您要添加数据绑定的布局是使用setContentView 设置还是使用inflate 扩展。以下步骤的两个版本都使用了方法setMainsetMain 方法是使用我们添加的layout 包装器中的name 参数的值自动生成和命名的。由于我们输入了name="main",因此该方法称为setMain


如果要添加数据绑定的布局与setContentView 设置的布局相同 在主活动类中找到类似于setContentView(R.layout.your_layout); 的行并将其更改为使用DataBindingUtil.setContentView而不是setContentView,添加this 作为它的第一个参数。使用binding.setMain 将布局的main 变量指向当前活动。

YourLayoutBinding binding = DataBindingUtil.setContentView(this, R.layout.your_layout);
binding.setMain(this);

如果您要添加数据绑定的布局不是由setContentView 设置的,而是膨胀的,请转到代码中的膨胀位置。它应该看起来像这样:

return inflater.inflate(R.layout.your_layout, container, false);

修改它以使用DataBindingUtil.inflate,添加之前的inflater 作为它的第一个参数。使用binding.setMain 将布局的main 变量指向主活动,并使用binding.getRoot() 获取视图。最后应该是这样的:

YourLayoutBinding binding = DataBindingUtil.inflate(inflater, R.layout.your_layout, container, false);
binding.setMain((MainActivity) getActivity());
return binding.getRoot();

现在数据绑定可以使用了。为onClick 添加一个函数以指向您的主要活动类。

public void exampleFunction(int number, String text) {
    System.out.println("Number: " + number + ", Text: " + text);
}

您可以使用 lambda 表达式从添加数据绑定的布局中调用它。此示例函数不需要View,因此可以这样使用:

<Button android:id="@+id/buttonID"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="26sp"
    android:text="Test"
    android:onClick='@{() -> main.exampleFunction(123, "test")}'/>

如果您打算使用String 输入,请确保在onClick 的值周围使用单引号。

如果您确实需要将按钮的视图传递给您的函数,只需将View 参数添加到您的函数所需的参数中,并改用如下的 lambda 表达式:

<Button android:id="@+id/buttonID"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="26sp"
    android:text="Test"
    android:onClick='@{(view) -> main.exampleFunction(view, 123, "test")}'/>

【讨论】:

  • DataBinding 很冗长。
【解决方案3】:

如果你要在 xml 中创建一些布局元素,你可以在那里使用

<ImageButton
    android:id="@+id/some_id_value" />

其中some_id_value 是一种独特的字符串,它将被转换为保存在 R.java 中的 id(对你来说更好——不要在那里更改任何东西),而不是在代码中你可以通过使用来获取该 id

R.id.some_id_value

读一点 there 这真的很基础。

【讨论】:

    【解决方案4】:

    您可以为视图设置标签。标签基本上是视图拥有记忆的一种方式。

    xml:

    <ImageButton
        ...Other Parameters...
        android:id="@+id/Button2"
        android:tag="2"
        android:onClick="GoToPageX"/>
    <ImageButton
        ...Other Parameters...
        android:id="@+id/Button3"
        android:tag="3"
        android:onClick="GoToPageX"/>
    

    android:tag="2"这一行将标签值2(字符串数据类型)设置为Button2

    Java 文件:

    一般情况:
    GoToPageX(View v) 函数内部, 使用v.getTag() 获取相应视图的标记值(从哪个视图调用该方法)。

    您的情况:
    添加方法如下

    public void GoToPageX(View v){
        int i = Integer.parseInt(v.getTag()); //parseInt converts string to integer
        startActivity(new Intent(getBaseContext(), activities.get(i)));
        finish();
    }
    

    【讨论】:

      猜你喜欢
      • 2016-05-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 1970-01-01
      • 2022-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多