在使线性布局容器无效后未调用子视图的 ondraw()

Posted

技术标签:

【中文标题】在使线性布局容器无效后未调用子视图的 ondraw()【英文标题】:children views's ondraw() not called after invalidate linearlayout container 【发布时间】:2013-11-15 03:15:10 【问题描述】:

我正在编写一个日历视图。当我按下下个月按钮时,我调用了 mCalendarContainerLL.invalidate();但是我的自定义视图没有被重绘。我的自定义视图中的 onDraw 方法没有被调用。

Ps:如果我直接使所有日历单元格视图无效。它可以工作。 为什么会这样???

代码如下:

private CalendarWidgetDayCell updateCalendarView() 

        CalendarWidgetDayCell dayCellSelected = null;
        boolean isSelected = false;

        final boolean isHasSelection = (mCalendarSelected.getTimeInMillis() != 0);

        final int selectedYear = mCalendarSelected.get(Calendar.YEAR);
        final int selectedMonth = mCalendarSelected.get(Calendar.MONTH);
        final int selectedDay = mCalendarSelected.get(Calendar.DAY_OF_MONTH);

        Calendar dateXOfCalendar = Calendar.getInstance();
        dateXOfCalendar.setTimeInMillis(mStartDateCurrentMonth.getTimeInMillis());

        Log.d(tag, "updateCalendarView cpt_func_ " + "mDayCellList.size(): " + mDayCellList.size());
        for (int i = 0; i < mDayCellList.size(); i++) 
            final int yearOfCellItem = dateXOfCalendar.get(Calendar.YEAR);
            final int monthOfCellItem = dateXOfCalendar.get(Calendar.MONTH);
            final int dayOfCellItem = dateXOfCalendar.get(Calendar.DAY_OF_MONTH);
            final int dayOfWeekOfCellItem = dateXOfCalendar.get(Calendar.DAY_OF_WEEK);
            CalendarWidgetDayCell dayCellItem = mDayCellList.get(i);

            boolean isToday = false;
            if (mCalendarToday.get(Calendar.YEAR) == yearOfCellItem) 
                if (mCalendarToday.get(Calendar.MONTH) == monthOfCellItem) 
                    if (mCalendarToday.get(Calendar.DAY_OF_MONTH) == dayOfCellItem) 
                        isToday = true;
                    
                
            

            // check holiday
            boolean isHoliday = false;
            if ((dayOfWeekOfCellItem == Calendar.SATURDAY) || (dayOfWeekOfCellItem == Calendar.SUNDAY))
                isHoliday = true;
            if ((monthOfCellItem == Calendar.JANUARY) && (dayOfCellItem == 1))
                isHoliday = true;

            isSelected = false;
            if (isHasSelection) 
                if ((selectedDay == dayOfCellItem) && (selectedMonth == monthOfCellItem)
                        && (selectedYear == yearOfCellItem)) 
                    isSelected = true;
                
            
            dayCellItem.setSelected(isSelected);

            boolean hasRecord = false;

            if (isSelected)
                dayCellSelected = dayCellItem;

            dayCellItem.setViewParam(yearOfCellItem, monthOfCellItem, dayOfCellItem, isToday, isHoliday,
                    mCurrentMonthInCalendar, hasRecord);

            dayCellItem.invalidate();//It works well.
            dateXOfCalendar.add(Calendar.DAY_OF_MONTH, 1);
        

        // mCalendarContainerLL.invalidate();//This is not working as expected.
        return dayCellSelected;
    

【问题讨论】:

【参考方案1】:

如果在布局级别调用invalidate(),则布局决定必须重绘它的哪些部分。因此,它仅在受影响/脏的子视图上调用invalidate()。对一个单元格的任何更改对布局都是不可见的,因此布局看不到使任何子级无效的必要性。

当需要重绘视图时,您应该让视图本身失效。在您的情况下,我会在 setParamView 方法中添加对 invalidateSelf() 的调用。据我了解的代码,这是负责将一个单元格装饰为日历中的一天的方法。

【讨论】:

@jboi....我将此代码提取到另一个测试项目中。然后它运行良好....我真的不明白为什么会这样! :( android 会变得奇怪,当它试图找出屏幕的哪些部分需要重绘时。所以最适合我的是在我认为这部分需要重绘时致电invalidateSelf()。无论如何,Gald 看到它现在正在工作。

以上是关于在使线性布局容器无效后未调用子视图的 ondraw()的主要内容,如果未能解决你的问题,请参考以下文章

在无效之间保持动画状态

未调用 CScrollView OnDraw

线性布局

activex 如何调用OnDraw函数

(自动布局)容器视图调整大小但子视图不

MFC中的Invalidate、OnDraw、OnPaint函数的作用、区别和联系?