简体   繁体   English

将视图添加到LinearLayout Android

[英]Adding Views to a LinearLayout Android

I have Vertical ScrollView where I am going to add some Views after a buttonClick. 我有Vertical ScrollView,在buttonClick之后要在其中添加一些视图。 Here is the xml of the scroll view 这是滚动视图的xml

<ScrollView
    android:background = "@drawable/border"
    android:layout_weight="31"
    android:id="@+id/scrollView1"
    android:layout_width="match_parent"
    android:layout_height="0dp" >

    <LinearLayout
        android:id="@+id/layoutScroll"
        android:padding = "10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >






        <LinearLayout
            android:id="@+id/layoutContainer"
            android:padding="5dp"
            android:orientation="vertical"
            android:background="@drawable/border_2"
            android:layout_width="fill_parent"
            android:layout_height = "wrap_content">

            <RelativeLayout
                android:id="@+id/relativeLayout"
                android:layout_height = "wrap_content"
                android:layout_width = "fill_parent">
                <TextView
                    android:id="@+id/textWord"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/word"
                    android:textAppearance="?android:attr/textAppearanceMedium" />

                <TextView
                    android:id="@+id/textNumber"
                    android:background = "@drawable/border_1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentTop="true"
                    android:text=" 1 "
                    android:textAppearance="?android:attr/textAppearanceMedium" />

            </RelativeLayout>

            <EditText 
                android:id="@+id/editWord"
                android:layout_marginTop="3dp"
                android:layout_gravity="left"
                android:inputType="text"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:lines="1"
                android:scrollbars="horizontal"/>
            <TextView 
                android:id="@+id/textDefinition"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text = "@string/definition" />
            <EditText 
                android:id="@+id/editDefinition"
                android:gravity="top|left"
                android:inputType="textMultiLine"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:lines="3"
                android:maxLines="3"
                android:scrollbars="vertical"/>               
        </LinearLayout>
        <TextView
            android:id="@+id/textEmpty"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:lines="1"
            android:textAppearance="?android:attr/textAppearanceMedium" />





    </LinearLayout>
</ScrollView>

In this function I create the same objects for adding them to the LinearLayout 在此函数中,我创建了相同的对象以将它们添加到LinearLayout

private void initInterface (){
    layoutScroll = (LinearLayout) findViewById (R.id.layoutScroll);
    layoutContainer = new LinearLayout(getApplicationContext());
    relativeLayout = new RelativeLayout(getApplicationContext());

    textWord = new TextView(getApplicationContext());
    textDefinition= new TextView(getApplicationContext());
    textNumber = new TextView(getApplicationContext());
    textEmpty = new TextView(getApplicationContext());

    editWord = new EditText(getApplicationContext());
    editDefinition = new EditText(getApplicationContext());


    layoutContainer.setPadding(5, 5, 5, 5);
    layoutContainer.setOrientation(LinearLayout.VERTICAL);
    layoutContainer.setBackgroundResource(R.drawable.border_2);
    LinearLayout.LayoutParams param1 = 
            new LayoutParams(LayoutParams.MATCH_PARENT , LayoutParams.WRAP_CONTENT );
    layoutContainer.setLayoutParams(param1);


    RelativeLayout.LayoutParams param2 = 
            new RelativeLayout.LayoutParams (RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    relativeLayout.setLayoutParams(param2);
    textWord.setLayoutParams(param2);
    textWord.setTextAppearance(this,android.R.style.TextAppearance_Medium);
    textWord.setText("Word:");

    RelativeLayout.LayoutParams param3= 
            new RelativeLayout.LayoutParams 
            (RelativeLayout.LayoutParams.WRAP_CONTENT, 
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
    param3.addRule(RelativeLayout.ALIGN_PARENT_TOP);
    param3.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    textNumber.setBackgroundResource(R.drawable.border_1);
    textNumber.setTextAppearance(this,android.R.style.TextAppearance_Medium);
    textNumber.setLayoutParams(param3);

    relativeLayout.addView(textWord);
    relativeLayout.addView(textNumber);


    LinearLayout.LayoutParams param4 = param1;
    param4.setMargins(0, 3, 0, 0);
    editWord.setGravity(Gravity.LEFT);
    editWord.setTextAppearance(this,android.R.style.TextAppearance_Medium);
    editWord.setLines(1);
    editWord.setHorizontallyScrolling(true);
    editWord.setLayoutParams(param4);


    textDefinition.setLayoutParams(param1);
    textDefinition.setTextAppearance(this,android.R.style.TextAppearance_Medium);
    textDefinition.setText("Definition:");

    editDefinition.setGravity(Gravity.TOP | Gravity.LEFT);
    editDefinition.setSingleLine(false);
    editDefinition.setLayoutParams(param1);
    editDefinition.setMaxLines(3);
    editDefinition.setLines(3);
    editDefinition.setVerticalScrollBarEnabled(true);
    editDefinition.setImeOptions(EditorInfo.IME_FLAG_NO_ENTER_ACTION);

    textEmpty.setTextAppearance(this,android.R.style.TextAppearance_Medium);
    textEmpty.setLines(1);
    textEmpty.setLayoutParams(param1);

    layoutContainer.addView(relativeLayout);
    layoutContainer.addView(editWord);
    layoutContainer.addView(textDefinition);
    layoutContainer.addView(editDefinition);




}

And then I add them to the Layout like this. 然后像这样将它们添加到布局中。

public void onCLick_Add(View v){
    layoutScroll.addView(layoutContainer);
    layoutScroll.addView(textEmpty);

}

The problem is that It only workd once . 问题是它只能工作一次。 When I click the button for the second time the app crashes. 当我第二次单击按钮时,应用程序崩溃。 Thank you in advance. 先感谢您。

Your log says: 您的日志显示:

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

You are trying to add same layoutContainer and textEmpty multiple times when clicking multiple times. 您试图在单击多次时多次添加相同的layoutContainer和textEmpty。 This fails because they are already added and therefore already have a parent. 之所以失败,是因为它们已经被添加,因此已经有一个父级。 (You cannot add same View to more then one parent) (您不能将同一视图添加到一个以上的父级中)

Solution I guess you want to create a new View every time you press the button and add this to your layoutScroll. 解决方案我想您想在每次按下按钮时创建一个新视图并将其添加到layoutScroll中。 You should call your init-method again for every click: 您应该为每次点击再次调用初始化方法:

public void onCLick_Add(View v){
  initInterface();
  layoutScroll.addView(layoutContainer);
  layoutScroll.addView(textEmpty);
}

I would also suggest to divide initInterface() into: 我也建议将initInterface()分为:

private View createLayoutContainer();
private View createTextEmpty();

Make sure you take initialization of scrollView outside (eg onCreate) and you declare views like layoutContainer localy in the createLayoutContainer() instead of globally. 确保在外部(例如onCreate)进行scrollView的初始化,并在createLayoutContainer()中而不是在全局中声明诸如layoutContainer的局部视图。

Here a snippet how it would look: 这是一个片段的外观:

private View createLayoutContainer(){
  LinearLayout layoutContainer = new LinearLayout(getApplicationContext());
  RelativeLayout relativeLayout = new RelativeLayout(getApplicationContext());

  TextView textWord = new TextView(getApplicationContext());
  ...
  return layoutContainer;
}

public void onCLick_Add(View v){
  layoutScroll.addView(createLayoutContainer());
  layoutScroll.addView(createTextEmptyView());
}

The problem occurs due to the fact that a ScrollView can only have on child View. 出现此问题的原因是ScrollView只能在子View上使用。 In other words, a ScrollView can have a LinearLayout or a RelativeLayout or a TextView etc. Update your code such that new views inside are added inside LinearLayout ( layoutScroll ) instead of ScrollView . 换句话说, ScrollView可以具有LinearLayoutRelativeLayoutTextView等。更新代码,以便将内部的新视图添加到LinearLayoutlayoutScroll )而不是ScrollView

As I pointed out in the comment, the bug is this : Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 正如我在评论中指出的那样,该错误是这样的: Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

Checklist for these kind of bugs. 这些错误的清单。

As pointed out in this post the specified child already has a parent 如这篇文章所指出的,指定的孩子已经有一个父母

Double check all your addView calls. 仔细检查所有的addView调用。

  • Make sure not to add any view more then once. 确保不要再添加任何视图。 When a View is allready used (eg, you got it with findViewById, don't use addView on it. 当一个View已经准备好使用时(例如,您将它与findViewById一起使用时,请勿在其上使用addView。

  • When you want to add a view, use addView with a NEW view. 当您要添加视图时,请将addView与新视图一起使用。 You can add several of these new views to one view, but you cannot add that one view multiple times. 您可以将多个新视图添加到一个视图,但是不能多次添加该视图。

  • You can't re-use a view simply by changing some stuff. 您不能仅通过更改某些内容来重用视图。 You CAN re-use a variable, but you need to make a new view if you want to re-add it using addView. 您可以重新使用变量,但是如果要使用addView重新添加变量,则需要创建一个新视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM