How to set layout dynamically in android
Solution 1
The best practice is to use fragments instead of change the content view.
In your code, setContentView with layouts recreate (inflate) all your views every time, so the call setContentView(R.layout.layout1) in someBtn2 click listener will create a new button without the associated listener.
If you don't want to use fragments you can do this:
private View view1, view2;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view1 = getLayoutInflater().inflate(R.layout.layout1, null);
view2 = getLayoutInflater().inflate(R.layout.layout2, null);
setContentView(view1);
The listeners will be:
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(view2);
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(view1);
}
});
Solution 2
If you just want to play around with your current code, a solution for your problem is that the listeners must be redeclared when the layout changes, as follows:
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout2);
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout1);
}
});
}
});
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout1);
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setContentView(R.layout.layout2);
}
});
}
});
An alternative to avoid declaring the listeners twice is to declare two methods to handle the layout changes and use the onClick
property of the button in each of the layouts, for example:
public void setLayout1(View view) {
setContentView(R.layout.layout1);
}
public void setLayout2(View view) {
setContentView(R.layout.layout2);
}
In layout1.xml
:
<Button
android:id="@+id/someBtn1"
android:onClick="setLayout2"/>
In layout2.xml
:
<Button
android:id="@+id/someBtn2"
android:onClick="setLayout1"/>
However, if you want to follow best practices, the best practice is not to mix layouts in the same activity, but instead declare two different activities (each one with its own layout) and call one activity or the other depending on the button that was clicked. Suppose that you are in Activity1 and want to call Activity2, then go back to Activity1:
In Activity1.java
:
someBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(this, Activity2.class));
}
});
In Activity2.java
:
someBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
Solution 3
One way of doing this is loading both views in onCreate(...)
, and then switching between them by making the one you don't want invisible. Something like the following:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutParams default_layout_params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
View view1 = inflater.inflate(R.layout.layout1, null);
addContentView(view1, default_layout_params);
View view2 = inflater.inflate(R.layout.layout2, null);
addContentView(view2, default_layout_params);
view2.setVisibility(View.INVISIBLE);
view1.setVisibility(View.VISIBLE);
view1.bringToFront();
iamcrypticcoder
Hi, This is MAHBUB. An Engineering student of Khulna University of Engineering and Technology. I am in CSE discipline. That's all about my academic info. I am a little developer both for web and desktop. C and C++ my favorite programming language as they are with me from my childhood. Currently I feel comfortable with PHP, CodeIgniter, Yii, Symfony, JQuery UI + AJAX, Javascript, MySql, JAVA SE, C# (.NET framework). I am very new in Stack Overflow. Hope I can contribute here as my ability. Thanks.
Updated on September 10, 2020Comments
-
iamcrypticcoder over 3 years
Well, Suppose there is an Activity called MainActivity and there are two layouts called layout1 and layout2 both have few buttons. By default MainActivity layout is layout1 like following:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout1);
Now what I did actually is by clicking a button in layout1 the second layout is set like following:
someBtn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { setContentView(R.layout.layout2); } });
There are another button in layout2 to return back to layout1 like following:
someBtn2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { setContentView(R.layout.layout1); } });
Problem is when I returned back to layout1 then OnClickListener of someBtn1 is not working. It seems I need to set OnClickListener again for someBtn1 of layout1. How I can write code to make them work perfectly with best practices ?
-
iamcrypticcoder almost 11 yearsYes, I know that. But for some reason i want to use different layouts in same activity dynamically. Thanks for your suggestion.
-
Piovezan almost 11 yearsI have improved my answer to avoid declaring listeners twice, please take a look.
-
Piovezan almost 11 yearsI'd like to learn the fragment way, do you have any quick examples?
-
iamcrypticcoder almost 11 yearsThanks for your code. Actually I need to switch 3-4 layouts in one activity. That's why still I confused what should i have to use. Is it better to use Fragment in this case ?
-
Stochastically almost 11 yearsI've just posted code that I've used successfully for two layouts. I'm pretty sure that this approach would work for more, but
better
andbest
are subjective so I'll leave the choice to you! -
spacifici almost 11 yearsPlease, read this developer.android.com/guide/components/fragments.html, and find examples in SDK Examples and Android Support Library (both available for download via the Android SDK Manager)
-
Žilvinas over 6 yearsHow can I make bottom back button to get back to previous layout but not to a previous activity ?
-
Nadeem Shaikh almost 6 yearswhat if button1 and button2 has same id in both views? I am actually struggling with that condition. I actually have multiple buttons on my both views and dont wanna write different listener for each if they are doing the same work. Is there any solution for it?
-
spacifici almost 6 yearsYou can get the button from the inflated view (view1.findViewById(...)), then assign to it a listener that just check the reference (view == view1)