在 LinearLayout 中彼此相邻添加动态生成的按钮

Adding dynamically generated buttons next to each other in LinearLayout

我已尝试查找此问题的示例,但找不到合适的示例。

我想要的是两个彼此相邻的按钮,来自自动生成的按钮列表。方法 newAddButtonToLayout 是我尝试做的东西。 我在 运行 时收到此错误:

Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

row.addView(button)

这里是activity代码:

package com.code.p2_project.finalevaluationapp;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import java.util.ArrayList;


public class ExerciseList extends Activity implements View.OnClickListener {

private ArrayList<Exercise> list = new ArrayList<Exercise>();
//This array holds the exercises
private ArrayList<Button> buttons = new ArrayList<Button>();
//This array holds the buttons
private ArrayList<Exercise> exercises = new ArrayList<Exercise>();//store them in ArrayList called exercises
private CategoryTypes categoryType;
private  TangibleTypes tangibleType;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_exercise_list);
    LinearLayout relativeLayout = (LinearLayout) findViewById(R.id.exerciseLayout); //The layout used to put the buttons in

    Intent intent = getIntent();
    categoryType = CategoryTypes.valueOf(intent.getStringExtra("categoyType"));
    tangibleType = TangibleTypes.valueOf(intent.getStringExtra("tangibleType"));
    System.out.println("Category sent was: "+categoryType);
    System.out.println("Tangible sent was: "+tangibleType);

    //Contruction and putting the objects into the aforementioned Exercise Array
    //TODO: Add this to the aforementioned method

    /*for (int i = 0; i <= 200; i++)
    {
        list.add(new Exercise("Exercise "+i, CategoryTypes.MOBILITY, TangibleTypes.CHAIR, "Lav sværhedsgrad",R.string.flexChair,this));
    }*/

    //Add BALANCE exercises here
    list.add(new Exercise("Øvelse 1",CategoryTypes.BALANCE, TangibleTypes.CHAIR,"Lav sværhedsgrad",R.string.flexChair,this));
    list.add(new Exercise("Øvelse 5",CategoryTypes.BALANCE, TangibleTypes.TABLE,"Mellem sværhedsgrad",R.string.flexChair,this));
    list.add(new Exercise("Øvelse 1",CategoryTypes.BALANCE, TangibleTypes.CHAIR,"Lav sværhedsgrad",R.string.flexChair,this));

    //Add STRENGTH exercises here
    list.add(new Exercise("Øvelse 2",CategoryTypes.STRENGTH, TangibleTypes.BAND,"Mellem sværhedsgrad",R.string.flexChair,this));
    list.add(new Exercise("Øvelse 2",CategoryTypes.STRENGTH, TangibleTypes.BAND,"Mellem sværhedsgrad",R.string.flexChair,this));
    list.add(new Exercise("Øvelse 2",CategoryTypes.STRENGTH, TangibleTypes.BAND,"Mellem sværhedsgrad",R.string.flexChair,this));

    //Add Mobility exercises here
    list.add(new Exercise("Øvelse 3",CategoryTypes.MOBILITY, TangibleTypes.NOTHING,"Høj sværhedsgrad",R.string.flexChair,this));
    list.add(new Exercise("Øvelse 6",CategoryTypes.MOBILITY,TangibleTypes.CHAIR,"Lav sværhedsgrad",R.string.flexChair,this));
    list.add(new Exercise("Øvelse 3",CategoryTypes.MOBILITY, TangibleTypes.NOTHING,"Høj sværhedsgrad",R.string.flexChair,this));

    //Add CARDIO exercises here
    list.add(new Exercise("Øvelse 4",CategoryTypes.CARDIO, TangibleTypes.TABLE,"Høj sværhedsgrad",R.string.flexChair,this));
    list.add(new Exercise("Øvelse 4",CategoryTypes.CARDIO, TangibleTypes.TABLE,"Høj sværhedsgrad",R.string.flexChair,this));
    list.add(new Exercise("Øvelse 4",CategoryTypes.CARDIO, TangibleTypes.TABLE,"Høj sværhedsgrad",R.string.flexChair,this));




    exercises = filterExercises(categoryType,tangibleType);

    //Creating the buttons depending on the size of the list
    // and setting the names to the list names
    for (int i = 0; i < exercises.size(); i++)
    {
        MainActivity.makeButton(this, this, exercises.get(i).getExerciseName(), buttons, exercises.get(i).getColor(), i);

    }
    //Adding buttons to the layout and deleting the "wrong" buttons
    for (int i = 0; i < buttons.size(); i++)
    {
        newAddButtonToLayout(buttons.get(i), relativeLayout, this, i);
    }

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_exercise_list, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

//CategoryTypes categories = CategoryTypes.values()[which];

private ArrayList<Exercise> filterExercises (CategoryTypes categoryType, TangibleTypes tangibleType)
{
    for (Exercise exercise : this.list) {
        System.out.println("exercise"+exercise.toString());
        if (exercise.isCategoryType(categoryType) && exercise.isTangibleType(tangibleType)) {
            System.out.println("match");
            exercises.add(exercise);
        }
        else if (categoryType == CategoryTypes.ALL && tangibleType == TangibleTypes.ALL)
        {
            exercises.add(exercise);
        }
        else if (categoryType == CategoryTypes.ALL && exercise.isTangibleType(tangibleType))
        {
            exercises.add(exercise);
        }
        else if (exercise.isCategoryType(categoryType) && tangibleType == TangibleTypes.ALL)
        {
            exercises.add(exercise);
        }
    }
    return exercises;
}

public void sendWithData(int index)
{
    Intent sendToClass = new Intent (this, ExerciseView.class);
    sendToClass.putExtra("exerciseTitle",buttons.get(index).getText());
    sendToClass.putExtra("difficulty",exercises.get(index).getDifficulty());
    sendToClass.putExtra("description",R.string.flexChair);
    startActivity(sendToClass);
}


@Override
public void onClick(View view)
{
    for (int i = 0; i < exercises.size(); i++) {
        if (view.getId() == i) {
            String buttonName = exercises.get(i).getExerciseName();
            switch (buttonName) {
                case "Øvelse 1":
                    sendWithData(i);
                    break;
                case "Øvelse 2": sendWithData(i);
                    break;
                case "Øvelse 3":
                    sendWithData(i);
                    break;
                case "Øvelse 4": sendWithData(i);
                    break;
                case "Øvelse 5":
                    sendWithData(i);
                    break;
                case "Øvelse 6": sendWithData(i);
                    break;
            }
        }
    }
}



public void newAddButtonToLayout (Button button, LinearLayout layout, Context context, int index)
{
    int counter = 0;        

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    params.weight = 1.0f;
    params.setMargins(0,20,0,20);

    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    layoutParams.gravity = Gravity.RIGHT;

    ArrayList<LinearLayout> rows = new ArrayList<LinearLayout>();

    for (int i = 0; i < buttons.size(); i++)
    {
        if (counter == buttons.get(i).getId())
        {
            LinearLayout row = new LinearLayout(context);
            row.setId(1000 + i);

            row.setLayoutParams(layoutParams);
            button.setLayoutParams(params);

            row.addView(button);
            layout.addView(row);

            counter += 2;

            rows.add(row);
        }
    }
    for (int i = 0; i < rows.size(); i++)
    {
        layout.addView(rows.get(i));
        System.out.println("Button's parent is: "+button.getParent());
    }

}

}

以及静态引用的 makeButtons

public static void makeButton (Context context, View.OnClickListener view, String buttonText, ArrayList<Button> buttons, int colour, int id)
{
    Typeface tf = Typeface.createFromAsset(context.getAssets(),"fonts/RobotoSlab-Regular.ttf");
    Typeface tfBold = Typeface.createFromAsset(context.getAssets(),"fonts/RobotoSlab-Bold.ttf");

    Button button = new Button(context);
    button.setText(buttonText);
    button.setId(id);
    button.setOnClickListener(view);
    button.setBackgroundColor(colour);
    button.setPadding(0, 20, 0, 20);
    button.setTextSize(25);
    button.setTypeface(tfBold);

    buttons.add(button);
    System.out.println(button.getId());
}

如何在视图中添加 2 个按钮并将其添加到按钮 ArrayList 中的任意数量的按钮?不使用 ListView 或适配器?

(注意:我试过找到按钮的父级,但它是空的)

您为每个按钮添加了两次按钮。到达这里 ->

for (int i = 0; i < buttons.size(); i++)
{
    newAddButtonToLayout(buttons.get(i), relativeLayout, this, i);
}

并且在您的 newAddButtonToLayout() 方法中一次。所以我认为你应该将这个方法转换为:

public void newAddButtonToLayout (Button button, LinearLayout layout, Context context){   
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
    params.weight = 1.0f;
    params.setMargins(0,20,0,20);

    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.WRAP_CONTENT);
    layoutParams.gravity = Gravity.RIGHT;
    layout.setLayoutParams(layoutParams);
    button.setLayoutParams(params);
    layout.addView(button);
}

输入你的xml:

 <LinearLayout
                android:paddingTop="10dp"
                android:layout_width="fill_parent"
                android:layout_height="match_parent"
                android:orientation="horizontal"
                android:fillViewport="true"
                android:id="@+id/layoutInbox"
                android:background="#f4f3f8"></LinearLayout>

并在您的 class 中放入一个方法并在 OnCreate

中调用它
private void buildInboxItems() {
final LinearLayout inboxLayout = (LinearLayout) findViewById(R.id.layoutInbox);
            final String[] buttonsInfoList = new String[]{"image1#text1#1",
                    "image2#text2#2"};

        final List<Button> buttonsList = new ArrayList<Button>();
        for (int i = 0; i < buttonsInfoList.length; i++) {
            final Button customButton = new Button(this);

            customButton.setId(100 + i);

            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);

            if (i >= 0) {
                String image = buttonsInfoList[i];
                String[] parts = image.split("#");
                String imagePart = parts[0];
                String textPart = parts[1];
                final String tagPart = parts[2];

                Drawable img = GetImage(getApplicationContext(), imagePart);
                customButton.setTag(Integer.parseInt(tagPart));
                customButton.setCompoundDrawablesWithIntrinsicBounds(null, img, null, null);
                customButton.setBackgroundColor(Color.TRANSPARENT);
                customButton.setText(textPart);
                customButton.setTextColor(getResources().getColor(R.color.CustomGray));
                customButton.setLayoutParams(lp);
                final int index = i;
                final int[] buttonIdsList = new int[buttonsInfoList.length];
                buttonIdsList[i] = index;
                customButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        for (Button button : buttonsList) {
                            if (button.getId() == v.getId()) {
                                //  button.setBackgroundColor(Color.RED);
                                Drawable imgOn = GetImage(getApplicationContext(), "imageButtonClicked");
                                button.setTextColor(getResources().getColor(R.color.CustomOrange));
                                button.setCompoundDrawablesWithIntrinsicBounds(null, imgOn, null, null);

                            } else {
                                //  button.setBackgroundColor(Color.BLUE);

                                Drawable imgOff = GetImage(getApplicationContext(), "imageButtonNotClicked");
                                button.setTextColor(getResources().getColor(R.color.CustomGray));
                                button.setCompoundDrawablesWithIntrinsicBounds(null, imgOff, null, null);
                            }
                        }
                    }
                });
            }

//            setMargins(int left, int top, int right, int bottom)
            lp.setMargins(60, 5, 60, 5);
            lp.width = 120;
            lp.height = 150;
            inboxLayout.addView(customButton, lp);
            buttonsList.add(customButton);
        }
    }

我希望这会有所帮助,按钮是动态绘制的,点击的按钮会突出显示..

根据我们的私人聊天,这非常有效,祝你造型成功。

public void newAddButtonToLayout (Context context)
{
int counter = 1;

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        300);
params.weight = 1f;
params.setMargins(10,10,10,10);

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.MATCH_PARENT,
        LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.RIGHT;

ArrayList<LinearLayout> rows = new ArrayList<>();

for (int i = 0; i < buttons.size(); i++)
{
    if (counter == buttons.get(i).getId())
    {
        LinearLayout row = new LinearLayout(context);
        row.setId(1000 + i);

        row.setLayoutParams(layoutParams);

        if(i <= buttons.size()) {
            if(i == buttons.size()) {
                if(buttons.size() % 2 == 0) {
                    buttons.get(i - 1).setLayoutParams(params);
                    row.addView(buttons.get(i - 1));
                }
            } else {
                buttons.get(i - 1).setLayoutParams(params);
                row.addView(buttons.get(i - 1));
            }

        }

        buttons.get(i).setLayoutParams(params);
        row.addView(buttons.get(i));
        //relativeLayout.addView(buttons.get(i));



        relativeLayout.addView(row);



        counter += 2;

        System.out.println(buttons.get(i).getId() + " BUTTON HERE");

        //rows.add(row);

    }
    if(i == buttons.size()-1) {
        System.out.println("IT IS IN THE LOOP");
        if(buttons.size() % 2 != 0) {
            buttons.get(i).setLayoutParams(params);
            relativeLayout.addView(buttons.get(buttons.size()-1));
        }
    }
}

您可以使用 google flexboxlayout 动态添加按钮。

里面xml

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/thanks_bottom_background"
        android:orientation="vertical">

        <com.google.android.flexbox.FlexboxLayout
            android:id="@+id/mainRecepientLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="20dp"
            app:alignContent="flex_start"
            app:alignItems="flex_start"
            app:flexWrap="wrap" />
    </LinearLayout> 

里面activity

  private void addRecepientList(ArrayList<User> recipientsOfThanks, FlexboxLayout layoutRecepient)
        {
       for (int i = 0; i < recipientsOfThanks.size(); i++) {
          LinearLayout layout = new LinearLayout(getContext());
          LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);


          layout.setOrientation(LinearLayout.HORIZONTAL);
          layout.setPadding(0, 10, 0, 10);
          layout.setLayoutParams(params);
          Button userLabel = new Button(getContext());
          userLabel.setLayoutParams(params);
          userLabel.setPadding(0, 20, 0, 20);
          layout.addView(userLabel);
          layoutRecepient.addView(layout);


    }