I'm trying to create a function that pulls together information that is currently scattered around different parts of my project.
As part of this task, I have a layout file with something like the following content... basically a set of rows, with each row having a label (TextView
) and a UI element (e.g. CheckBox
, Spinner
or EditText
) to collect information from the user:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/MyLinearLayout.Section"
android:id="@+id/section_pressure" >
<TableLayout style="@style/MyTableLayout"
android:id="@+id/table_pressure" >
<TableRow style="@style/MyTableRow" >
<TextView
style="@style/MyTextView.Label.WithHelp"
android:tag="label_show"
android:text="@string/label_show" />
<CheckBox
style="@style/MyCheckBox"
android:id="@+id/pressure" />
</TableRow>
<TableRow style="@style/MyTableRow" >
<TextView
style="@style/MyTextView.Label.WithHelp"
android:tag="label_unit"
android:text="@string/label_unit" />
<Spinner
style="@style/MySpinnerStyle"
android:id="@+id/pressureUnit" />
</TableRow>
</TableLayout>
</LinearLayout>
I already have an array of all the android:id
values for the UI elements, and from that I want to generate another array of the corresponding android:text
labels.
e.g. from R.id.pressureUnit
I want to find the associated R.string.label_unit
from that TableRow
, so that I have a central record of what label is used for each UI element... currently that information is scattered across lots of different layout files.
Is this possible programmatically?
From what I understand you want to find @string
resource ID of a sibling view of a given view.
Assuming you have the xml
file already inflated, you can do the following:
private int getSiblingStringId(@IdRes int viewId) {
View uiElement = findViewById(viewId);
ViewGroup parent = (ViewGroup) uiElement.getParent();
// iterate through the siblings
for (int i = 0; i < parent.getChildCount(); i++) {
View view = parent.getChildAt(i);
if (view instanceof TextView) {
String value = ((TextView) view).getText().toString();
// found
return getStringIdFromValue(value);
}
}
throw new IllegalArgumentException("no TextView sibling for " + viewId);
}
private int getStringIdFromValue(String value) {
// get all fields using reflection
Field[] fields = R.string.class.getDeclaredFields();
for (Field field : fields) {
int stringResId = getResources().getIdentifier(field.getName(), "string", getPackageName());
String s = getString(stringResId);
if (s.equals(value)) return stringResId;
}
throw new IllegalArgumentException("no matching string for " + value);
}
The above code will work inside an activity. You might need to modify it a bit for other classes. (You will need to call findViewById
, getResources
and getString
)
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