Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding an element within the same TableRow

Tags:

android

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?

like image 722
drmrbrewer Avatar asked May 09 '18 09:05

drmrbrewer


1 Answers

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)

like image 161
Vedant Agarwala Avatar answered Nov 15 '22 05:11

Vedant Agarwala