I currently have an activity with some buttons.
In my xml, buttons are defined like this:
<ImageButton (...) android:onClick="GoToPageX"/>
and I have in my activity:
public void GotoPageX() {
startActivity(new Intent(this, PageX.class));
finish();
}
The problem is that I have hundreds of buttons and do not want to write
<ImageButton (...) android:onClick="GoToPage1"/>
<ImageButton (...) android:onClick="GoToPage2"/>
<ImageButton (...) android:onClick="GoToPage3"/>
...
<ImageButton (...) android:onClick="GoToPage100"/>
and all the scripts.
I am now using
public void GotoPage( int i) {
startActivity(new Intent(getBaseContext(), activities.get(i)));
finish();
}
and would like to give the parameter i from the xml, is that possible?
Thank a lot for any help.
It is not directly possible. However, maybe you could use android:tag
to get your parameter.
<ImageButton (...) android:onClick="goToPage" android:tag="25"/>
public void goToPage(View v) {
String pageNumber = v.getTag().toString();
/* ... */
}
You could also do this by enabling data binding and using a lambda expression for the onClick
value. This way is especially useful if you plan to use multiple inputs of different types. Here's an example of a simple MainActivity.xml in which this strategy is used.
<?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>
and in MainActivity.java
public void GotoPage(int i, String otherVariable) {
/** code using i and otherVariable **/
}
UPDATE: For those who don't know how to set up data binding, I will explain it here so you don't have to google around for it. First, enable dataBinding
in the build.gradle file:
android {
...
dataBinding {
enabled = true
}
...
}
Also, make sure jcenter()
is in your repositories.
Then, go to the XML of the layout where onClick
will be used and wrap its layout in a layout
tag with a data
section like this:
<?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>
For the variable
tag's type
parameter, you need to put the class that will contain the function which onClick
points to. In this example, I will use the main activity class, which is named MainActivity
in my test project.
After you have your layout wrapped in a layout
tag like in the example above, clean the project in Android Studio. You may also need to invalidate cache/restart or close and reopen Android Studio.
Next, if the the layout with onClick
you are trying to set up data binding for is the same layout set by setContentView
in your main activity class, open the file that contains your main activity class. If the layout with onClick
you are trying to set up data binding for is inflated programmatically in a different file, open the file in which the layout is inflated instead.
Add these imports to that file:
import com.example.android.yourapp.databinding.YourLayoutBinding;
import android.databinding.DataBindingUtil;
That first class you are importing is generated when you clean the project (and possibly have to invalidate cache/restart) and is automatically named after the XML file you added the layout
wrapper to. If the layout file is named your_layout.xml, the import class will be named YourLayoutBinding
. The exact import path will depend on your app name and structure, but it will always be within a databinding
parent class.
The next step depends on whether the layout you are adding data binding to is set with setContentView
or is inflated with inflate
. Both versions of the following step make use of the method setMain
. The setMain
method is automatically generated and named using the value of the name
parameter in the layout
wrapper we added. Since we put name="main"
, the method is called setMain
.
If the layout you are adding data binding to is the same layout set by setContentView
find the line in your main activity class that looks like setContentView(R.layout.your_layout);
and change it to use DataBindingUtil.setContentView
instead of setContentView
, adding this
as its first argument. Use binding.setMain
to point the layout's main
variable to the current activity.
YourLayoutBinding binding = DataBindingUtil.setContentView(this, R.layout.your_layout);
binding.setMain(this);
If the layout you are adding data binding to is not set by setContentView
but rather inflated go to where it is inflated in your code. It should look something like this:
return inflater.inflate(R.layout.your_layout, container, false);
Modify it to use DataBindingUtil.inflate
, adding the previous inflater as its first argument. Use binding.setMain
to point the layout's main
variable to the main activity, and use binding.getRoot()
to get the view. It should end up like this:
YourLayoutBinding binding = DataBindingUtil.inflate(inflater, R.layout.your_layout, container, false);
binding.setMain((MainActivity) getActivity());
return binding.getRoot();
Now the data binding is ready to use. Add a function for onClick
to point to within your main activity class.
public void exampleFunction(int number, String text) {
System.out.println("Number: " + number + ", Text: " + text);
}
You can call it from the layout you added data binding to using a lambda expression. This example function doesn't require a View
, so it can be used like this:
<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")}'/>
Make sure to use single quotes around the value for onClick
if you plan on using a String
input.
If you do need to pass the button's view to your function, simply add a View
parameter to your function's required arguments and use a lambda expression like this instead:
<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")}'/>
If you will create some layout element in xml you can use there
<ImageButton
android:id="@+id/some_id_value" />
where some_id_value
is kind of unique string which will be translate into id which is kept in R.java (better for you- don't change anything there) than in code you can get that id by using
R.id.some_id_value
read a little bit there that's really basics.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With