Nat
Nat

Reputation: 908

Setting Nested TextView Text

I've created a layout for a button format I use multiple times. The button format has a TextView and an ImageView. With the way I'm including this layout in my main activity, I don't think I'm able to change the text of the inner TextView dynamically in Java or in the XML. Is there a different way I can do this such that I can set the text of the inner TextView?

Layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/settingslayout">


<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="25dp"
    android:layout_marginTop="13dp"
    android:textSize="20dp"
    android:text="CHANGE ME"
    android:id="@+id/text" />

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="12dp"
    android:layout_marginRight="25dp"
    android:layout_alignParentRight="true"
    android:src="@drawable/left"
    android:adjustViewBounds="true"
    android:scaleType="centerCrop"
    android:maxHeight="30dp"
    android:maxWidth="30dp"/>
</RelativeLayout>

Main Activity:

...
<include layout="@layout/settings_layout"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/accountStaticUnderline"
    android:id="@+id/termBegin"
    android:text="TEST" /> //DOESNT WORK
...
</RelativeLayout>

Upvotes: 1

Views: 1446

Answers (2)

Karakuri
Karakuri

Reputation: 38605

Setting the text that way won't work because android:text is not applicable to the <include> tag. More specifically, it's not applicable to the thing being included, which is a RelativeLayout. (You couldn't put the android:text on the RelativeLayout and have it apply to the TextView, nor would you expect that to work.)

My first suggestion (and the easiest immediate solution) is to use TextView's built in support for compound drawables so you can simply use TextViews instead of includes and have a style resource for the attributes you want.

If that's not good enough for your use case, then you might need to make a custom View. This view will replace the RelativeLayout and have the TextView and ImageView as children. The main thing to decide is where and how the children are created and their references are obtained: you can create them manually in Java when the parent is being constructed; or you can use some combination of layouts with <include>s and/or <merge>s. Making the text attribute work then requires some use of a <declare-styleable>.

I assume you want the children to always appear the same and that you want to reuse the layout you already made (i.e. you don't want to set all the attributes manually), so this is what I would probably do:

public class MyButton extends RelativeLayout {

    private TextView mTextView;
    private ImageView mImageView;

    public MyButton(Context context) {
        super(context);
        init(context, null);
    }

    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    public MyButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attributeSet) {
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.my_button, this, true); // used with merge tag
        mTextView = (TextView) findViewById(R.id.text);
        mImageView = (ImageView) findViewById(R.id.image);

        int[] attrs = {android.R.attr.text};
        TypedArray a = context.obtainStyleAttributes(attributeSet, attrs);
        String text = a.getString(0, null);
        mTextView.setText(text);
        a.recycle();
    }
}

In res/layout/my_button.xml:

<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="25dp"
        android:layout_marginTop="13dp"
        android:textSize="20dp"
        android:text="CHANGE ME"
        android:id="@+id/text" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:layout_marginRight="25dp"
        android:layout_alignParentRight="true"
        android:src="@drawable/left"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
        android:maxHeight="30dp"
        android:maxWidth="30dp"/>
</merge>

In your activity layout:

...
<!-- no more include -->
<com.package.MyButton
    android:id="@+id/something"
    android:layout_width="..."
    android:layout_height="..."
    android:text="..." />

<!-- you can have multiple instances with different IDs -->
<com.package.MyButton
    android:id="@+id/something_else"
    android:layout_width="..."
    android:layout_height="..."
    android:text="..." />
...

You could also use your own <declare-styleable> for the custom view, which will be necessary if later you want to have custom XML attributes for it, but the approach above should be sufficient.

Upvotes: 1

P. Ilyin
P. Ilyin

Reputation: 791

sure, just type this code in your activity

((TextView)findViewById(R.id.text)).setText("enter_text_here");

Upvotes: 1

Related Questions