Android: Programmatically iterate through Resource ids - android

I want to be able to iterate through all of the fields in the generated R file.
Something like:
for(int id : R.id.getAllFields()){
//Do something with id, like create a view for each image
}
I've tried reflection, but I can't seem to load a specific inner class that's contained inside the R class. So, for example, this wouldn't work for me:
Class c = Class.forName("packageName.R.id")
I can reflect on the R class itself, but I need the fields within the id class.
I also tried looking through the Resources class, but couldn't find anything there. In that case, it seems you can take a resourceID and get the string name of that id, or take a string name and get the corresponding resourceID. I couldn't find anything like:
int[] Resources.getAllResourceIDs()
Maybe I'm going about this wrong. Or maybe I shouldn't fight typing them all in by hand, e.g.:
int[] myIds = {R.id.firstResource, R.id.secondResource}
This approach has the downside of not being as flexible when working with my UI designer. Whenever he adds a new resource to the XML file, I'll have to update the code. Obviously not too painful, but it would still be nice to have and it seems like it should be doable.
EDIT:
The answer below about ViewGroup.getChildCount()/ViewGroup.getChildAt() works fine. But, I also had to find a way to instantiate my XML ViewGroup/Layout. To do that, try something like:
LayoutInflater li = MyActivity.getLayoutInflater();
ViewGroup vg = (ViewGroup) li.inflate(R.layout.main, null);

I found that "Class.forName(getPackageName()+".R$string");" can give you access to the string resources and should work for id, drawable, exc as well.
I then use the class found like this:
import java.lang.reflect.Field;
import android.util.Log;
public class ResourceUtil {
/**
* Finds the resource ID for the current application's resources.
* #param Rclass Resource class to find resource in.
* Example: R.string.class, R.layout.class, R.drawable.class
* #param name Name of the resource to search for.
* #return The id of the resource or -1 if not found.
*/
public static int getResourceByName(Class<?> Rclass, String name) {
int id = -1;
try {
if (Rclass != null) {
final Field field = Rclass.getField(name);
if (field != null)
id = field.getInt(null);
}
} catch (final Exception e) {
Log.e("GET_RESOURCE_BY_NAME: ", e.toString());
e.printStackTrace();
}
return id;
}
}

Your reply to my comment helped me get a better idea of what you're trying to do.
You can probably use ViewGroup#getChildAt and ViewGroup#getChildCount to loop through various ViewGroups in your view hierarchy and perform instanceof checks on the returned Views. Then you can do whatever you want depending on the type of the child views and where they are in your hierarchy.

You can use reflection on an inner class, but the syntax is packagename.R$id. Note that reflection can be very slow and you should REALLY avoid using it.

Related

Change ObjectBox LiveData Query

I have an ObjectBoxLiveData object with a query that is set at runtime:
private ObjectBoxLiveData<MyObject> myObjectLiveData;
public ObjectBoxLiveData<MyObject> getMyObjectLiveData(Box<MyObject> myObjectBox, String filterTerm)
{
if (myObjectLiveData == null)
myObjectLiveData = new ObjectBoxLiveData<>(myObjectBox.query().equal(MyObject_.filterProperty, filterTerm).build());
return myObjectLiveData;
}
But I also need to be able to change the filterTerm at runtime. My thinking is that I can make a private String currentFilterTerm; object in MyViewModel to see if I need to update the filter term in the LiveData object, but is there a correct way to update the filter term? I worry that setting myObjectLiveData = new ObjectBoxLiveData<> again will leave a memory leak for the previously defined myObjectLiveData or anything tied to it, but I don't see any graceful way to dispose of it or update the query once defined. Is there a way to redefine my query once defined?

textView updates do not show

Ok - preface with I am new to android and new to java as well. But I did code in a previous lifetime.....
I am working on an application and now trying to pull some methods out and place into a utility class. In particular, I have a method which updates text views that I wanted to move out of an activity.
When in the activity, I had two versions of the method the only difference being that one would accept a view in the parameter list (I used this to populate some fields in a custom dialog). They all worked fine.
Once placed in the external utility package/class, the method no longer works - no errors, and it appears to have all it needs - I've done some logging and the view claims to be visible and the textview ids appear to be correct. Yet nothing changes on the screen.
I'm guessing this is something completely obvious and stupid but I can't seem to sort it out.
package xxx.xxx.Utility;
(some imports)
public class Utility {
public static void updateTextView(int id, String opt_data, View v) {
String TAG = "updateTextView: ";
if (v.getVisibility() == View.VISIBLE) Log.i(TAG," visible");
TextView tvTarget = (TextView) v.findViewById(id);
if (tvTarget == null) {
Log.i(TAG, "Error: updateTextView target is null");
}
if (opt_data != null) {
if (tvTarget != null) {
tvTarget.setText(opt_data);
}
} else {
if (tvTarget != null) {
tvTarget.setText(" ");
}
}
}
}
EDIT w/ Additional Info:
In the inital description I mentioned that this method was also being used to populate some fields of a pop-up dialog with data. In fact, I can request any number of dialogs in that manner and they all display properly and with the correct (and different) data. So it seems to fail only when trying to update the tv data of the main activity (the initial) view.
I'm guessing this is something completely obvious and stupid but I
can't seem to sort it out.
It helps to get the root(?) parent (?) view properly. IE,
currentView = this.findViewById(android.R.id.content).getRootView();
and now all is well.

Parsing XML in android, but not the attributes

I'm trying to parse a really simple XML in my android app, for example:
<data>
<section id="123">bla</section>
<area>blabla</area>
</data>
But in every example I find I see how to extract the data in the attribute (id being 123) when what I need to extract is the data displayed - "bla" and "blabla".
How do I do that using SAXParser?
this tutorial respond to exactly what you want hope you gonna enjoy
See how The characters method in the parser handler takes care of extreacting an element's text value
The characters method in the parser handler takes care of an element's text value.
You need to override the characters method.
Well, writing parsers by hand is of course fun & error-prone, I'd however recommend using a framework - even a simple one like the built in android.sax package.
Using the StartElementListener (if you want the attributes at all that is) & EndTextListener (captures the body text of the element):
class Section implements StartElementListener, EndTextElementListener {
String mValue;
String mId;
#Override
public void end(String body) {
mValue = body;
}
#Override
public void start(Attributes attributes) {
mId = attributes.getValue("", "id");
}
}
Listeners of these types are attached to Elements derived from a RootElement, like so:
Section section = new Section();
RootElement data = new RootElement("data");
// Use "requireChild" if a "section" is required as a child of "data".
Element s = data.getChild("section");
s.setStartElementListener(section);
s.setEndTextElementListener(section);
try {
Xml.parse(xml, data.getContentHandler());
} catch (SAXException e) {
}
Basically, this helps you build content handlers for SAX that cares about the hierarchy and keeps track of what element you are parsing easily. Short & nifty code also I guess.

how to link my getEmptyForeignCollection() object with my parent object?

I want to persist an object with two foreignCollections.
But when I try to query the object, my foreignId is always null.
I already read this answers but it doesn't really help me: Collections in ORMLite
VOPerception perception = new VOPerception();
perception.setOrientation(daoOrientation.createIfNotExists(
orientationLocalizer.getCurrentOrientation()));
ForeignCollection<VOAccessPoint> fAp =
daoPerception.getEmptyForeignCollection("accessPoints");
fAp.addAll(wifiLocalizer.getCurrentScanResultMap());
perception.setAccessPoints(fAp);
daoPerception.create(perception);
List<VOPerception> list = daoPerception.queryForAll();
here data are correctly stored but VOAccessPoint objects have no link with the parent VOPerception object.
Here are my two classes:
public class VOPerception {
#DatabaseField(generatedId=true)
private int per_id;
#ForeignCollectionField(eager=true)
ForeignCollection<VOAccessPoint> accessPoints;
...
}
public class VOAccessPoint{
#DatabaseField(generatedId=true)
private int ap_id;
#DatabaseField(foreign=true,columnName="apForeignPerception_id")
private VOPerception apForeignPerception;
...
}
Your queryForAll() is returning no objects because none of your VOAccessPoint instances ever set their apForeignPerception field to be perception. Adding the VOAccessPoint objects using the ForeignCollection added them to the DAO but did not automagically assign their apForeignPerception field.
You should do something like:
...
Collection<VOAccessPoint> points = wifiLocalizer.getCurrentScanResultMap();
for (VOAccessPoint point : points) {
point.setApForeignPerception(perception);
}
fAp.addAll(points);
...
I can see how you might think that this would be handled automagically but at the time they are added to the ForeignCollection, the perception is not even assigned. I suspect that there is a missing feature for ORMLite here or at least a better exception.
I would recommend to use assignEmptyForeignCollection(Obj parent, fieldName). This will create a new foreign collection and all objects you will add via add(Obj element) will have the parent value set automatically.

android - get a resource (a string) from its unique integer

I want to do the following:
I want to make a very simple gallery application. So I'd like to select a path for the images and set it as a resource. I set it in String.xml.
So I have another class, which needs the selected path to load all the images from it.
class ImageHolder
{
public ImageHolder()
{
this(R.string.image_dir);
//problem is here - R.string.image_dir returns a unique int, while what I really need is the string. How can I get it...
}
public ImageHolder(String path)
{
.........standart procedure.....
}
}
Use getString(resID) but you'll need a Context Object though.
It's a Function of Context, so within an Activity you can write this.getString(R.string.image_dir); or you can skip this altogether...

Categories

Resources