Android 自定义日历周视图

简版如下:


知识点:viewpager无限滑动、日期的计算、自定义day(每个单元格view) 以及week(每七个单元格)


关于viewpager的另一种无限循环方式:点击打开链接


简要知识点:onPageSelected里面做条件判断,在onPageScrollStateChanged里面做跳转

真实数据为  A   B  C   实际要添两条辅助数据:C  A  B C A





自定义 day视图

        主要绘制显示的天和小蓝点

package cn.edu.sxu.www.customercalendar;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by ${huozhenpeng} on 17/3/27.
 * Company : www.miduo.com
 */

public class DayItem extends View {

    private int width;
    private int height;
    private TextPaint textPaint;
    private Paint pointPaint;
    private int radius;
    private Context context;
    public DayItem(Context context) {
        this(context,null);
    }

    public DayItem(Context context, AttributeSet attrs) {
        this(context, attrs,-1);
    }

    public DayItem(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context=context;
        init();
    }

    private void init()
    {
        textPaint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(Color.parseColor("#000000"));
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setTextSize(context.getResources().getDimension(R.dimen.px2sp_24));
        pointPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
        pointPaint.setColor(Color.parseColor("#369ed2"));
        radius= (int) context.getResources().getDimension(R.dimen.px2dp_6);
        pointPaint.setStrokeWidth(radius);

    }

    private int baseY;
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //绘制文字
        // 计算Baseline绘制的Y坐标
        baseY = (int) ((height/ 2) - ((textPaint.descent() + textPaint.ascent()) / 2));

        canvas.drawText(dateBean.getDate(), width/2, baseY, textPaint);

        //绘制标记

        canvas.drawCircle(width/2,height-radius,radius,pointPaint);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width=w;
        height=h;
    }

    private DateBean dateBean;
    public  void setData(DateBean dateBean)
    {
        this.dateBean=dateBean;
    }


}


自定义week视图

      包含7个day视图

package cn.edu.sxu.www.customercalendar;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Toast;

import java.util.List;

/**
 * Created by ${huozhenpeng} on 17/3/27.
 * Company : www.miduo.com
 */

public class viewPagerItem extends LinearLayout implements View.OnClickListener{
    private Context context;
    private List<DateBean> lists;
    private int day;
    private int week;
    private int month;
    private int year;
    private int lastDay;
    private String[] nums;

    public List<DateBean> getLists() {
        return lists;
    }

    public void setLists(List<DateBean> lists) {
        this.lists = lists;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public int getWeek() {
        return week;
    }

    public void setWeek(int week) {
        this.week = week;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getLastDay() {
        return lastDay;
    }

    public void setLastDay(int lastDay) {
        this.lastDay = lastDay;
    }

    public String[] getNums() {
        return nums;
    }

    public void setNums(String[] nums) {
        this.nums = nums;
    }

    public viewPagerItem(Context context) {
        this(context,null);
    }

    public viewPagerItem(Context context, AttributeSet attrs) {
        this(context, attrs,-1);
    }

    public viewPagerItem(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context=context;
    }
    public void setData(List<DateBean> lists)
    {
        this.lists=lists;
        removeAllViews();
        for(int i=0;i<lists.size();i++)
        {
            DayItem dayItem=new DayItem(context);
            dayItem.setData(lists.get(i));
            LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            layoutParams.weight=1;
            dayItem.setLayoutParams(layoutParams);
            addView(dayItem);
            dayItem.setOnClickListener(this);
            dayItem.setTag(lists.get(i));
        }
    }


    @Override
    public void onClick(View v) {

        Toast.makeText(context,((DateBean)v.getTag()).getDate(),Toast.LENGTH_SHORT).show();
    }
}



布局文件:

activity_main.xml

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


    <include layout="@layout/top_week_title"
        />
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpater"
        android:layout_width="match_parent"
        android:layout_height="@dimen/px2dp_72">

    </android.support.v4.view.ViewPager>


    <TextView
        android:id="@+id/tv_tip"
        android:layout_marginTop="100dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        />

</LinearLayout>


top_week_title.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:paddingTop="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/sunday"
        android:textColor="@color/calendar_week_color"
        android:textSize="12sp" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/monday"
        android:textColor="@color/calendar_week_color"
        android:textSize="12sp" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/tuseday"
        android:textColor="@color/calendar_week_color"
        android:textSize="12sp" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/wednesday"
        android:textColor="@color/calendar_week_color"
        android:textSize="12sp" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/thursday"
        android:textColor="@color/calendar_week_color"
        android:textSize="12sp" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/friday"
        android:textColor="@color/calendar_week_color"
        android:textSize="12sp" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/saturday"
        android:textColor="@color/calendar_week_color"
        android:textSize="12sp" />

</LinearLayout>



主界面:

  逻辑冗余很多,可做优化


package cn.edu.sxu.www.customercalendar;

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ViewPager viewPager;
    private CalendarAdapger calendarAdapger;
    private List<viewPagerItem> lists;

    private TextView tv_tip;



    private float lastValue;
    private boolean isRightToLeft = false;  //从右向左滑动
    private boolean isLeftToRight = false;  //从左向右滑动


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager= (ViewPager) findViewById(R.id.viewpater);
        tv_tip= (TextView) findViewById(R.id.tv_tip);
        lists=new ArrayList<>();
        Calendar calendar= Calendar.getInstance();
        int day=calendar.get(Calendar.DAY_OF_MONTH);
        int week=calendar.get(Calendar.DAY_OF_WEEK);
        int month=calendar.get(Calendar.MONTH);
        int year=calendar.get(Calendar.YEAR);
        int lastDay=getLastDay(calendar);
        String[] nums=makeViewpagerItem(day,week,lastDay,-1,month,year);

        tv_tip.setText(year+"年"+(month+1)+"月");


        //计算下一页数据
        if(TextUtils.isEmpty(nums[1])||Integer.parseInt(nums[1])==lastDay)
        {
            //下一月份
            //判断是不是该到下一年
            if(month==11)
            {
                //取下一年
                calendar.set(year+1,0,1);
            }
            else
            {
                calendar.set(year,month+1,1);


            }
        }
        else
        {
            //本月
            calendar.set(year,month,Integer.parseInt(nums[1])+1);

        }
        int day1=calendar.get(Calendar.DAY_OF_MONTH);
        int week1=calendar.get(Calendar.DAY_OF_WEEK);
        int month1=calendar.get(Calendar.MONTH);
        int year1=calendar.get(Calendar.YEAR);
        int lastDay1=getLastDay(calendar);
        String[] nums1=makeViewpagerItem(day1,week1,lastDay1,-1,month1,year1);

        //计算前一页数据
        if(TextUtils.isEmpty(nums[0])||Integer.parseInt(nums[0])==0)
        {
            //前一月份
            //判断是不是该到前一年
            if(month==0)
            {
                //取上一年
                calendar.set(year-1,11,1);
                int week2=calendar.get(Calendar.DAY_OF_WEEK);
                int lastDay2=getLastDay(calendar);
                int date=lastDay2-(week2-1);
                calendar.set(year-1,11,date);
            }
            else
            {
                calendar.set(Calendar.MONTH,month-1);
                int lastDay2=getLastDay(calendar);
                int week2=calendar.get(Calendar.DAY_OF_WEEK);
                int  date=lastDay2-(week2-1);
                calendar.set(year,month-1,date);

            }
        }
        else
        {
            //本月
            calendar.set(year,month,Integer.parseInt(nums[0])-1);

        }
        day=calendar.get(Calendar.DAY_OF_MONTH);
        week=calendar.get(Calendar.DAY_OF_WEEK);
        month=calendar.get(Calendar.MONTH);
        year=calendar.get(Calendar.YEAR);
        lastDay=getLastDay(calendar);
        makeViewpagerItem(day,week,lastDay,0,month,year);



        calendarAdapger=new CalendarAdapger(lists,this);
        viewPager.setAdapter(calendarAdapger);
        viewPager.setCurrentItem(Integer.MAX_VALUE/2+1);

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                if (positionOffset == 0.0){
                    return;
                }
                if (lastValue > positionOffset) {
                    // 递减,从左向右滑动
                    isRightToLeft = false;
                    isLeftToRight = true;
                } else if (lastValue < positionOffset) {
                    // 递增,从右向左滑动
                    isRightToLeft = true;
                    isLeftToRight = false;
                } else if (lastValue == positionOffset) {
                    isLeftToRight = isRightToLeft = false;
                }
                lastValue = positionOffset;

            }

            @Override
            public void onPageSelected(int position) {
                viewPagerItem viewPagerItem=lists.get(position%3);
                tv_tip.setText(viewPagerItem.getYear()+"年"+(viewPagerItem.getMonth()+1)+"月");

                if(isRightToLeft)//右边滑动
                {
                    String[] nums=viewPagerItem.getNums();
                    int month=viewPagerItem.getMonth();
                    int year=viewPagerItem.getYear();
                    int lastDay=viewPagerItem.getLastDay();
                    Calendar calendar=Calendar.getInstance();
                    //计算下一页数据
                    if(TextUtils.isEmpty(nums[1])||Integer.parseInt(nums[1])==lastDay)
                    {
                        //下一月份
                        //判断是不是该到下一年
                        if(month==11)
                        {
                            //取下一年
                            calendar.set(year+1,0,1);
                        }
                        else
                        {
                            calendar.set(year,month+1,1);
                        }
                    }
                    else
                    {
                        //本月
                        calendar.set(year,month,Integer.parseInt(nums[1])+1);

                    }
                    int day1=calendar.get(Calendar.DAY_OF_MONTH);
                    int week1=calendar.get(Calendar.DAY_OF_WEEK);
                    int month1=calendar.get(Calendar.MONTH);
                    int year1=calendar.get(Calendar.YEAR);
                    int lastDay1=getLastDay(calendar);
                    makeViewpagerItem(day1,week1,lastDay1,month1,year1,lists.get((position-2)%3));
                    calendarAdapger.notifyDataSetChanged();

                }
                else//左边滑动
                {
                    String[] nums=viewPagerItem.getNums();
                    int month=viewPagerItem.getMonth();
                    int year=viewPagerItem.getYear();
                    Calendar calendar=Calendar.getInstance();
                    //计算前一页数据
                    if(TextUtils.isEmpty(nums[0])||Integer.parseInt(nums[0])==0)
                    {
                        //前一月份
                        //判断是不是该到前一年
                        if(month==0)
                        {
                            //取上一年


                            calendar.set(year-1,11,1);
                            int week=calendar.get(Calendar.DAY_OF_WEEK);
                            int lastDay=getLastDay(calendar);
                            int date=lastDay-(week-1);
                            calendar.set(year-1,11,date);
                        }
                        else
                        {
                            calendar.set(Calendar.MONTH,month-1);
                            int lastDay=getLastDay(calendar);
                            int week=calendar.get(Calendar.DAY_OF_WEEK);
                            int  date=lastDay-(week-1);
                            calendar.set(year,month-1,date);

                        }
                    }
                    else
                    {
                        //本月
                        calendar.set(year,month,Integer.parseInt(nums[0])-1);

                    }
                    int  day1=calendar.get(Calendar.DAY_OF_MONTH);
                    int  week1=calendar.get(Calendar.DAY_OF_WEEK);
                    int month1=calendar.get(Calendar.MONTH);
                    int year1=calendar.get(Calendar.YEAR);
                    int lastDay1=getLastDay(calendar);
                    makeViewpagerItem(day1,week1,lastDay1,month1,year1,lists.get((position+2)%3));
                    calendarAdapger.notifyDataSetChanged();
                }

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });



    }


    /**
     * 返回第一个数和最后一个数
     * @param parameterday
     * @param week
     * @param lastDay
     * @return
     */
    private String[] makeViewpagerItem(int parameterday,int week,int lastDay,int flag,int month,int year)
    {
        int day=parameterday;
        List<DateBean> dateBeens=new ArrayList<>();
        for(int i=week;i>0;i--)
        {
            if(day<1)
            {
                dateBeens.add(0,new DateBean("",true));
            }
            else
            {
                dateBeens.add(0,new DateBean(""+day,true));
            }
            day--;
        }

        day=parameterday;
        for(int i=week+1;i<=7;i++)
        {
            day++;
            if(day>lastDay)
            {
                dateBeens.add(new DateBean("",true));
            }
            else
            {
                dateBeens.add(new DateBean(""+day,true));
            }
        }
        viewPagerItem viewPagerItem=new viewPagerItem(this);
        String [] num=new String[2];
        num[0]=dateBeens.get(0).getDate();
        num[1]=dateBeens.get(6).getDate();
        viewPagerItem.setDay(parameterday);
        viewPagerItem.setMonth(month);
        viewPagerItem.setYear(year);
        viewPagerItem.setNums(num);

        viewPagerItem.setData(dateBeens);

        if(flag==0)
        {
            lists.add(0,viewPagerItem);
        }
        else
        {
            lists.add(viewPagerItem);
        }
        return num;
    }

    private int getLastDay(Calendar calendar)
    {
        //得到月末
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.get(Calendar.DAY_OF_MONTH);
    }


    private String[] makeViewpagerItem(int parameterday,int week,int lastDay,int month,int year,viewPagerItem viewPagerItem)
    {
        int day=parameterday;
        List<DateBean> dateBeens=new ArrayList<>();
        for(int i=week;i>0;i--)
        {
            if(day<1)
            {
                dateBeens.add(0,new DateBean("",true));
            }
            else
            {
                dateBeens.add(0,new DateBean(""+day,true));
            }
            day--;
        }

        day=parameterday;
        for(int i=week+1;i<=7;i++)
        {
            day++;
            if(day>lastDay)
            {
                dateBeens.add(new DateBean("",true));
            }
            else
            {
                dateBeens.add(new DateBean(""+day,true));
            }
        }
        String [] num=new String[2];
        num[0]=dateBeens.get(0).getDate();
        num[1]=dateBeens.get(6).getDate();
        viewPagerItem.setDay(parameterday);
        viewPagerItem.setMonth(month);
        viewPagerItem.setYear(year);
        viewPagerItem.setNums(num);

        viewPagerItem.setData(dateBeens);
        return num;
    }
}





package cn.edu.sxu.www.customercalendar;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * Created by ${huozhenpeng} on 17/3/27.
 * Company : www.miduo.com
 */

public class CalendarAdapger extends PagerAdapter {


    private List<viewPagerItem> lists;
    private Context context;
    public CalendarAdapger(List<viewPagerItem> lists,Context context)
    {

        this.lists=lists;
        this.context=context;
    }
    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;
    }



    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        Log.e("abc","destroyItem----->"+(position%3));
//        container.removeView(lists.get(position%3));
    }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Log.e("abc","instantiateItem------>"+(position%3));

        viewPagerItem viewPagerItem=lists.get(position%3);
        String log="";

        for(int i=0;i<viewPagerItem.getLists().size();i++)
        {
            log+=viewPagerItem.getLists().get(i).getDate()+"----";

        }
        Log.e("abc",log);

        ViewGroup parentView= (ViewGroup) viewPagerItem.getParent();
        if(parentView!=null)
        {
            parentView.removeView(viewPagerItem);
        }
        container.addView(lists.get(position%3));
        return lists.get(position%3);
    }

}




package cn.edu.sxu.www.customercalendar;

import java.io.Serializable;

/**
 * Created by ${huozhenpeng} on 17/3/27.
 * Company : www.miduo.com
 */

public class DateBean implements Serializable {

    private String  date;
    private boolean needFlag;

    public DateBean(String date,boolean needFlag)
    {
        this.date=date;
        this.needFlag=needFlag;
    }
    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public boolean isNeedFlag() {
        return needFlag;
    }

    public void setNeedFlag(boolean needFlag) {
        this.needFlag = needFlag;
    }
}



源码:点击打开链接


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值