Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set layout dynamically in android

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 ?

like image 626
iamcrypticcoder Avatar asked Jun 12 '13 15:06

iamcrypticcoder


People also ask

What is dynamic layout in Android Studio?

DynamicLayout is a text layout that updates itself as the text is edited. This is used by widgets to control text layout. You should not need to use this class directly unless you are implementing your own widget or custom display object, or need to call Canvas.

How to add LinearLayout dynamically in Android?

This example demonstrates how to add a TextView to a LinearLayout dynamically in Android using Kotlin. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.


2 Answers

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);
    }
});
like image 115
spacifici Avatar answered Sep 19 '22 10:09

spacifici


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();
     }
 });
like image 36
Piovezan Avatar answered Sep 22 '22 10:09

Piovezan