2015-05-13 3 views
-3

Я попытался найти примеры этой проблемы, но не могу найти ничего подходящего.Добавление динамически сгенерированных кнопок рядом друг с другом в 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)

Вот код вида деятельности:

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 или Adapters?

(Примечание: Я пытался найти родитель кнопки, но это нуль)

+1

вы добавляете ту же кнопку дважды ... (переборе '' buttons' внутри buttons's' итерации - вы даже понять код?) – Selvin

ответ

1

Это прекрасно работает на основе наш частный чат, удачи в стилизации.

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

Вы добавление кнопок в два раза для каждой кнопки. Когда-то здесь ->

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

и один раз в методе newAddButtonToLayout(). Так что я думаю, вы должны Transfor этот метод:

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

Но разве это не помещало бы одну кнопку в каждый макет? – Mowinckel

+0

Да, это будет, но это тоже делает ваш код - строки (LinearLayouts) с помощью одной кнопки –

+0

Я вижу. У вас есть идея, как сделать строку с двумя кнопками, новая строка с двумя кнопками. – Mowinckel

0

положить в вашем 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> 

и положить в классе способ и назвать его в 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); 
     } 
    } 

я надеюсь это поможет, кнопки будут нарисованы динамически, а щелчок будет подсвечен.

+1

Я не совсем понимаю, как это можно интегрировать в мои переменные, и вся часть изображения кажется очень произвольной, но я пытаюсь ее реализовать. – Mowinckel

+1

Я попытался реализовать, но, кажется, просто добавляет кнопки навсегда справа, никогда не переходя к новой строке. – Mowinckel

+0

вы хотите их каждый подряд? если да, то просто измените «android: orientation =« horizontal »to to android: orientation =« vertical »' –

0

Вы можете использовать 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> 

в деятельности

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


    } 
Смежные вопросы