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.

Community
  • 1
  • 1
Zarwan
  • 5,537
  • 4
  • 30
  • 48

2 Answers2

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

    }
}
ElDuderino
  • 3,253
  • 2
  • 21
  • 38
  • 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. – Zarwan Jun 22 '15 at 02:22
  • 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. – Zarwan Jun 23 '15 at 00:09
  • 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 http://developer.android.com/reference/android/content/res/Resources.html#getIdentifier%28java.lang.String,%20java.lang.String,%20java.lang.String%29. The newIdea button does nothing. You don't need settranslation. – ElDuderino Jun 23 '15 at 08:15
  • 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. – Zarwan Jun 24 '15 at 00:24
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);
}
Joel Duggan
  • 215
  • 1
  • 7
  • 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. – Zarwan Jun 21 '15 at 23:25