0

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.

3
  • If you have multiple buttons you should consider a listview. It was made for these things. Commented Jun 21, 2015 at 0:50
  • @ElDuderino I am looking into this now. There seems to be a lot to it, is there not an easier way? What is wrong with my approach? Commented Jun 21, 2015 at 23:24
  • I just added some tips regarding a listview tutorial to my answer, Commented Jun 22, 2015 at 0:15

2 Answers 2

1

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);

    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I added those two lines in the if stmnt before I set the params and add it to the layout. I set the ID to ideas.size() using .setId(). The problem is still there though. I will try the ListView (thanks for the tut) but I'm wondering what is wrong with my current code.
I tried your code and it works but when I converted the concept to my code I ran into the same problem. I updated my MainActivity code to show you what I did. I'm not using the fragment right now, so I remade the new idea button in onCreate as well.
Do it like I did with an ID+X, like 1000 in my case as 0 is not a valid id, as you can read here developer.android.com/reference/android/content/res/…. The newIdea button does nothing. You don't need settranslation.
I replaced all ideas.size() with ideas.size() + 1000 and there is no change. I need the newIdea button to take me to the other activity where I can make the buttons. Basically everytime I click the newIdea button and then click the return button on the other activity I pass a title in the intent which should be created with a new button whenever I come back to the MainAcitivity. It's translated as a temporary fix to it overlapping with the dynamically created buttons.
0

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);
}

1 Comment

I tried this. It gives me this error: "java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first", which I think means that I'm adding the same button to the view multiple times.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.