向LinearLayout插入TextView时触发IndexOutOfBound异常求助
解决LinearLayout插入视图触发IndexOutOfBound异常的问题
嘿,我明白你在开发CalendarView多日事件功能时遇到的麻烦了——想直接往LinearLayout的位置2插TextView,但因为前面0、1位置还没视图,直接触发了索引越界异常对吧?
问题根源
其实LinearLayout的addView(View child, int index)方法有个规则:你指定的索引必须在0到当前子视图数量(getChildCount())之间(包含两端)。当布局里还没有任何子视图时,getChildCount()是0,这时候只能插入到索引0的位置,硬插索引2肯定会报错。
具体解决办法
这里给你两种可行的思路,你可以根据自己的日历布局结构选:
1. 先补全前置位置的视图(或占位视图)
如果0、1位置是日历中前面几天的容器,那你需要先把这些位置的视图创建并添加进去,再插入目标视图:
// 先创建位置0的视图(比如第一天的容器) TextView day0View = new TextView(context); // 设置视图属性,比如日期文本、样式等 day0View.setText("1号"); linearLayout.addView(day0View); // 再创建位置1的视图(第二天的容器) TextView day1View = new TextView(context); day1View.setText("2号"); linearLayout.addView(day1View); // 现在就可以安全插入位置2的事件视图了 TextView tv = new TextView(context); tv.setBackgroundResource(R.drawable.event_view); int height = context.getResources().getDimensionPixelSize(R.dimen.event_image_size); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, height ); linearLayout.addView(tv, 2, params);
如果0、1位置暂时不需要显示内容,只是为了占位保证索引合法,可以用透明视图填充:
// 创建透明占位视图填充位置0 View placeholder0 = new View(context); placeholder0.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, 0 // 可根据布局需求调整高度 )); placeholder0.setBackgroundColor(Color.TRANSPARENT); linearLayout.addView(placeholder0); // 填充位置1 View placeholder1 = new View(context); placeholder1.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, 0 )); placeholder1.setBackgroundColor(Color.TRANSPARENT); linearLayout.addView(placeholder1); // 插入目标事件视图到位置2 TextView tv = new TextView(context); tv.setBackgroundResource(R.drawable.event_view); int height = context.getResources().getDimensionPixelSize(R.dimen.event_image_size); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, height ); linearLayout.addView(tv, 2, params);
2. 先构建完整的日历布局结构,再添加事件
对于多日日历场景,更合理的方式是先把每一天对应的容器视图都创建好,再往对应日期的容器里加事件,这样从根源上避免索引问题:
// 假设是周视图,先创建7天的容器 LinearLayout weekContainer = new LinearLayout(context); weekContainer.setOrientation(LinearLayout.HORIZONTAL); List<LinearLayout> dayContainers = new ArrayList<>(); // 循环创建每天的垂直容器,用来放当天的事件 for (int i = 0; i < 7; i++) { LinearLayout dayLayout = new LinearLayout(context); dayLayout.setOrientation(LinearLayout.VERTICAL); dayContainers.add(dayLayout); weekContainer.addView(dayLayout); } // 现在给第3天(索引2)添加事件视图 TextView eventView = new TextView(context); eventView.setBackgroundResource(R.drawable.event_view); int height = context.getResources().getDimensionPixelSize(R.dimen.event_image_size); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, height ); dayContainers.get(2).addView(eventView, params);
额外小提醒
每次调用addView指定索引前,最好加个判断避免意外报错:
int targetIndex = 2; if (targetIndex <= linearLayout.getChildCount()) { linearLayout.addView(tv, targetIndex, params); } else { // 如果索引超出范围,直接加到布局末尾 linearLayout.addView(tv, params); }
内容的提问来源于stack exchange,提问作者nidhi
相关产品推荐
相关产品推荐

