RecyclerView样式的日历选择器

    看到携程,飞猪上面的日历选择,比如飞机票选择里的日历,这里就会是列表形式的日历选择,这上面会有还会展示价格,折扣之类的东西。但是这个有个缺点,就是固定了从哪一天到哪一天,而且是对于未来某段时间的展示,如果要展示之前的呢,要无限加载呢?下面就来看看我所实现的效果吧:

实现效果就是这样,无限下拉加载更多日历,然后每个日期的的item也是可以自定义,加上点加上背景,字体设置都是可以的。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="560dp"
        android:background="#ffffff"
        android:orientation="vertical">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="44dp">

            <TextView
                android:id="@+id/tv_cancel"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center"
                android:paddingLeft="30dp"
                android:paddingRight="30dp"
                android:text="取消"
                android:textColor="#999999"
                android:textSize="14sp" />

            <TextView
                android:id="@+id/tv_today"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_alignParentRight="true"
                android:gravity="center"
                android:paddingLeft="30dp"
                android:paddingRight="30dp"
                android:text="今天"
                android:textColor="#2A51A1"
                android:textSize="14sp" />


        </RelativeLayout>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#CDCED2" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_week"
            android:layout_width="wrap_content"
            android:layout_height="36dp"
            android:layout_gravity="center_horizontal" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_month"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal" />
    </LinearLayout>
</RelativeLayout>


这就是基本布局,分为两部分的RecyclerView,上面那个展示的是星期,下面的那部分展示的就是日期了。对于日期就是要分月份和天的展示,天的展示其实也是在一个RecyclerView中,有的有些疑问,滑动冲突怎么办?页面展示不好怎么办?对于RecyclerView嵌套RecyclerView最方面的就是item的高度要么写死要么wrap_content。类似于下面这样:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">


    <TextView
        android:id="@+id/tv_cal_title"
        android:layout_width="match_parent"
        android:layout_height="36dp"
        android:layout_gravity="center_horizontal"
        android:background="#f4f6fa"
        android:gravity="center_vertical"
        android:paddingLeft="27dp"
        android:text="2017年12月"
        android:textColor="#303030"
        android:textSize="17sp" />


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_day"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

那么剩下的就是数据的来源了,主要就是利用系统自带的Calendar对象了,我现在做的事每次加载一年的数据,每次加载之后就修改Calendar,然后在set数据时候根据你想要的的日期可以自己自定义数据然后再adapter的时候获取出来进行想要样式的展示了。

private int year, month, day;
    private int nowDay;
    private int currentI = 0;
    private List<MonthEntity> monthList = new ArrayList<>();
    private Calendar calendar = Calendar.getInstance();

    private void setMonthData(CalendarMonthAdapter calendarDayAdapter) {

        for (int i = 0; i < 12; i++) {
            List<DateEntity> deList = new ArrayList<>();
            MonthEntity monthEntity = new MonthEntity();
            int maxDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            int empty = calendar.get(Calendar.DAY_OF_WEEK);
            empty = empty == 1 ? 6 : empty - 2;
            for (int j = 0; j < empty; j++) {
                DateEntity de = new DateEntity();
                de.setType(1);
                deList.add(de);
            }
            for (int j = 1; j <= maxDayOfMonth; j++) {
                DateEntity de = new DateEntity();
                if (currentI == 0) {
                    if (j > nowDay) {
                        de.setType(4);
                    } else if (j == nowDay) {
                        de.setType(2);
                    } else {
                        de.setType(0);

                    }

                } else {
                    de.setType(0);
                }
                de.setMonth(calendar.get(Calendar.MONTH) + 1);
                de.setDate(j);
                de.setParentPos(currentI);
                de.setDesc(Lunar.getLunarDate(year, month + 1, j));
                deList.add(de);
            }
            currentI++;
            year = calendar.get(Calendar.YEAR);
            month = calendar.get(Calendar.MONTH) + 1;
            monthEntity.setTitle(year + "年" + month + "月");
            monthEntity.setYear(year);
            monthEntity.setList(deList);
            monthList.add(monthEntity);

            calendar.add(Calendar.MONTH, -1);
        }
        calendarDayAdapter.loadMoreComplete();
        calendarDayAdapter.notifyDataSetChanged();
    }

由上面的可以看出我是根据type来区分不同的日期了,因此在我实现天的adapter中就根据这个来展示不同的样式了:

public class CalendarDayAdapter extends BaseQuickAdapter<DateEntity, BaseViewHolder> {


    public CalendarDayAdapter(List<DateEntity> data) {
        super(R.layout.item_task_day, data);

    }


    @Override
    protected void convert(BaseViewHolder helper, DateEntity item) {
        if (item == null) {
            return;
        }
        RelativeLayout rl_content = helper.getView(R.id.rl_content);
        View view_bg = helper.getView(R.id.view_bg);
        View view_point = helper.getView(R.id.view_point);
        view_bg.setVisibility(View.GONE);
        view_point.setVisibility(View.GONE);
        TextView tv_date = helper.getView(R.id.tv_date);
        tv_date.setTextColor(Color.parseColor("#999999"));
        if (item.getType() == 1) {//留白
            tv_date.setText("");
            view_point.setVisibility(View.GONE);
        } else if (item.getType() == 2) {
            //今天
            view_bg.setVisibility(View.VISIBLE);
            tv_date.setText(item.getDate() + "");

        } else if (item.getType() == 0) {
            view_bg.setVisibility(View.GONE);
            tv_date.setText(item.getDate() + "");
        } else if (item.getType() == 4) {
            //今天之后的
            view_point.setVisibility(View.GONE);
            view_point.setVisibility(View.VISIBLE);
            tv_date.setTextColor(Color.parseColor("#303030"));
            tv_date.setText(item.getDate() + "");
        }

    }

}

基本上就实现了,下面是下载链接地址:

https://download.csdn.net/download/greatdaocaoren/12673449

有兴趣可以看看下面服务号和订阅号:

猜你喜欢

转载自blog.csdn.net/greatdaocaoren/article/details/107689760