热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android自定义日历滑动控件

这篇文章主要为大家详细介绍了Android自定义日历滑动控件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android自定义日历滑动控件的使用方法,供大家参考,具体内容如下


最近公司项目需要做这个需求,自己才疏学浅,总算能写出个大概来,遂在这里记录下来。

分析

先来分析一下:

首先,我们的需求是可以左右点击查看跳转到下一个月,中间的日历控件可以水平滚动选择日期,所以我们中间的日历控件用一个RecycleView来做,左右两位的为ImageVeiw。
LRCalendarView 总体流程:

  • 编写LRCalendarView的布局R.layout.calendar_view
  • 新建类LRCalendarView继承LinearLayout
  • LRCalendarView添加布局R.layout.calendar_view
  • 数据初始化
  • 构建GalleryAdapter
  • 给RecycleView设置GalleryAdapter并且给左右按钮添加点击事件
  • 处理左右日历翻页逻辑
  • 按需要给RecycleView添加item的点击事件

1. R.layout.calendar_view

<&#63;xml version="1.0" encoding="utf-8"&#63;>


  

  

  

2. 新建类LRCalendarView继承LinearLayout并添加布局

public class LRCalendarView extends LinearLayout {

  private Context context;
  private ImageView ivLeft, ivRight;
  private RecyclerView mRecyclerView;
  private GalleryAdapter mAdapter;
  private List data = new ArrayList<>();
  private int mCurrYear, mCurrMonth, mCurrDay;
  private int mSelYear, mSelMonth, mSelDay;
  //今天的日期的position
  private int todayPos;

  public LRCalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    this.cOntext= context;
    setupView(context);
  }

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

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

  /**
   * 初始化控件
   */
  private void setupView(final Context context) {
    View view = LayoutInflater.from(context).inflate(R.layout.calendar_view, null);
    this.addView(view);

    data = init();
    mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    ivLeft = (ImageView) findViewById(R.id.iv_left);
    ivRight = (ImageView) findViewById(R.id.iv_right);
    //设置manger
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
    linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
    mRecyclerView.setLayoutManager(linearLayoutManager);
    //设置adapter
    mAdapter = new GalleryAdapter(context, init());
    mRecyclerView.setAdapter(mAdapter);

  }
}

public class Cell {

  private String day;
  private String month;
  private int mCurrDay;
  private boolean isSelect;

  public int getmCurrDay() {
    return mCurrDay;
  }

  public void setmCurrDay(int mCurrDay) {
    this.mCurrDay = mCurrDay;
  }

  public String getDay() {
    return day;
  }

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

  public String getMonth() {
    return month;
  }

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

  public boolean isSelect() {
    return isSelect;
  }

  public void setSelect(boolean select) {
    isSelect = select;
  }

}

接下来都是获取日期数据,可以写在一个工具类里,我直接写在LRCalendarView

/**
   * 初始化每个月的数据
 */
  private List init() {
    Calendar calendar = Calendar.getInstance();
    mCurrYear = calendar.get(Calendar.YEAR);
    mCurrMOnth= calendar.get(Calendar.MONTH);
    mCurrDay = calendar.get(Calendar.DATE);
    return init(mCurrYear, mCurrMonth, mCurrDay, 0);
  }

 /**
   * @param flag 0:正常初始化日期 1:为左右点击的初始化日期
   */
  private List init(int year, int month, int day, int flag) {
    if (flag != 0) {
      day = 1;
    }
    setSelectYearMonth(year, month, day);
    List listData = new ArrayList<>();

    int mMOnthDays= getMonthDays(year, month);
    for (int i = 0; i 
/**
   * 通过年份和月份 得到当月的日子
   *
   * @param year
   * @param month
   * @return
 */
  public int getMonthDays(int year, int month) {
    month++;
    switch (month) {
      case 1:
      case 3:
      case 5:
      case 7:
      case 8:
      case 10:
      case 12:
        return 31;
      case 4:
      case 6:
      case 9:
      case 11:
        return 30;
      case 2:
        if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
          return 29;
        } else {
          return 28;
        }
      default:
        return -1;
    }
}

GalleryAdapter

class GalleryAdapter extends RecyclerView.Adapter {

  private LayoutInflater mInflater;
  private List mDatas;
  /**
   * 用来记录点击的item
   */
  private int selectedPos;
  private boolean isClick;

  public GalleryAdapter(Context context, List data) {
    mInflater = LayoutInflater.from(context);
    this.mDatas = data;
  }

  public void setList(List data) {
    this.mDatas = data;
    isClick = false;
  }

  public static class ViewHolder extends RecyclerView.ViewHolder {
    public ViewHolder(View view) {
      super(view);
      tv1 = (TextView) view.findViewById(R.id.textView1);
      tv2 = (TextView) view.findViewById(R.id.textView2);
      linearLayout = (LinearLayout) view.findViewById(R.id.ll);
    }

    TextView tv1;
    TextView tv2;
    LinearLayout linearLayout;
  }

  @Override
  public int getItemCount() {
    return mDatas.size();
  }

  /**
   * 创建ViewHolder
   */
  @Override
  public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = mInflater.inflate(R.layout.cell, null);
    ViewHolder viewHolder = new ViewHolder(view);
    return viewHolder;
  }

  /**
   * 设置值
   */
  @Override
  public void onBindViewHolder(final ViewHolder viewHolder, final int i) {

    if (!isClick) {
      selectedPos = Integer.valueOf(mDatas.get(i).getmCurrDay());
      selectedPos -= 1;
    }

    viewHolder.tv1.setText(mDatas.get(i).getDay());
    viewHolder.tv2.setText(mDatas.get(i).getMonth());

    if (selectedPos == i) {
      viewHolder.linearLayout.setSelected(true);
    } else {
      viewHolder.linearLayout.setSelected(false);
    }

    //如果设置了回调,则设置点击事件
    if (mOnItemClickLitener != null) {
      viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          isClick = true;
          clearSelection(i);
          notifyDataSetChanged();
          String date = mDatas.get(i).getMonth() + mDatas.get(i).getDay();
          mOnItemClickLitener.onItemClick(viewHolder.itemView, i, date);
        }
      });
    }

  }

  public void clearSelection(int pos) {
    selectedPos = pos;
  }

  private OnItemClickLitener mOnItemClickLitener;

  public interface OnItemClickLitener {
    void onItemClick(View view, int position, String date);
  }

  public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener) {
    this.mOnItemClickLitener= mOnItemClickLitener;
}

给左右的ImageView设置点击事件

 ivLeft.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        data.clear();
        data.addAll(onLeftClick(mSelYear, mSelMonth, mSelDay));
        mAdapter.setList(data);
        mAdapter.notifyDataSetChanged();
        mRecyclerView.scrollToPosition(0);
      }
    });

  ivRight.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        data.clear();
        data.addAll(onRightClick(mSelYear, mSelMonth, mSelDay));
        mAdapter.setList(data);
        mAdapter.notifyDataSetChanged();
        mRecyclerView.scrollToPosition(0);
      }
    });

 /**
   * 左点击,日历向后翻页
   */
  public List onLeftClick(int mSelYear, int mSelMonth, int mSelDay) {
    int year = mSelYear;
    int mOnth= mSelMonth;
    int day = mSelDay;

    if (mOnth== 0) {//若果是1月份,则变成12月份
      year = mSelYear - 1;
      mOnth= 11;
    } else if (getMonthDays(year, month) == day) {
      //如果当前日期为该月最后一点,当向前推的时候,就需要改变选中的日期
      mOnth= month - 1;
      day = getMonthDays(year, month);
    } else {
      mOnth= month - 1;
    }

    return init(year, month, day, 1);
  }

  /**
   * 右点击,日历向后翻页
   */
  public List onRightClick(int mSelYear, int mSelMonth, int mSelDay) {
    int year = mSelYear;
    int mOnth= mSelMonth;
    int day = mSelDay;
    if (mOnth== 11) {//若果是12月份,则变成1月份
      year = mSelYear + 1;
      mOnth= 0;
    } else if (getMonthDays(year, month) == day) {
      //如果当前日期为该月最后一点,当向前推的时候,就需要改变选中的日期
      mOnth= month + 1;
      day = getMonthDays(year, month);
    } else {
      mOnth= month + 1;
    }
    return init(year, month, day, 1);
}

给adapter设置item的点击事件

mAdapter.setOnItemClickLitener(new GalleryAdapter.OnItemClickLitener() {
      @Override
      public void onItemClick(View view, int position, String date) {
        Toast.makeText(context.getApplicationContext(), date, Toast.LENGTH_SHORT).show();
      }
    });

以上完成后即可在activity中使用


大功告成。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • Android 九宫格布局详解及实现:人人网应用示例
    本文深入探讨了人人网Android应用中独特的九宫格布局设计,解析其背后的GridView实现原理,并提供详细的代码示例。这种布局方式不仅美观大方,而且在现代Android应用中较为少见,值得开发者借鉴。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文探讨了 RESTful API 和传统接口之间的关键差异,解释了为什么 RESTful API 在设计和实现上具有独特的优势。 ... [详细]
  • 本文详细介绍了如何使用Spring Boot进行高效开发,涵盖了配置、实例化容器以及核心注解的使用方法。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 将Web服务部署到Tomcat
    本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 本文介绍如何在 Unity 的 XML 配置文件中,将参数传递给自定义生命周期管理器的构造函数。我们将详细探讨 CustomLifetimeManager 类的实现及其配置方法。 ... [详细]
  • 本文详细介绍了 Java 中 org.apache.xmlbeans.SchemaType 类的 getBaseEnumType() 方法,提供了多个代码示例,并解释了其在不同场景下的使用方法。 ... [详细]
author-avatar
锦瑟刻下两段缠绵
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有