2012-08-12 47 views
0

我得到这个错误,但我不知道确切原因:为什么我需要调用removeView(),以便于查看添加到我的LinearLayout

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

,我添加了查看的部分是错误指向的行。我正在提供适配器代码,以便让您更好地了解我在做什么以及为什么会出现此错误。请让我知道是否需要更多的信息。提前致谢。

适配器

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> 

回答

4

当你拿到那个异常(应用程序启动时或当您滚动GridView上下)你没有说,但这是正常的。 views数组有一个值不是null(该数组中的第一个条目设置为您创建的TextView),并且很可能您会尝试在某个点重新添加TextView。此外,父母AdapterView可能会多次调用getView方法来让一些孩子进行测量。

无论如何,你不知道你想要做什么,但目前的做法是错误的。

首先,你创建一个数组,其中一个TextView和其余的值设置为null,你基本上不会做任何事情(但也许这不是完整的代码?!)。其次,你不应该在(比如GridViewListView等)的儿童中存储一个Views的数组,这个数组有一个回收其子女的机制。第三,你没有考虑到GridView的回收机制。例如,您为第一个元素添加TextView,但您不会在getView中恢复此更改,因此如果第一行的View(其中包含添加的TextView)被循环使用,则最终将包含之前添加的行ViewTextView在你不需要的行上。

+0

你不知道我有多爱你现在lmao。你清理了很多,我不知道GridView和ListView!首先,我甚至不知道有一个回收机制,这就解释了为什么我一直在收到重复的TextView问题!我很欣赏你的直率,多数民众赞成我的学习。至于我用1 TextView做什么,它只是一个测试,看它是否有效,可惜它没有。所以这是我的完整代码,但它不会。但是当'onCreate'运行时我会得到异常。所以我从来没有机会看到任何东西。 – Andy 2012-08-12 06:42:03

+0

虽然我很困惑。你说我在添加'TextView'时不会恢复'getView'中的变化,我不认为我必须这样做。你能否解释一下,或者如果它更方便给我一个好的解释的链接。它非常明显,现在我需要了解更多关于ListView和GridView,因为我显然不知道足够的-_-我看过文档,我从来没有看到他们如何回收视图,所以我很抱歉没有知道。 – Andy 2012-08-12 06:47:53

+0

@Andy我不想变钝(只有一些建议)。只是出于好奇,在'getView()'方法中放入了一个日志条目,看看它是否被多次调用(我认为这就是为什么你在应用程序开始时得到异常的原因,'GridView'试图衡量它的孩子)。关于'TextView',如果你解释你想做什么,也许我可以推荐你另一种解决方案。关于回收机制,请参阅此链接http://www.vogella.com/articles/AndroidListView/article.html#adapterperformance – Luksprog 2012-08-12 07:00:00

1

我已经接受了一个答案,但我想补充一点,因为它可以帮助解释一些关于ListView(以及定义,GridView)的东西,知道有人了解它。我对ListView中的Views意见感到困惑,我发现this文章很棒。很好的解释。希望它可以帮助没有完全理解ListView和Adapters如何工作的人,这对我来说是一个显而易见的问题。