Rufus
Rufus

Reputation: 27

How to get a layout from activity that is linked with onClick attribute in XML?

I'm a beginner in Android and I'm testing my code using Android JUnit test.

So, I have a test activity that extends ActivityInstrumentationTestCase2<Activity>.

Activity has it's own layout in onCreate() method. (Main layout)

In my XML, I have a onClick attribute for a button that calls foo() method.

Back to Activity, in the foo(View v), I set my content view to a different layout.

I want to test that layout.

How do I get the layout though??

I know for the main layout, I can do this.

Activity act = getActivity();
View mainLayout = (View) act.findViewById(bla.bla.bla.R.id.main_layout);

How do I get the layout that I set in foo(View v)??

I've already tried doing,

fooLayout = (View) act.findViewById(bla.bla.bla.R.id.foo_layout);

and

act.setContentView(bla.bla.bla.R.layout.foo_layout);
fooLayout = (View) act.findViewById(bla.bla.bla.R.id.foo_layout);

I think I got NullPointerException for the first one and android.view.ViewRootImpl$CalledFromWrongThreadException for the second one.

Upvotes: 0

Views: 2956

Answers (2)

207
207

Reputation: 3804

In your first try you get a NullPointerException because you are searching for your foo_layout wihtin your main_layout. findViewById is used to search for views wihtin a layout and not to find/inflate layouts. In your second try you get a CalledFromWrongThread Exception because you access the UI (setContentView()) from outside the UI thread. This is how you change the layout wihtin your test class:

getActivity().runOnUiThread(new Runnable() {
@Override
    public void run() {
        getActivity().setContentView(R.layout.foo_layout);
    }
});
getInstrumentation().waitForIdleSync();
// now you can access your views from your foo_layout via getActivity().findViewById(...)

I don't know what you mean by "I want to test my layout". Either you want to check if your layout got successfully loaded through a button click or you want to access the views of the new (loaded) layout. In both cases you can do something like the following:

public void testLayout() {
    // get your button that changes the layout of your activity. 
    // that button is in your main_layout
    final Button btChangeLayout = (Button) getActivity().findViewById(R.id.yourButtonThatChangesTheLayout);

    // perform a click in order to change the layout
    getActivity().runOnUiThread(new Runnable() {
    @Override
        public void run() {
            btChangeLayout.performClick();
        }
    });
    getInstrumentation().waitForIdleSync();

    // get a reference of a view thats in your foo_layout e.g. a Button
    Button aButtonInYourFooLayout = (Button) getActivity().findViewById(R.id.aButtonInYourFooLayout);
    // now you can do what your want with your button/view. 

    //if you just want to know wheter your layout has successfully been loaded
    //or not you can test your view if it's null
    assertNotNull(aButtonInYourFooLayout);
}

Upvotes: 1

Alex Muni
Alex Muni

Reputation: 474

i'm not sure ... but i think the first problem is:

act.setContentView(bla.bla.bla.R.id.foo_layout);

change to:

act.setContentView(bla.bla.bla.R.layout.foo_layout);

because in res/layout/ you have your UI, isn't it?

Upvotes: 0

Related Questions