huanghaibin-dev / CalendarView

Android上一个优雅、万能自定义UI、仿iOS、自定义动画,支持垂直、水平方向切换、支持周视图、自定义周起始、性能高效的日历控件,支持热插拔实现的UI定制!支持标记、自定义颜色、农历、自定义月视图各种显示模式等。Canvas绘制,速度快、占用内存低,你真的想不到日历居然还可以如此优雅!An elegant, highly customized and high-performance Calendar Widget on Android.
Apache License 2.0
9.12k stars 1.79k forks source link

如果布局文件中 CalendarView 的外层父布局不为 CalendarLayout,调用 CalendarView#scrollToCurrent() 会出现空指针异常 #474

Closed 374901588 closed 5 years ago

374901588 commented 5 years ago

因为CalendarView#scrollToCurrent() 内部会调用 WeekViewPager#scrollToCurrent(),而该方法内部又会调用mParentLayout属性,该属性定死来为 CalendarLayout。

374901588 commented 5 years ago

因为 CalendarLayout 有发现会无限循环调用其onMeasure 方法的情景,因此不得不在外层调用自己的写的 Layout

huanghaibin-dev commented 5 years ago

感谢你认真阅读了源码并提出issue,针对第一个疑问,这个库只有在使用CalendarLayout才会出现支持WeekView的情况,也就是会使用的WeekViewPager,否则都是跟原生日历一样的效果,CalendarLayout的作用是可选的,如果需要周视图才用的上。 CalendarLayout在CalendarView随着MonthViewPager高度变化才会调用onMeasure,MonthViewPager在mode_only_current或mode_fix模式下,左右滑动都会引起布局变化,如果使用mode_all模式为全部的话,起高度是不变的,就不会引起CalendarLayout的高度变化,应该不会出现没做操作也会无限循环onMeasure的情况,不然是会出现很卡顿的情况的

374901588 commented 5 years ago
<ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="@color/defualt_bg_color"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <LinearLayout
        android:background="@color/white"
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/dateTxtView"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="40dp">

        <com.renren.mobile.uilib.widget.SemiboldTextView
            ...
            android:layout_marginLeft="15dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent" />

        <com.renren.mobile.uilib.widget.SemiboldTextView
            ...
            android:layout_marginRight="15dp"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent" />
    </LinearLayout>

    <com.haibin.calendarview.CalendarLayout
        android:background="@color/defualt_bg_color"
        android:id="@+id/calendarLayout"
        app:gesture_mode="disabled"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/dateTxtView"
        app:layout_constraintBottom_toBottomOf="parent"
        android:orientation="vertical"
        app:default_status="shrink"
        app:calendar_content_view_id="@+id/linearLayout">

        <com.haibin.calendarview.CalendarView
            android:id="@+id/calendarView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/white"
            app:select_mode="single_mode"
            app:current_month_text_color="@color/c323655"
            app:week_bar_view="com.renren.lucrativ.android.ui.widget.calendar.CustomWeekBar"
            app:week_bar_height="20dp"
            app:calendar_height="45dp"
            app:month_view="com.renren.lucrativ.android.ui.widget.calendar.CustomMonthView"
            app:month_view_show_mode="mode_all"
            app:selected_text_color="@color/white"
            app:selected_theme_color="@color/c5894255"
            app:week_start_with="sun"
            app:week_text_color="@color/c323655"
            app:week_view="com.renren.lucrativ.android.ui.widget.calendar.CustomWeekView"
            app:week_view_scrollable="true" />

        <com.renren.lucrativ.android.ui.widget.calendar.pager.CalendarLinearLayout
            android:background="@color/defualt_bg_color"
            android:id="@+id/linearLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:elevation="0dp"
            android:orientation="vertical">

            <FrameLayout
                android:elevation="0dp"
                android:background="@mipmap/bg_calendar_scroll_opreate"
                android:layout_width="match_parent"
                android:layout_height="27dp">
                ...
            </FrameLayout>

            <android.support.design.widget.TabLayout
                android:background="@color/white"
                android:layout_marginTop="10dp"
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="46dp"
                app:tabMode="scrollable"
                .../>

            <android.support.v4.view.ViewPager
                android:layout_marginTop="10dp"
                android:id="@+id/viewPager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

        </com.renren.lucrativ.android.ui.widget.calendar.pager.CalendarLinearLayout>

    </com.haibin.calendarview.CalendarLayout>
</ConstraintLayout>

问题大概找到了,上面的是我用到的文件布局,最外层用的 ConstraintLayout,然后导致了之前说的那个无限 onMesure 的问题,后来把它改成 LinearLayout 之后就好了。具体原因暂时未知。

huanghaibin-dev commented 5 years ago

ConstraintLayout没试过放日历的情况,理论上应该不会的,除非这控件子布局改变的时候全局一直刷新,有空我排查一下