1

My goal is to add a number of buttons (in a 4 column grid) to a RelativeLayout depending on how many "items" are in the database. When I was first learning how to add buttons to a RelativeLayout I just created 6 static buttons and added them the following way (ItemButton is simple class that extends Button):

private void loadItemButtons2(){
    itemButtonLayout = (RelativeLayout)findViewById(R.id.itemButtonLayout);
    itemButtonLayout.removeAllViews();
    ArrayList<Item> items = db.getAllActiveItems();
    ItemButton b1, b2, b3, b4, b5, b6;
    b1 = new ItemButton(this, items.get(0));
    b2 = new ItemButton(this, items.get(1));
    b3 = new ItemButton(this, items.get(2));
    b4 = new ItemButton(this, items.get(3));
    b5 = new ItemButton(this, items.get(4));
    b6 = new ItemButton(this, items.get(5));

    RelativeLayout.LayoutParams params1 = (RelativeLayout.LayoutParams)b1.getLayoutParams();
    params1.addRule(RelativeLayout.ALIGN_PARENT_START);
    b1.setId(111);
    b1.setLayoutParams(params1);

    RelativeLayout.LayoutParams params2 = (RelativeLayout.LayoutParams)b2.getLayoutParams();
    params2.addRule(RelativeLayout.RIGHT_OF, 111);
    b2.setId(222);
    b2.setLayoutParams(params2);

    RelativeLayout.LayoutParams params3 = (RelativeLayout.LayoutParams)b3.getLayoutParams();
    params3.addRule(RelativeLayout.RIGHT_OF, 222);
    b3.setId(333);
    b3.setLayoutParams(params3);

    RelativeLayout.LayoutParams params4 = (RelativeLayout.LayoutParams)b4.getLayoutParams();
    params4.addRule(RelativeLayout.RIGHT_OF, 333);
    b4.setId(444);
    b4.setLayoutParams(params4);

    RelativeLayout.LayoutParams params5 = (RelativeLayout.LayoutParams)b5.getLayoutParams();
    params5.addRule(RelativeLayout.ALIGN_PARENT_START);
    params5.addRule(RelativeLayout.BELOW, 111);
    b5.setId(555);
    b5.setLayoutParams(params5);

    RelativeLayout.LayoutParams params6 = (RelativeLayout.LayoutParams)b6.getLayoutParams();
    params6.addRule(RelativeLayout.RIGHT_OF, 555);
    params6.addRule(RelativeLayout.BELOW, 222);
    b6.setId(666);
    b6.setLayoutParams(params6);

    itemButtonLayout.addView(b1);
    itemButtonLayout.addView(b2);
    itemButtonLayout.addView(b3);
    itemButtonLayout.addView(b4);
    itemButtonLayout.addView(b5);
    itemButtonLayout.addView(b6);
}

And this gives me a perfect result:

enter image description here

But this is the dynamic solution I came up with, and to me it looks like it is doing the exact same thing but the results come out super wonky:

private void loadItemButtons(){
    itemButtonLayout = (RelativeLayout)findViewById(R.id.itemButtonLayout);
    itemButtonLayout.removeAllViews();
    ArrayList<Item> items = db.getAllActiveItems();
    int colCount = 0;
    int rowCount = 0;
    int i = 0;

    while(i < items.size()-1){
        ItemButton newItemButton = new ItemButton(this, items.get(i));
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)newItemButton.getLayoutParams();
        newItemButton.setId(i);

        if(colCount == 0){
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_START);
        }else if(colCount == 1){
            layoutParams.addRule(RelativeLayout.RIGHT_OF, i-1);
        }else if(colCount == 2){
            layoutParams.addRule(RelativeLayout.RIGHT_OF, i-1);
        }else if(colCount == 3){
            layoutParams.addRule(RelativeLayout.RIGHT_OF, i-1);
        }

        //If we are in any row except the top row, place in reference to the button above it
        if(rowCount != 0){
            layoutParams.addRule(RelativeLayout.BELOW, i-4);
        }

        newItemButton.setLayoutParams(layoutParams);
        itemButtonLayout.addView(newItemButton);

        if(colCount == 3){
            colCount = 0;
            rowCount += 1;
        }else{
            colCount += 1;
        }

        i++;
    }
}

enter image description here

Is anyone able to see what I am doing incorrectly or different from the first example??? Any advice is much appreciated!

5
  • Maybe you could simply change the visibility of existing buttons. Much easier. Commented Mar 25, 2015 at 20:52
  • 2
    Is there any reason not to use GridView and having your layout in xml? Commented Mar 25, 2015 at 21:00
  • @DerGolem - I believe that would require a set amount of buttons and the number of items can always be changing which is why I need a dynamic solution. Commented Mar 25, 2015 at 21:10
  • @Lamorak - I could possibly use that instead, but this solution should work just fine considering example one is exactly what I want....just need to understand why it's not working dynamically. Commented Mar 25, 2015 at 21:12
  • @BenKrueger newItemButton.getLayoutParams() will return Null value, since newItemButton is not yet attached to the Parent, I don't know how you are getting results? Commented Mar 25, 2015 at 22:37

2 Answers 2

2

The reason this is failing for you is because of the IDs you are using. Android uses "reserved" ids for things like the general content area of the app.

Using your code, I was able to add 1000 to each ID and generate the intended result.

Do note my cleanup below:

private void loadItemButtons(){
    itemButtonLayout = (RelativeLayout)findViewById(R.id.itemButtonLayout);
    itemButtonLayout.removeAllViews();
    List<String> items = itemList;
    int colCount = 0;
    int rowCount = 0;

    // # of items per column
    int colSpan = 4;

    final int itemListSize = itemList.size();
    for (int i = 0; i < itemListSize; i++) {
        int id = 1000 + i;
        ItemButton newItemButton = new ItemButton(this, items.get(i));
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        newItemButton.setId(id);

        if(colCount == 0)
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_START);
        else
            layoutParams.addRule(RelativeLayout.RIGHT_OF, id-1);


        //If we are in any row except the top row, place in reference to the button above it
        if(rowCount != 0)
            layoutParams.addRule(RelativeLayout.BELOW, id-colSpan);

        newItemButton.setLayoutParams(layoutParams);
        itemButtonLayout.addView(newItemButton);

        if(colCount == colSpan - 1)
            rowCount += 1;

        colCount = (colCount + 1) % colSpan;
    }
}

Also, as mentioned in my comment on the original post, you really should use a gridview for this, it's what it was built for.

I can dig a hole with a pitchfork, but I bet a shovel would work better.

My Result

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

1 Comment

Thank you Alex this is now working. I was using RelativeLayout because I am way more familiar with it than GridView but you are right I should learn how to use it for situations like this. Thanks again!
0

I didn't test the code:

private void loadItemButtons(){
    itemButtonLayout = (RelativeLayout)findViewById(R.id.itemButtonLayout);
    itemButtonLayout.removeAllViews();
    ArrayList<Item> items = db.getAllActiveItems();
    int colCount = 0;
    int rowCount = 0;
    int i = 0;

    while(i < items.size())
   {
        ItemButton newItemButton = new ItemButton(this, items.get(i));
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)newItemButton.getLayoutParams();
        newItemButton.setId(i);

        if(colCount == 0)
            layoutParams.addRule(RelativeLayout.ALIGN_PARENT_START);
        else 
            layoutParams.addRule(RelativeLayout.RIGHT_OF, i-1);


        //If we are in any row except the top row, place in reference to the button above it
        if(rowCount != 0){
            layoutParams.addRule(RelativeLayout.BELOW, i-4);
        }

        itemButtonLayout.addView(newItemButton, i, layoutParams);

        if(colCount == 3){
            colCount = 0;
            rowCount += 1;
        }else{
            colCount += 1;
        }

        i++;
    }
}

Comments

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.