4

I try my hardest to develop a clever way to clean out piles of Blah blah = (Blah) this.findViewById(R.id.blah) that otherwise pollute the field and the onCreate() method of my little Activity, and to do so, I feel I should not use setContentView() but getViewInflate().inflate() for every View defined in XMLs.

Is Activity.setContentView() is sorta a syntax sugar and it's virtually repeating getViewInflate().inflate() for every View on XML? I read something saying as if they were the same.

If I can get an answer by looking into the code, please tell so. I checked Activity.class, but only comments were found.

Quv
  • 2,958
  • 4
  • 33
  • 51

3 Answers3

2

The setContentView on your Activity actually calls the setContentView on the Window used by the activity, which itself does a lot more than just inflating the layout.

What you could do is to map the views to the class field using reflexion. You can download a utility class on Github that does this.

It will parse all the views declared in the layout, then try to find the name corresponding to the id in your R.id class. Then it will try to find a field with the same name in the target object and set it with the corresponding view.

For example, if you have a layout like this

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

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
</LinearLayout>

it will automatically map it to a textView1 field in your activity.

XGouchet
  • 10,002
  • 10
  • 48
  • 83
  • Thanks. They were really interesting. One problem for me is its performance, perhaps because it calls a method to search EVERY `View `that belongs the `ViewGroup` of `android.R.id.content`. Perhaps I'll refrain from using `setContentView()` and define my own method, so that I can assign `View` to variables every time `ViewInflate.inflate()` is executed. – Quv Jul 16 '12 at 13:47
2

I'm posting my poor research. In summary, Activity.setContentView() delegates PhoneWindow.setContentView() (the only concrete class of Window ) within which LayoutInflater.inflate() is called, so saying "setContentView() == ViewInflate().inflate()" is not so overly off, I guess.

public class Activity extends ContextThemeWrapper{

    private Window mWindow;

    public void setContentView(int layoutResID) {
        getWindow().setContentView(layoutResID);
        initActionBar();
    }

    public Window getWindow() {
        return mWindow;
    }
}



public class PhoneWindow extends Window {

    private LayoutInflater mLayoutInflater;

    @Override
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            installDecor();
        } else {
            mContentParent.removeAllViews();
        }
        **mLayoutInflater.inflate(layoutResID, mContentParent);**
        final Callback cb = getCallback();
        if (cb != null) {
            cb.onContentChanged();
        }
    }
}
Asutosh Panda
  • 1,463
  • 2
  • 13
  • 25
Quv
  • 2,958
  • 4
  • 33
  • 51
0

Actually you're right, there's two ways to achieve the same thing:

1) setContentView(R.layout.layout);

2)

LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
View v = inflater.inflate(R.layout.layout, null);
setContentView(v);

You decide what is more appropriate for you. Hope this helps.

Egor
  • 39,695
  • 10
  • 113
  • 130
  • Sorry for my really vague question. I suspected, in the definition of `setContentView()` method, `ViewInflate.inflate()` was actually used, and wanted to know it it was the case. Should I elaborate my question more, maybe... – Quv Jul 11 '12 at 10:22