3

I have 2 layouts.

The 1st loads (a WebView) fine when the program starts.

The 2nd one also loads (a simple layout) fine when user selects a menu item:

setContentView(R.layout.simple);
LinearLayout ll = (LinearLayout) findViewById(R.id.simple_layout);

All it does is display an image while processing something in the background. When processing is done, it attempts to switch back (via Handler) to the WebView it just obscured.

setContentView(R.layout.main);

The switching seems to occur but the webview is blank.

Why is that? Isn't setContentView() enough to switch back to the 1st layout just as the switch to 2nd worked fine?

Eternal Learner
  • 2,602
  • 5
  • 27
  • 38
  • 1
    If you want to switch dynamically without creating new activities, use fragments. One fragment - one layout. So your one activity has 2 fragments on "fly" (one per time). How to use fragments, see here: http://developer.android.com/guide/components/fragments.html – Volodymyr Lykhonis Jul 23 '12 at 01:39
  • @VladimirLichonos Thanks for tip. Are fragments available/compatible with Android 2.2? – Eternal Learner Jul 23 '12 at 01:41
  • Or just make sure you use Inflater to inflate any views you may want to use, then you can use setContentView whenever you wish. – Andy Harris Jul 23 '12 at 01:42

2 Answers2

6

I use this method: In main program:

private LinearLayout mainview;
private LinearLayout playerview;

In onCreate:

LayoutInflater inflater = LayoutInflater.from(this);
setContentView(R.layout.main);
mainview = (LinearLayout) this.findViewById(R.id.main);
playerview = (LinearLayout) inflater.inflate(R.layout.player, null);

Then you can call

setContentView(mainview);

and

setContentView(playerview);

whenever you want. All you need is two layout xml files, one for each layout. This is much simpler than Fragments or other methods.

For some reason, I don't have to inflate the main view I start with, only the others. I think it's because setContentView() must inflate the view for you when it's called.

Andy Harris
  • 928
  • 5
  • 10
  • I love your approach but where do you initialize `mainview`? – Eternal Learner Jul 23 '12 at 01:58
  • This method has the added bonus that all fields of each view are preserved as you switch back and forth between views, so if you have user input, etc. it won't be lost. If you reinitialize your views every time you switch, you'll have to save any new information yourself. And remember to switch any LinearLayout references to WebView etc. as needed :) – Andy Harris Jul 23 '12 at 02:21
  • Sorry, there's something wrong in the code you posted. The switch to `playerview` works OK, but switching back produces `IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.` – Eternal Learner Jul 23 '12 at 02:57
  • Also, why the asymmetrical init of the two LinearLayout private members? Why not initialize both with `inflater.inflate()`? – Eternal Learner Jul 23 '12 at 02:59
  • You can inflate it if you want. I think it's unnecessary only because the main Activity is set to the main layout on creation, while all other views are only inflated and ready to be used later. I have several views in my actual code and I inflate them all except the main one. I copied this code directly from a project I'm working on, so I'm not sure why it doesn't work for you...must be your setup is different than mine. – Andy Harris Jul 23 '12 at 03:36
2

The main problem here is that you shouldn't call setContentView() several times (as noted in the comments). Fragments are a good idea, but you can also use a ViewFlipper if your just tying to change between 2 views. Example taken from http://blog.kerul.net/2011/07/viewflipper-examplea-simple-flashcard.html

   Button next,previous;
    ViewFlipper vf;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        next = (Button) findViewById(R.id.Button01);
        previous = (Button) findViewById(R.id.Button02);
        next.setOnClickListener(this);
        previous.setOnClickListener(this);
        vf=(ViewFlipper)findViewById(R.id.ViewFlipper01);
    }

    //@Override
    public void onClick(View v) {
        if (v == next) {
            vf.showNext();
        }
        if (v == previous) {
            vf.showPrevious();
        }
    }
}

The reason your screen is blank is because you'll have to re-init your webview again. If you were to call setContentView() several times, you have to re get your findViewByIds and all that. List view included.

Frank Sposaro
  • 8,511
  • 4
  • 43
  • 64
  • I think you are right about having to re-init the webview again. Since I just want to switch back to the previous state of the webview where I left it, I don't really want to re-init the webview. Your ViewFlipper approach works like a charm. Accepting. – Eternal Learner Jul 23 '12 at 03:29