Search code examples
androidandroid-viewandroid-orientation

Maintaining dynamically set View tag on orientation change


When I set the tag of a View with setTag() dynamically it is not kept after an orientation change. The answers to a couple of related questions (these two answers in particular - 1 & 2) seem to suggest that tags are maintained on orientation changes (memory leaks if a View is stored in the tag means that its not released when it should be - i.e. orientation change). Is there any way to keep View tags after an orientation change (besides physically implementing your own method)?

I've done up a simple example where the tag is not saved on orientation change. The first Button is used to set the tag of the second Button. The second Button displays its current tag when clicked. On orientation change the tag is always null:

public class Main extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        findViewById(R.id.set_tag).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                findViewById(R.id.display_tag).setTag("MY VIEW TAG");
                Toast.makeText(Main.this, "Tag set!", Toast.LENGTH_SHORT).show();
            }
        });
        findViewById(R.id.display_tag).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String s = (String) findViewById(R.id.display_tag).getTag();
                Toast.makeText(Main.this, "Tag is: "+((s == null) ? "null" : s), Toast.LENGTH_SHORT).show();
            }
        });
    }

}
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/set_tag"
        android:text="Set Tag"
        android:freezesText="true"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/display_tag"
        android:text="Display Tag"
        android:freezesText="true"/>
</LinearLayout>

Prior to orientation: Prior to orientation - with tag

Post orientation: After orientation - no tag


Solution

  • I don't think a tag is really what you want here. Consider using onSaveInstanceState and onRestoreInstanceState to preserve any data that needs to persist when the activity gets destroyed and recreated.

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putString("tag", message);
    }
    
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(state);
        message = state.getString("tag");
    }