Zarwan
Zarwan

Reputation: 5797

Adding Android buttons to view dynamically

I have already looked at the following questions and a bunch of other ones: How to add a button dynamically in Android?

Dynamically Creating/Removing Buttons in Android

I have 2 activities with a fragment. Each time the user presses a button on the second activity they get redirected to the main activity and a button is added to the page. Even though the buttons are being saved properly in MainActivity in an array only the most recent one is shown on the layout, but it is being pushed downward as if the other ones are above it.

In MainActivity:

private static List<Button> ideas = new ArrayList<Button>();
private static SharedPreferences sharedPref;
private Context myContext;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    RelativeLayout layout = new RelativeLayout(this);
    setContentView(layout, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
    Intent intent = getIntent();

    Button newIdea = new Button(this);
    newIdea.setText("NEW IDEA");
    newIdea.setTranslationX(300);
    newIdea.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(v.getContext(), NewIdeaPageActivity.class);
            startActivity(intent);
        }
    });
    layout.addView(newIdea);


    if (intent != null) {
        if (intent.hasExtra("title")) {
            Button button = new Button(this);
            button.setId(ideas.size());
            button.setText(getIntent().getStringExtra("title"));
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

            if (ideas.size() == 0) {
                params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
            } else {
                params.addRule(RelativeLayout.BELOW, ideas.size() - 1);
            }
            layout.addView(button, params);
            ideas.add(button);
        }
    }
}

MainActivity xml:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/fragment"
    android:name="com.zarwanhashem.ideatrackr.MainActivityFragment"
    tools:layout="@layout/fragment_main" android:layout_width="match_parent"
    android:layout_height="match_parent" />

MainActivity fragment xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivityFragment"
    android:id="@+id/fragment_main_layout">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Idea"
        android:id="@+id/new_idea_button"
        android:onClick="onNewIdeaButtonClicked"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>

The new idea button takes them to the second activity where they create the button which is added to the main activity. Any idea why only the most recent button is actually displayed? All the buttons show up in the ideas array when I debug.

Upvotes: 0

Views: 449

Answers (2)

ElDuderino
ElDuderino

Reputation: 3263

You have a RelativeLayout as parent. That means, you have to tell the children where they should be, and you do that with e.g.

android:layout_alignParentTop

as you do in your xml. (btw some of those aligns cancel themselves out)

Read http://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams.html

You will find, there is also

android:layout_below

which needs an ID.

What you have to do, is give your generated buttons an ID, that can be a number. Then you have to add a rule to your RelativeLayout layoutparams.

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT)
params.addRule(RelativeLayout.BELOW, IDofPreviousButtonComesInHere);

And remove those setTranslations().

But, as said, have a look into ListView (or new RecyclerView).

If you have a look at tutorials, don't do that on http://developer.android.com/guide/topics/ui/layout/listview.html, no good start. Try this http://windrealm.org/tutorials/android/android-listview.php. Just exchange the planets array with your ideas array and the textview xml with a button. And it should work.

Edit:

Try this, it works.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    RelativeLayout layout = new RelativeLayout(this);
    setContentView(layout, new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));



    for(int i = 0; i<10; i++) {

        Button button = new Button(this);
        int id = i+1000;
        button.setId(id);
        button.setText("Button " + i);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        if(i==0) {
            params.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        } else {
            params.addRule(RelativeLayout.BELOW, id-1);
        }
        layout.addView(button, params);

    }
}

Upvotes: 1

Joel Duggan
Joel Duggan

Reputation: 215

Every time onCreate() is called, specifically when setContentView() is called, your entire layout is wiped clean and loaded with R.layout.activity_main.

The reason that you only see the most recent button, is because you are only adding at most one button inside of onCreate(). The button's position is offset because you are calculating its y position based on the number of buttons in your ideas array.

I would do something like this:

if (intent != null) {
     if (intent.hasExtra("title")) {
        ideas.add(new Button(myContext));
        ideas.get(ideas.size() - 1).setLayoutParams(new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT));
        ideas.get(ideas.size() - 1).setTranslationY(ideas.size() * 100 + 100);
        ideas.get(ideas.size() - 1).setText(intent.getStringExtra("title"));
    }
}

// add all the buttons to the layout hierarchy
for (Button b : ideas) {
    layout.addView(b);
}

Upvotes: 0

Related Questions