Dynamically adding a button to RelativeLayout not working correctly

爱⌒轻易说出口 提交于 2019-12-24 14:24:02

问题


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:

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

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


回答1:


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.




回答2:


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


来源:https://stackoverflow.com/questions/29266184/dynamically-adding-a-button-to-relativelayout-not-working-correctly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!