My button sends a parameter to the function.
<Button
android:id="#+id/tela1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Chinese Day"
android:onClick="loadPage"
android:tag="page1"
/>
My function should use this parameter to load the page1 activity.
public void loadPage(View view) {
String page = (String) view.getTag();
setContentView(R.layout.page);
}
How to make this work?
Tks
You want to specify in the button's tag the name of the layout, right?
Try the following:
String page = (String) view.getTag();
int layoutId= getResources().getIdentifier(page, "layout", getPackageName());
setContentView(layoutId);
Hope this helps.
You could use Java reflection API.
Each activity is an integer in R.layout. You only need to search for the attribute inside R.layout and then get its integer value to shove into setContentView.
try {
String tag = (String) btn.getTag(); // Button in variable "btn"
Class<R.layout> cls = R.layout.class;
Field field = cls.getDeclaredField(tag);
Integer obj = (Integer) field.get(null); // You could do these two in one line
int value = obj.intValue();
Log.i("Test", "Actvity id code = " + obj.toString()); // Testing code
setContentView(value);
}
catch (Exception e) {
e.printStackTrace();
return;
}
Related
I want to call a specific EditText which is named after my matrice location, I mean, building the id for EditText with a string and setting it afterwards.
now I need to set the editText01 text in the layout, normally I would set like this:
EditText et = (EditText) findViewById(R.id.editText01);
editText01.setText("WHATEVER I NEED");
BUT, I can't access by the id name because I have to access a specific one, based on the row, column so it needs to be something like:
String row = "0"; // row index converted to string, for example
String column = "1"; // column index converted to string, for example
String string = "editText" + row + column; // string should be editText01
string.setText("WHATEVER I NEED"); //WRONG LINE
Solution 1:
In your case, you can check the R.java class and get the id of editText.
But I recommend solution 2 to avoid use reflection in your code.
Here is the code of using reflection.
private int findIdByName(String nameOfId) {
try {
Class IdFolder = Class.forName(context.getPackageName()+".R$id");
Field field = IdFolder.getField(nameOfId);
return (int) field.get(null);
} catch (ClassNotFoundException e) {
Log.e(TAG, "can not find R.java class");
e.printStackTrace();
} catch (NoSuchFieldException e) {
Log.e(TAG, "the field of resource not defined");
e.printStackTrace();
} catch (IllegalAccessException e) {
Log.e(TAG, "can not get static field in R");
e.printStackTrace();
} catch (ClassCastException e) {
Log.e(TAG, "the value of field is not integer");
e.printStackTrace();
}
return 0;
}
String idName = "editText" + row + column; // string should be editText01
int id = findIdByName(idName);
if (id != 0)
EditText editText01 = findViewById(id);
Solution 2:
You must create EditText in for and set an id for each one. Then put each EditText into an array list.
So every time that you want access to an EditText you have all object in the array list. for more understanding what I said see below:
List<EditText> list = new ArrayList();
for (int i=0; i<100; i++) {
EditText editText = new EditText(context);
editText.setId("editText" + row + column);
list.add(editText);
}
and when you want an EditText you can call this method:
private EditText findEditText(String id) {
for (EditText editText: list)
if (editText.getId().equals(id)
return editText;
return null;
}
also don't forget to add each EditText in the view. For example you can put a LinearLayout in your layout and after create each EditText add that into LinearLayout. something like this put in the for:
LinearLayout linear = findViewById(R.id.linear);
for (int i=0; i<100; i++) {
//...
linear.addView(editText)
/...
}
If you do not understand what I said, feel free to put the comment and ask questions.
to create id using String to call specific edit text use this code
String viewID="editText" + row + column; // string should be editText01
//id for view
int resID= getResources().getIdentifier(viewID,"id", getPackageName());
EditText edit= (EditText) findViewById(resID);
edit.setText("WHATEVER I NEED");
In this code create Edittext id using string
You should set the tags for all edit text like
EditText et = new EditText(this);
et.setTag(<some tag >);
then make use to findViewByTag API to retrieve the edit text
EditText et = (EditText)findViewByTag(<tag name>);
You can use getIdentifier():
int id = context.getResources().getIdentifier("editText" + row + column, "id", context.getPackageName());
EditText et = (EditText) findViewById(id);
et.setText("WHATEVER I NEED");
You can omit context inside an activity class.
I have 50 styled buttons with identificators like "level_i", I need to enable button with certain i in id.
I have code to work with indexed aarays in string xml, but I have no proper ideas how to change it for my usage
Class<R.id.array> res;
Field field;
try {
res = R.array.class;
field = res.getField("words_" + fname);
//set myString to the string resource myArray[fname,y]
myString = getResources().obtainTypedArray(field.getInt(null)).getString(y);
}
catch (Exception e) {
e.printStackTrace();
}
I believe you are saying that you have an ID resource named "words_" + fname for example R.id.words_100. If that is correct, then you can first get the ID using the name of the resource with getIdentifier. Then you can get the actual ID, then you can find the view with that ID:
String resName = "words_" + fname";
Resources res = getResources();
int resId = res.getIdentifier(resName, "id", getPackageName());
View button = findViewById(resId);
EDIT:
Modified original answer to fetch resources from R.id rather than R.string-array.
Searched and working on this a long while - no luck. ( It must be simple ? Thanks for the assist. )
Trying to get / set a screen full of EditTexts' text, but not with the usual, more hard-coded way:
... findViewById (R.id.SomeTextWidgetId) ;
Instead, I'm trying to figure out a reusable way via a variable holding the (String) name_of_widget.
In psuedo code:
findViewById (R.id.>> StringVarHere << ); // how to do that ?
I tried also this findViewById method, but it didn't work (!?)
//// given:
static final String FIELD_TV_FEE = "TextViewFee" ;
static final String FIELD_TV_FOO = "TextViewFoo" ;
static final String FIELD_TV_FUM = "TextViewFum" ;
//// and some arbitrary number more of similar fields
static final String [] ALL_FIELDS = {
FIELD_TV_FEE ,
FIELD_TV_FOO ,
FIELD_TV_FUM // ...
} ;
//// ...
//// this part works
int ResourceID;
String stringVarHere = FIELD_TV_FEE;
//// outputs a correct id, say '0x7f05000f' as in R.id.xxx below
ResourceID = context
.getResources()
.getIdentifier ( stringVarHere,
"id",
context
.getApplicationInfo()
.packageName
) ;
Log.d ("MyClass" , "RESID = " + Integer.toHexString(ResourceID) ) ;
/*
* that's where I'm stuck ^^^ ... how do I do:
*/
String field_name ;
for ( field_name : ALL_FIELDS ) {
(EditText) SomethingLike_a_findViewById(field_name).setText ("Hello Wurld") ;
}
I've tried .setId ...
//// details
<!-- excerpt from working xml layout -->
<EditText
android:id="#+id/TextViewFee"
android:inputType="text"
android:layout ... etc ...
/>
<EditText
android:id="#+id/TextViewFoo"
android:inputType="text"
android:layout ... etc ...
/>
<EditText
android:id="#+id/TextViewFum"
android:inputType="text"
android:layout ... etc ...
/>
As expected, the gen'ed R file has something like this:
// ...
public static final class id {
public static final int TextViewFee=0x7f05000f;
public static final int TextViewFum=0x7f05001c;
public static final int TextViewFoo=0x7f05001d;
// ... etc
Yes, thanks - it makes sense to do it in the activity. I was trying to keep it from getting too code bulky. Here's what I'm doing now, based on your and A-C's helpful suggestions. The intention is to get all the text of fields of a form back in one String[]. (I know I could brute force all the fields too.)
What do you all think about this below - seems very similar to your suggestion, madlymad ? I am wondering if this is a poor design approach ?
public class FoodBar {
private Activity activity;
private Context ctx;
public FoodBar ( Activity _activity ) {
this.activity = _activity;
this.ctx = this.activity.getApplicationContext() ;
}
public String[] getTextFromAllEditTexts () { // the UI views
int res_id = 0;
int i = 0;
String [] retValues = new String [MyClassName.ALL_FIELDS_LENGTH] ;
for (String field : MyClassName.ALL_FIELDS_ALL_VEHICLES) {
res_id = this.ctx.getResources()
.getIdentifier ( field, "id", this.ctx.getPackageName() );
((EditText) this.activity
.findViewById (res_id))
.setText( "Meat and Potatoes" ) ;
// redundant - get it right back to make sure it really went in !
retVal[i++] = ((EditText) this.activity
.findViewById (res_id))
.getText().toString() ;
}
return retVal;
} // end func
} // end class
Then from the Activity class, it's just:
String [] theFields = null;
FoodBar = new FoodBar (this);
try {
theFields = FoodBar.getTextFromAllEditTexts ();
} catch (Exception e) {
Log.d ("OOPS", "There's a big mess in the Foodbar: " + e.toString() );
}
The way you could do it is (as I understand the way you are trying):
This can be in non-Activity (YourClassname.java):
public static int getMyId(Context context, String field) {
return context.getResources().getIdentifier (field, "id", context.getPackageName());
}
in Activity-class:
for ( String field_name : YourClassname.ALL_FIELDS ) {
int resid = YourClassname.getMyId(context, field_name);
if(resid != 0) { // 0 = not found
EditText et = (EditText) findViewById(resid);
if (et != null) {
et .setText ("Hello Wurld") ;
}
}
}
But I think it's better to code in the activity class like:
String packageName = getPackageName();
Resources res = getResources();
for ( String field_name : YourClassname.ALL_FIELDS ) {
int resid = res.getIdentifier (field_name, "id", packageName);
if(resid != 0) {// 0 = not found
EditText et = (EditText) findViewById(resid);
if (et != null) {
et .setText ("Hello Wurld") ;
}
}
}
A-C suggested something along the lines of:
res_id = getResources().getIdentifier (field, "id", getPackageName());
((EditText)findViewById (res_id)).setText("NoLongerFubar");
this DOES work - when I tried it standalone in a test rig. Thanks ! Still not sure what was blowing up, but I suspect it was Context or Resource items not being accessible.
Note that variable names (such as R.id.some_id) are only available at compile time and cannot be accessed from a String value at run time. Since these ids are declared as ints, you might consider using an int[] or List<Integer> to store the ids. Depending on how dynamic your layout is and what you are doing with the Views in it, you might even want to simply create the Views at run time and store an array or List of them without using any ids at all.
I am wondering how to convert an EditText input to an int, I have the user input a number, which then divides it by 8.
MainActivity.java:
#SuppressWarnings("unused")
public void calcSpeed(View view)
{
setContentView(R.layout.activity_speed);
final TextView mTextView = (TextView) findViewById(R.id.textView3);
mTextView.setText("You should be getting: " +netSpedCalcd);
}
activity_main.xml:
<EditText
android:id="#+id/editText1"
android:inputType="number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="62dp"
android:ems="10" >
you have to used.
String value= et.getText().toString();
int finalValue=Integer.parseInt(value);
if you have only allow enter number then set EditText property.
android:inputType="number"
if this is helpful then accept otherwise put your comment.
Use Integer.parseInt, and make sure you catch the NumberFormatException that it throws if the input is not an integer.
I'm very sleepy and tired right now but wouldn't this work?:
EditText et = (EditText)findViewById(R.id.editText1);
String sTextFromET = et.getText().toString();
int nIntFromET = new Integer(sTextFromET).intValue();
OR
try
{
int nIntFromET = Integer.parseInt(sTextFromET);
}
catch (NumberFormatException e)
{
// handle the exception
}
Try this,
EditText x = (EditText) findViewById(R.id.editText1);
int n = Integer.parseInt(x.getText().toString());
You can use parseInt with try and catch block
try
{
int myVal= Integer.parseInt(mTextView.getText().toString());
}
catch (NumberFormatException e)
{
// handle the exception
int myVal=0;
}
Or you can create your own tryParse method :
public Integer tryParse(Object obj) {
Integer retVal;
try {
retVal = Integer.parseInt((String) obj);
} catch (NumberFormatException nfe) {
retVal = 0; // or null if that is your preference
}
return retVal;
}
and use it in your code like:
int myVal= tryParse(mTextView.getText().toString());
Note: The following code without try/catch will throw an exception
int myVal= new Integer(mTextView.getText().toString()).intValue();
Or
int myVal= Integer.decode(mTextView.getText().toString()).intValue();
Try the line below to convert editText to integer.
int intVal = Integer.parseInt(mEtValue.getText().toString());
I had the same problem myself. I'm not sure if you got it to work though, but what I had to was:
EditText cypherInput;
cypherInput = (EditText)findViewById(R.id.input_cipherValue);
int cypher = Integer.parseInt(cypherInput.getText().toString());
The third line of code caused the app to crash without using the .getText() before the .toString().
Just for reference, here is my XML:
<EditText
android:id="#+id/input_cipherValue"
android:inputType="number"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
You can use like this
EditText dollar=(EditText) findViewById(R.id.money);
int rupees=Integer.parseInt( dollar.getText().toString());
First, find your EditText in the resource of the android studio by using this code:
EditText value = (EditText) findViewById(R.id.editText1);
Then convert EditText value into a string and then parse the value to an int.
int number = Integer.parseInt(x.getText().toString());
This will work
int total_Parson = Integer.parseInt(etRegularTickets.getText().toString());
int ticket_price=Integer.parseInt(TicketData.get(0).getTicket_price_regular());
total_ticket_amount = ticket_price * total_Parson;
etRegularPrice.setText(""+total_ticket_amount);
In Kotlin, you can do this.
val editText1 = findViewById(R.id.editText)
val intNum = editText1.text.toString().toInt()
In kotlin, there is shortest way thanks to the Extension Function
fun EditText.toInt(): Int {
return this.text.toString().toInt()
}
Use it in your code like below:
mEditText.toInt()
I have 24 buttons in my layout, all these buttons do something similar so I want to create a generic function. But first I need to know the name (xml id) of he button.
This the XML code of the button:
<Button
android:id="#+id/add_04"
android:layout_width="42dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="15dp"
android:background="#xml/zbuttonshape"
android:onClick="onClick"
android:text="#string/mas" />
I set android:onClick="onClick" for all the buttons.
In my activity I've create a new function onClick:
This the code I've tried:
public void onClick(View v) {
String name = v.getContext().getString(v.getId());
String name2 = context.getString(v.getId());
String name3 = getString(v.getId());
String name4 = getResources().getString(v.getId());
}
But when I try to get the name (in this case "add_04") I always get "false".
Finally I've found a solution with the following code:
import java.lang.reflect.Field;
String name5 = null;
Field[] campos = R.id.class.getFields();
for(Field f:campos){
try{
if(v.getId()==f.getInt(null)){
name5 = f.getName();
break;
}
}
catch(Exception e){
e.printStackTrace();
}
}
Is there an easier way to get this ID?
like this:
/**
* #return "[package]:id/[xml-id]"
* where [package] is your package and [xml-id] is id of view
* or "no-id" if there is no id
*/
public static String getId(View view) {
if (view.getId() == View.NO_ID) return "no-id";
else return view.getResources().getResourceName(view.getId());
}
I use this in view constructors to make more meaningful TAGs
The approach is misguided to begin with. If you want to associate a piece of arbitrary data (e. g. a string) with a view, that's what tag is for. The ID is numeric and it better stay that way. A word of caution though, tags are not unique in Android, watch for accidental tag collisions within the same view tree.
EDIT much later: the OP's issue was a case of an XY problem. That said, the question title alone is a legitimate question in its own right.
Edit:
You have to use
getResources().getResourceEntryName(int resid);
If you want to retrieve the entry name associated to a resId
or
You can use getIdentifier() to retriece a resource identifier for the given resource name.
For instance:
int id = this.getResources().getIdentifier("yourtext", "string", this.getPackageName());
You can check id of each button such way:
public void onClick(View v) {
switch (v.getId()) {
case R.id.add_04:
Toast.makeText(MainActivity.this, "1", Toast.LENGTH_LONG).show();
break;
case R.id.add_05:
Toast.makeText(MainActivity.this, "2", Toast.LENGTH_LONG).show();
break;
}
}
Use this Approach to get View Id by Programming .
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
/>
String id=getResources().getResourceEntryName(textView.getId());
Toast.makeText(this,id,Toast.LENGTH_LONG).show();
You will get Result ; tv
You can put this toString() inside an Android View, it will return the String resource Id.
#Override
public String toString() {
Context context;
Resources r = null;
context = getContext();
if (context != null) {
r = context.getResources();
}
String entryName = null;
if (r != null)
entryName = r.getResourceEntryName(getId());
return entryName;
}
Kotlin version (from #gadget) as view extension:
val View.stringId: String
get() {
return if (this.id == -0x1)
"no-id"
else
this.resources.getResourceName(this.id)
}
It's a late answer but may useful someone looking out for a way to get the resource id (int) for any view / drawable / String programmatic.
image from res/drawable
int resID = getResources().getIdentifier("my_image",
"drawable", getPackageName());
view based on resource name
int resID = getResources().getIdentifier("my_resource",
"id", getPackageName());
string
int resID = getResources().getIdentifier("my_string",
"string", getPackageName());
The answer by #King of Masses is great. Here is my in Kotlin:
image from res/drawable
val viewId = context.resources.getIdentifier("my_image", "drawable", context.packageName)
view based on resource name
val viewId = context.resources.getIdentifier("my_textview_id", "id", context.packageName)
string
val viewId = context.resources.getIdentifier("my_string", "string", context.packageName)
Layout
val viewId = context.resources.getIdentifier("my_custom_layout", "layout", context.packageName)