Android and getting a view with id cast as a string - java

In the Java code of an Android project if you want the reference for a view resource you can do something like:
View addButton = findViewById(R.id.button_0);
In the above R.id.button_0 is not a String. Is it possible to dynamically refer to a resource by a string, such as "R.id.button_0"?
I'd like to refer to a button by "R.id.button_%i" where %i is replaced by some valid index.

int resID = getResources().getIdentifier("button_%i",
"id", getPackageName());
View addButton = findViewById(resID);
where %i is replaced by some valid index.
The getResources() method belongs to the Context class, so you can use that directly from an Activity. If you are not inside an activity, then use a context to access: (myCtxt.getResources()).

You could try putting all the ids you want in an array and then using that array to dynamically refer to your resources instead.

Related

Deleting a View in a class method

In my activity I try to call a method from a class but it's not getting the right values.
This is ActivityTwo:
int id = intent.getIntExtra("id", 0);
LayoutInflater inflater = getLayoutInflater();
View mainActivity = inflater.inflate(R.layout.activity_main, null);
LinearLayout eventsLayout = mainActivity.findViewById(R.id.eventsLayout);
Log.d("ACTIVITY_eventlayout", String.valueOf(eventsLayout)); // gives the layout perfectly
Event.RemoveSpecific(eventsLayout, id);
finish();
This is the class(Event) with the method:
public static void RemoveSpecific(LinearLayout layout, int id){
View event = layout.findViewById(id);
Log.d("INSIDE_removespecific", String.valueOf(event));// event is null
layout.removeView(event);
}
And in my MainActivity it's working fine:
LinearLayout eventsLayout = findViewById(R.id.eventsLayout);
View event = eventsLayout.findViewById(id);
//Log.d("MAIN_event", String.valueOf(event1)); // gives it perfectly
eventsLayout.removeView(event);
I also add this view in my MainActivity and use .setId(id) to give it the right id. So my question is, why is the View in my class method null, while I pass the right LinearLayout from my activityTwo?
Where does the id come from?
I have the Event class which contains an id, name, date, & description. This class also has a static ArrayList called eventsList. Whenever the user creates a new reminder I create a new Event using my class and giving it an id as Event.eventsList().size() (after adding it to my eventsList [so the first event id is always 1]), then I create a new View and pass the recently created Event details and use setId() to give it an id [1]. Then in this View I have a button which has an onClickListener which passes the given View id and the LinearLayout (where the View was added) to my Event.removeSpecific() method.
App flow:
The user clicks a button in MainActivity to create an event, then the button click then use startActivityForResult() with an intent to open a new Activity where the user puts in a name,description and date for the event, then I create an intent with putExtra() methods and then use setResult(RESULT_OK, resultintent) to send the data back to MainActivity. Now when the MainActivity gets the data back I use .getStringExtra() to create a new Event object with the data and add it to may Event.eventsList ArrayList, then I use the following:
LayoutInflater inflater = getLayoutInflater();
View event_Exmaple = inflater.inflate(R.layout.event_example, null);
and set the textView's with the data I got, and use event_example.setId(Event.eventsList.size()) to give it an id.
After that I add this to my LinearLayout (which I declared already in the MainActivity):
eventsLayout.addView(event_example)
Now I mentioned that the Event class has a date field. I use that to set up an alarm with AlarmManager. With the AlarmManager I send the current Event object's data through the intent and when the user gets the notification it opens up a new Activity which gets the given Event object data (with intent.putExtra()'s) and that's the part where the user clicks on a Button. I want to remove the given Event object's View from my LinearLayout in the MainActivity XML.
well since you didn't share where the id value come from (from where the intent gets its data/how you put the values in it/where the values come from), I assumed this solution :
whenever I use a 'switch' statement with View Ids it tells me a very important warning which is
Resource IDs will be non-final in Android Gradle Plugin version 5.0, avoid using them in switch case statements
that means that view Ids doesn't have a stable id in some cases that you shouldn't consider them to be final.
I guess in your case when you get an id to your event view and then inflate the layout view, the inflate procedure involve changing the 'int' id value of the event view so whenever you query the old id it returns null since the event view inside the inflated layout view now has a new 'int' id value.
I don't know why it works in main activity since you didn't share full code where you get the id from.
so I guess the only solution is that you should find a way to get a fresh copy of the id after you inflate the view you want to work on in the method.
Update
the problem is with this block of code
View mainActivity = inflater.inflate(R.layout.activity_main, null);
everytime you inflate a new layout view thinking that you have the one used by main activity back there but instead you're creating an entirely new one with new views and new Id's.
that would be why you could get the view in main activity but you can't get it from a newly inflated view.
Update
if you need to remove this item using the id and have a static array stored in the view custom class, call a getter on the static array and remove the item from it instead of trying to remove the view itself.
a better implementation of the whole situation is to store these events in a database using room instead of the static array, that way you could delete/add/edit any event anytime with just one line of code, if you're willing to do this you can start by reading the developers documentation of room.

How objects are created in android studio using findViewById(R.id.xyz) and without using new

TextView quantityTextView=(TextView) findViewById(R.id.quantity_text_view);
When creating object for quantityTextView reference we use id from xml that is quantity_text_view but how object is created for it without using new keyword.
I have searched a lot but haven't found the solution. I'm new in Android Programming, if you know the answer please tell how you find the solution for it
On your onCreate method you are doing something like that
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
}
on the line setContentView(R.layout.main_layout); you are setting the layout and then you just getting reference on elements from that layout
And because of the UI has been set you don't need to create something with the new keyword just to get the reference with the findViewById
If you want to add dynamically a layout element you will need to use the new keyword and then add that element on your layout
You can use android-layout-finder to without using new keyword. https://www.buzzingandroid.com/tools/android-layout-finder/
Declare in class:
private TextView quantityTextView; //this is already a object
In your onCreate() init the View:
TextView quantityTextView=(TextView) findViewById(R.id.quantity_text_view);
Now you can use quantityTextView anywhere without any new creation.
If you want to add Textview dynamically you need to use Text view like this:
TextView tv=new Textview(this);
And if you want to inflate the Textview from the XML file then you need to use TextView like this:
TextView quantityTextView=(TextView) findViewById(R.id.quantity_text_view);
findViewById does nothing. It just looks through view hierarchy and returns reference to a view with requested viewId. View is already created and exists. If you do not call findViewById for some view nothing changes.
Views are inflated by LayoutInflator. When you call setContentView xml layout is parsed and view hierarchy is created.
attributes passed to Button's constructor by LayoutInflater. check LayoutInflator source code.

Open a resource file just with specific String variable

Sorry for the title, had troubles describing what I'm trying to do. I've always had this question for Java as a whole, but right now, its specific for Android. Let's say that I am parsing an API and get this special String, let's say "clear". Inside my drawables, I have a clear.jpg that I would like to set as an ImageView programically . That's not the hard part. What I was wondering is if there was a quick way where I Could call on the .jpg with just the variable name? I know I can easily make different if statements, such as:
if(string == "clear")
{
//setImageView to drawable/clear
}
but is there anyway I can do something such as
//setImageView to drawable/string
where string would be clear? I know obviously it would look for a string inside drawable, but is there anyway I could do what I'm describing? Just a general question I had; it was something I always wondered about.
Let me know! Thanks!
private void showImage() {
String uri = "drawable/icon";
// int imageResource = R.drawable.icon;
int imageResource = getResources().getIdentifier(uri, null, getPackageName());
ImageView imageView = (ImageView) findViewById(R.id.myImageView);
Drawable image = getResources().getDrawable(imageResource);
imageView.setImageDrawable(image);
}
Else I would recommend you to work with R.* references like this:
int imageResource = R.drawable.icon;
Drawable image = getResources().getDrawable(imageResource);
Reference -> Android - Open resource from #drawable String
With what i know, the quickest way to call up that picture is putting the
picture's name in the xml file; For instance if you want to change the background
of an imageview, you can just put in your xml file this code below
android:background="#drawable/clear".
Note the image must have been in the drawable folder. Thanks, i hope this helps.
It looks like Java 8 provides limited support for local variable annotations, but its reflection API can't give you access within method bodies. So you'd need to parse the class file itself. And for that, a library like ASM would do the trick.
if(string.equals("clear")){
int resID = getResources().getIdentifier("clear", "drawable", getPackageName());
imageView.setBackgroundResource(resID);
}
Same as other ones at the point which is using getIdentifier method.
imageView.setImageView(getResources().getIdentifier(string, "drawable",
getPackageName()));
However, by doing this, you can process without if-condition block and just specify a Drawable of the value from string directly (I think it is your intention of this question).

Adding a xml to a LinearLayout item in android studio

I have xml layout which includes a avatar picture a name and a textbox. These are all in one xml file. I would like to add instances these programmically to a linear layout that is nested in a scoll view. Here is my code.
View v = getLayoutInflater().inflate(R.layout.include_message, null);
LinearLayout stallWall = (LinearLayout) v.findViewById(R.id.stallMessages);
R.layout.include_message = My xml
R.id.stallMessages = Linear Layout
I get no errors and i see no items being added.
I would like to read a array and put a include_message in for each message.
First, I would not recommend using x = y = z = a and so on.
It may be working but it's not easy to read and understand.
as codeMagic said, you should use addView() method to achieve this.
here's an example http://androidexample.com/Dynamically_Create_View_Elements__-_Android_Example/index.php?view=article_discription&aid=115&aaid=137
If you are trying to use a layout defined in an xml file, you can user LayoutInflater like this:
View view = getLayoutInflater().inflate(R.layout.yourfile, null);
layout.addView(view);

android how to find an element defined in view

In android layout xml file a framelayout element is defined like #android:id/tabcontent
how to refer that element in java code
= (Framelayout) findViewById(R.id. _ __
so then what is the difference between
#android:+id/tabcontent
#+id/tabcontent
#android:id/tabcontent
#id/tabcontent –
It should be android.R.id.tabcontent
Always remember whenever you use predefined android resources you must use android.R
Defining the id as "#+id/tabcontent" you could easily find it as (Framelayout) findViewById(R.id.tabcontent)
if you declared the id of frame layout like #android:id/tab??? so you have to find this framelayout using this.
(Framelayout) findViewById(android.R.id.tabcontent)
The + sign adds this id to the automatically created R.java file (so you can reference the resource using R.id) the android: means that the resource is inside android.R.java file (similar to R.java, but refers to android system resources). So, as in the other answers #android:id refers to android.R.id

Categories

Resources