自定义CalendarView

因为项目原因,不多说上代码

public class CommonCalendarView extends FrameLayout implements View.OnClickListener {

    private ViewPager mViewPager;
    private TextView mMonthTv;
    private Context mContext;
    private ImageButton mLeftMonthBtn;
    private ImageButton mRightMonthBtn;

    private SparseArray<GridView> mViewMap = new SparseArray<>();

    private Map<String, List> mYearMonthMap;
    private DatePickerController mController;
    private CalendarAdapter adapter;
    private Date maxDate;
    private Date minDate;

    public void setMaxDate(Date maxDate) {
        this.maxDate = maxDate;
    }

    public void setMinDate(Date minDate) {
        this.minDate = minDate;
    }

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

    public CommonCalendarView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CommonCalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
    }




    public void init(DatePickerController controller){
        if (controller==null){
             mController = new DatePickerController() {
                 @Override
                 public int getMaxYear() {
                     return DateUtils.getToYear()+1;
                 }

                 @Override
                 public void onDayOfMonthSelected(int year, int month, int day) {
                     Toast.makeText(mContext, String.format("%s-%s-%s", year,StringUtils.leftPad(String.valueOf(month),2,"0"),
                             StringUtils.leftPad(String.valueOf(day),2,"0")), Toast.LENGTH_SHORT).show();
                 }

                 @Override
                 public void onDayOfMonthAndDataSelected(int year, int month, int day, List obj) {

                 }

                 @Override
                 public void showOtherFields(Object obj, View view, int gridItemYear, int gridItemMonth, int gridItemDay,int postion) {

                 }

                 @Override
                 public Map<String, List> getDataSource() {
                     return null;
                 }

             };
        }else{
            mController = controller;
        }
        this.mYearMonthMap = mController.getDataSource();
        adapter = new CalendarAdapter(mContext);
        mViewPager.setPageTransformer(true,new DepthPageTransformer());
        mViewPager.setAdapter(adapter);


        if (minDate!=null){
            mMonthTv.setText(String.format("%s年%s月",DateUtils.getYear(minDate), StringUtils.leftPad(String.valueOf(DateUtils.getMonth(minDate)),2,"0")));
        }else{
            mMonthTv.setText(String.format("%s年%s月",DateUtils.getToYear(), StringUtils.leftPad(String.valueOf(DateUtils.getToMonth()),2,"0")));
        }

        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                mMonthTv.setText(adapter.getPageTitle(position));
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        View view = LayoutInflater.from(mContext).inflate(R.layout.activity_page_calendar_price,this,true);
        this.mViewPager = (ViewPager) view.findViewById(R.id.viewPager);
        this.mRightMonthBtn = (ImageButton) view.findViewById(R.id.right_month_btn);
        this.mMonthTv = (TextView) view.findViewById(R.id.month_tv);
        this.mLeftMonthBtn = (ImageButton) view.findViewById(R.id.left_month_btn);
        this.mLeftMonthBtn.setOnClickListener(this);
        this.mRightMonthBtn.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.left_month_btn:
                mViewPager.setCurrentItem(mViewPager.getCurrentItem()-1,true);
                break;
            case R.id.right_month_btn:
                mViewPager.setCurrentItem(mViewPager.getCurrentItem()+1,true);
                break;
        }
    }


    class CalendarAdapter extends PagerAdapter implements AdapterView.OnItemClickListener {

        protected static final int MONTHS_IN_YEAR = 12;
        private final Calendar calendar = Calendar.getInstance();
        private Integer firstMonth = calendar.get(Calendar.MONTH);
        private LayoutInflater inflater;
        private Integer lastMonth = (calendar.get(Calendar.MONTH) - 1) % MONTHS_IN_YEAR;
        private Integer startYear = calendar.get(Calendar.YEAR);

        public CalendarAdapter(Context context) {
            inflater = LayoutInflater.from(context);
            mContext = context;
            if (maxDate!=null){
                lastMonth = DateUtils.getMonth(maxDate)-1;
            }
            if (minDate!=null){
                startYear = DateUtils.getYear(minDate);
                firstMonth = DateUtils.getMonth(minDate)-1;
            }
        }


        @Override
        public CharSequence getPageTitle(int position) {
            int year = position / MONTHS_IN_YEAR + startYear + ((firstMonth + (position % MONTHS_IN_YEAR)) / MONTHS_IN_YEAR);
            int month = (firstMonth + (position % MONTHS_IN_YEAR)) % MONTHS_IN_YEAR;
            return String.format("%s年%s月",year, StringUtils.leftPad(String.valueOf(month+1),2,"0"));
        }

        @Override
        public int getCount() {
            int maxYear = mController.getMaxYear();
            int minYear = calendar.get(Calendar.YEAR) ;
            if (maxDate!=null){
                maxYear = DateUtils.getYear(maxDate);
            }
            if (minDate!=null){
                minYear = DateUtils.getYear(minDate);
            }

            int itemCount = (maxYear-minYear+1) * MONTHS_IN_YEAR;

            if (firstMonth != -1)
                itemCount -= firstMonth;

            if (lastMonth != -1)
                itemCount -= (MONTHS_IN_YEAR - lastMonth) - 1;
            return itemCount;
        }


        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            GridView mGridView = mViewMap.get(position);
            if (mGridView ==null){
                mGridView = (GridView) inflater.inflate(R.layout.item_page_month_day, container, false);
                mViewMap.put(position,mGridView);
            }
            int year = position / MONTHS_IN_YEAR +  startYear + ((firstMonth + (position % MONTHS_IN_YEAR)) / MONTHS_IN_YEAR);
            int month = (firstMonth + (position % MONTHS_IN_YEAR)) % MONTHS_IN_YEAR;
            DateBean dateBean = new DateBean(year, month + 1);
            mGridView.setOnItemClickListener(this);

            mGridView.setAdapter(new MyGridAdapter(dateBean));
            container.addView(mGridView);
            return mGridView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

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

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            MyGridAdapter gridAdapter = (MyGridAdapter) parent.getAdapter();
            int day = (int) gridAdapter.getItem(position);
            if (day == -1) {
                return;
            }
            DateBean bean = gridAdapter.getDateBean();
            List<ProductDatePrice> list = gridAdapter.getProductDatePriceList();
            if (mController!=null){
                if (list!=null&&!list.isEmpty()){
                    mController.onDayOfMonthAndDataSelected(bean.currentYear,bean.currentMonth,day+1,list);
                }else{
                    mController.onDayOfMonthSelected(bean.currentYear,bean.currentMonth,day+1);
                }
            }
        }

    }


    class MyGridAdapter extends BaseAdapter {


        private DateBean mDateBean;
        private int days;
        private int dayOfWeeks;
        private List mProductDatePriceList;


        public DateBean getDateBean() {
            return mDateBean;
        }

        public MyGridAdapter(DateBean dateBean) {
            this.mDateBean = dateBean;
            if (mYearMonthMap!=null){
                this.mProductDatePriceList = mYearMonthMap.get(String.format("%s-%s", dateBean.currentYear, StringUtils.leftPad(dateBean.currentMonth + "", 2, "0")));
            }
            GregorianCalendar c = new GregorianCalendar(dateBean.currentYear, dateBean.currentMonth - 1, 0);
            days = DateUtils.getDaysOfMonth(dateBean.currentYear, dateBean.currentMonth); //返回当前月的总天数。
            dayOfWeeks = c.get(Calendar.DAY_OF_WEEK);
            if (dayOfWeeks == 7) {
                dayOfWeeks = 0;
            }
        }

        public List getProductDatePriceList() {
            return mProductDatePriceList;
        }

        @Override
        public int getCount() {
            return days + dayOfWeeks;
        }

        @Override
        public Object getItem(int i) {
            if (i < dayOfWeeks) {
                return -1;
            } else {
                return i - dayOfWeeks;
            }
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            GridViewHolder viewHolder ;
            if (view == null) {
                view = LayoutInflater.from(mContext).inflate(R.layout.item_day, viewGroup, false);
                viewHolder = new GridViewHolder();
                viewHolder.mTextView = (TextView) view.findViewById(R.id.day_tv);
                viewHolder.mPriceTv = (TextView) view.findViewById(R.id.price_tv);
                viewHolder.mLineView = view.findViewById(R.id.line_view);
                view.setTag(viewHolder);
            } else {
                viewHolder = (GridViewHolder) view.getTag();
            }
            int item = (int) getItem(i);
            if (item == -1) {
                viewHolder.mTextView.setText("");
                viewHolder.mPriceTv.setText("");
            } else {
                viewHolder.mTextView.setText(String.valueOf(item + 1));
                viewHolder.mPriceTv.setText("");
                if (i%7==0||i%7==6){
                    viewHolder.mTextView.setActivated(true);
                }else{
                    viewHolder.mTextView.setActivated(false);
                }
                if (mProductDatePriceList != null) {
                    viewHolder.mTextView.setEnabled(false);
                    view.setEnabled(false);
                    for (Object obj : mProductDatePriceList) {//用于展示价格等额外的属性
                        if (mController!=null){
                            mController.showOtherFields(obj,view,mDateBean.currentYear,mDateBean.currentMonth,item+1,i);
                        }
                    }
                }
            }
            return view;
        }
    }

    static class DateBean {
        private int currentYear;
        private int currentMonth;

        public DateBean(int currentYear, int currentMonth) {
            this.currentYear = currentYear;
            this.currentMonth = currentMonth;
        }
    }

    public static class GridViewHolder {
        public TextView mTextView;
        public View mLineView;
        public TextView mPriceTv;
    }

    class DepthPageTransformer implements ViewPager.PageTransformer {
        private static final float MIN_SCALE = 0.75f;

        @Override
        public void transformPage(View view, float position) {
            int pageWidth = view.getWidth();

            if (position < -1) { // [-Infinity,-1)
                // This page is way off-screen to the left.
                view.setAlpha(0);

            } else if (position <= 0) { // [-1,0]
                // Use the default slide transition when moving to the left page
                view.setAlpha(1);
                view.setTranslationX(0);
                view.setScaleX(1);
                view.setScaleY(1);

            } else if (position <= 1) { // (0,1]
                // Fade the page out.
                view.setAlpha(1 - position);

                // Counteract the default slide transition
                view.setTranslationX(pageWidth * -position);

                // Scale the page down (between MIN_SCALE and 1)
                float scaleFactor = MIN_SCALE
                        + (1 - MIN_SCALE) * (1 - Math.abs(position));
                view.setScaleX(scaleFactor);
                view.setScaleY(scaleFactor);

            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
                view.setAlpha(0);
            }
        }
    }

    public interface DatePickerController {


        int getMaxYear();

        void onDayOfMonthSelected(int year, int month, int day);

        void onDayOfMonthAndDataSelected(int year, int month, int day, List obj);

        //展示其它属性(用于扩展数据  日期相等时设置显示效果)
        void showOtherFields(Object obj, View view, int gridItemYear, int gridItemMonth, int gridItemDay,int position);

        Map<String,List> getDataSource();
    }

}

调用时

public class MoreInfoCalendarActivity extends AppCompatActivity {

    private  CommonCalendarView calendarView;
    private Map<String,List> mYearMonthMap = new HashMap<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_more_info_calendar);

        List<ProductDatePrice> mDatePriceList = new ArrayList<>();
        for (int i = 1; i <= 12; i++) {//构造12个月每天的价格数据
            for (int j = 1; j <= 28; j++) {
                ProductDatePrice price = new ProductDatePrice();
                price.setPriceDate(String.format("2018-%s-%s", StringUtils.leftPad(String.valueOf(i), 2, "0"), StringUtils.leftPad(String.valueOf(j), 2, "0")));
                price.setPrice(RandomUtils.nextInt(1000));
                mDatePriceList.add(price);
            }
        }

        for (ProductDatePrice productDatePrice : mDatePriceList) {//把价格数据改为同一个月的list 在一个key value里,减少渲染界面时循环判断数量
            productDatePrice.getPriceDate();
            String yearMonth = TextUtils.substring(productDatePrice.getPriceDate(), 0, TextUtils.lastIndexOf(productDatePrice.getPriceDate(), '-'));
            List list = mYearMonthMap.get(yearMonth);
            if (list == null) {
                list = new ArrayList();
                list.add(productDatePrice);
                mYearMonthMap.put(yearMonth, list);
            } else {
                list.add(productDatePrice);
            }
        }

        this.calendarView = (CommonCalendarView) findViewById(R.id.calendarView);
        this.calendarView.init(new CommonCalendarView.DatePickerController() {
            @Override
            public int getMaxYear() {
                return 2020;
            }

            @Override
            public void onDayOfMonthSelected(int year, int month, int day) {
                Toast.makeText(MoreInfoCalendarActivity.this, String.format("%s-%s-%s", year,StringUtils.leftPad(String.valueOf(month),2,"0"),
                        StringUtils.leftPad(String.valueOf(day),2,"0")), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onDayOfMonthAndDataSelected(int year, int month, int day, List obj) {
                if (obj==null){
                    return;
                }
                String priceDate = String.format("%s-%s-%s", year,
                        StringUtils.leftPad(month + "", 2, "0"), StringUtils.leftPad(String.valueOf(day), 2, "0"));
                for (int i = 0; i < obj.size(); i++) {
                    ProductDatePrice datePrice = (ProductDatePrice) obj.get(i);
                    if (datePrice==null){
                        continue;
                    }
                    if (TextUtils.equals(datePrice.getPriceDate(),priceDate)){
                        Toast.makeText(MoreInfoCalendarActivity.this, datePrice.toString(), Toast.LENGTH_SHORT).show();
                    }
                }
            }

            @Override
            public void showOtherFields(Object obj, View view, int gridItemYear, int gridItemMonth, int gridItemDay) {
                //当你设置了数据源之后,界面渲染会循环调用showOtherFields方法,在该方法中实现同一日期设置界面显示效果。
//                ProductDatePrice productDatePrice  = (ProductDatePrice) obj;
//                if (TextUtils.equals(productDatePrice.getPriceDate(), String.format("%s-%s-%s", gridItemYear,
//                        StringUtils.leftPad(gridItemMonth + "", 2, "0"), StringUtils.leftPad(String.valueOf(gridItemDay), 2, "0")))) {
                    CommonCalendarView.GridViewHolder viewHolder = (CommonCalendarView.GridViewHolder) view.getTag();
                    if(gridItemYear == 2018 && gridItemMonth == 5 && gridItemDay == 8){
                        viewHolder.mPriceTv.setText("填写显示");
                    }
//                    viewHolder.mPriceTv.setText(String.format("¥ %s", productDatePrice.getPrice()));
                    view.setEnabled(true);
                    viewHolder.mTextView.setEnabled(true);
//                }
            }

            @Override
            public Map<String, List> getDataSource() {
                return mYearMonthMap;
            }
        });
    }
}

可以在日期里设置界面

项目地址:https://download.csdn.net/download/qq_35711467/10400978

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天来临

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值