Why do I need to call removeView() in order to add a View to my LinearLayout

我是研究僧i 提交于 2019-12-08 13:41:32

问题


I am getting this error but I am not sure exactly why:

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

The part where I add the View is the line that the error is pointing to. I am providing my Adapter code in order for you guys to get a better picture of what I am doing and why I am getting this error. Please let me know if anymore info is needed. Thanks in advance.

Adapter

private class InnerAdapter extends BaseAdapter{
    String[] array = new String[] {"12\nAM","1\nAM", "2\nAM", "3\nAM", "4\nAM", "5\nAM", 
                                "6\nAM", "7\nAM", "8\nAM", "9\nAM", "10\nAM", "11\nAM",
                                "12\nPM", "1\nPM", "2\nPM", "3\nPM", "4\nPM", "5\nPM",
                                "6\nPM", "7\nPM", "8\nPM", "9\nPM", "10\nPM", "11\nPM"};
    TextView[] views = new TextView[24];

    public InnerAdapter() {
        TextView create = new TextView(DayViewActivity.this);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 62, getResources().getDisplayMetrics()), 1.0f);
        params.topMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
        params.bottomMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
        create.setLayoutParams(params);
        create.setBackgroundColor(Color.BLUE);
        create.setText("Test");
        views[0] = create;
        for(int i = 1; i < views.length; i++) {
            views[i] = null;
        }
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return array.length;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            convertView = inflater.inflate(R.layout.day_view_item, parent, false);
        }

        ((TextView)convertView.findViewById(R.id.day_hour_side)).setText(array[position]);
        LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.day_event_layout);
        if(views[position] != null) {
            layout.addView((TextView)views[position], position);
        }

        return convertView;
    }

}

XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="61dp"
    android:orientation="horizontal" >



    <LinearLayout 
        android:layout_width="wrap_content"
        android:layout_height="61dp"
        android:orientation="vertical">
        <TextView 
            android:id="@+id/day_hour_side"
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:text="12AM"
            android:background="#bebebe"
            android:layout_weight="0"
            android:textSize="10dp"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"/>
        <TextView 
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_weight="0"
            android:background="#000000"
            android:id="@+id/hour_side_divider"/>
    </LinearLayout>
    <LinearLayout 
        android:layout_width="0dp"
        android:layout_height="61dp"
        android:orientation="vertical"
        android:layout_weight="1">
        <LinearLayout 
            android:id="@+id/day_event_layout"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:orientation="horizontal" ></LinearLayout>
        <TextView 
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#000000"
            android:id="@+id/event_side_divider" />
    </LinearLayout>


</LinearLayout>

回答1:


You didn't say when you get that exception(when the application starts or when you scroll the GridView up and down) but it's normal. The views array has one value that is not null(the first entry in that array in set to the TextView that you create) and most likely you'll be trying to re-add that TextView at some point. Also the parent AdapterView may call the getView method several times to get some children to measure.

Anyway you don't know exactly what you're trying to do but the current approach is wrong.

First, you create an array with one TextView and the rest of the values set to null and you basically don't do anything else with it(but maybe this isn't the full code?!). Second, you shouldn't store an array of Views especially within a child of AdapterView(like GridView, ListView etc) which has a mechanism to recycle its children. Third, you didn't take in consideration the recycling mechanism of the GridView. For example, you add the TextView for the first element but you don't revert this changes in the getView so if this first row's View(which contains the added TextView) gets recycled you'll end up with a row View containing the previously added TextView at rows where you don't want it.




回答2:


I already accepted an answer, but thought I'd add this as it helps explain some stuff about ListView (and by definition, GridView as well), that someone learning about it can understand. I was confused about recycling Views in ListView, and this article I found is great. Explains it well. Hopefully it helps anyone not fully understanding how ListView and Adapters work, which was an obvious problem for me.



来源:https://stackoverflow.com/questions/11919033/why-do-i-need-to-call-removeview-in-order-to-add-a-view-to-my-linearlayout

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