基于Android week view仿小米和iphone日历效果

前言

最近由于项目需求,要做一个仿小米日历的功能,下面显示一天的日程,header以周为单位进行滑动,github上找了很久也没有找到合适的,但找到一相近的开源项目Android-week-view,它不是我们项目所需要的效果,但是它帮我们实现的Event的添加和事件的处理,这让我们省了不少工作,Android-week-view效果如下图

废话不多说,先看看我项目中的效果

主要包括两个核心的类,两个定义控件,上面的WeekHeaderView和下面的WeekDayView,都是继承的view,然后计算位置,将上面的week label 和下面的Day text 画上去,通过Scroller和 GestureDetector控制滑动和处理各种事件。废话不多说,直接教大家怎么用。

首先是布局文件,大家可以通过属性去控件文字的大小,背影颜色、焦点颜色等等。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity"> 

  <TextView
    android:id="@+id/tv_date"
    android:layout_width="match_parent"
    android:layout_height="30dp"
    android:background="#455964"
    android:gravity="center"
    android:text="2015年1月"
    android:textColor="#ffffff"
    android:textSize="16sp"/> 

  <com.guojunustb.library.WeekHeaderView
    android:id="@+id/weekheaderview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/tv_date"
    app:firstDayOfWeek2="sunday"
    app:headerBackgroundColor="#455964"
    app:headerDayLabelNormalTextColor="#ffffff"
    app:headerDayLabelTextSize="20sp"
    app:headerDayLabelTodayTextColor="@android:color/holo_red_dark"
    app:headerFocusBackgroundColor="#ffffff"
    app:headerFocusSameDayBackgroundColor="#ffffff"
    app:headerFocusSameDayTextColor="#000000"
    app:headerFocusTextColor="#000000"
    app:headerPaddingTop="20dp"
    app:headerRowGap="40dp"
    app:headerWeekLabelTextColor="#ffffff"
    app:headerWeekLabelTextSize="16sp" /> 

  <com.guojunustb.library.WeekDayView
    android:id="@+id/weekdayview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/weekheaderview"
    android:visibility="visible"
    app:columnGap="8dp"
    app:dayBackgroundColor="#ffffffff"
    app:eventTextColor="@android:color/white"
    app:headerColumnBackground="#ffffffff"
    app:headerColumnPadding="8dp"
    app:headerColumnTextColor="@color/toolbar_text"
    app:headerRowBackgroundColor="#465a65"
    app:headerRowPadding="12dp"
    app:hourHeight="60dp"
    app:noOfVisibleDays="1"
    app:textSize="12sp"
    app:todayBackgroundColor="#1848adff"
    app:todayHeaderTextColor="@color/accent" />
</RelativeLayout> 

java代码

package com.guojunutb.weekview; 

import android.app.Activity;
import android.graphics.RectF;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast; 

import com.guojunustb.library.DateTimeInterpreter;
import com.guojunustb.library.WeekDayView;
import com.guojunustb.library.WeekHeaderView;
import com.guojunustb.library.WeekViewEvent; 

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale; 

/**
 *
 */
public class MainActivity extends Activity implements WeekDayView.MonthChangeListener,
    WeekDayView.EventClickListener, WeekDayView.EventLongPressListener,WeekDayView.EmptyViewClickListener,WeekDayView.EmptyViewLongPressListener,WeekDayView.ScrollListener {
  //view
  private WeekDayView mWeekView;
  private WeekHeaderView mWeekHeaderView;
  private TextView mTv_date; 

  List<WeekViewEvent> mNewEvent = new ArrayList<WeekViewEvent>();
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    assignViews();
  } 

  private void assignViews() {
    mWeekView = (WeekDayView) findViewById(R.id.weekdayview);
    mWeekHeaderView= (WeekHeaderView) findViewById(R.id.weekheaderview);
    mTv_date =(TextView)findViewById(R.id.tv_date);
    //init WeekView
    mWeekView.setMonthChangeListener(this);
    mWeekView.setEventLongPressListener(this);
    mWeekView.setOnEventClickListener(this);
    mWeekView.setScrollListener(this);
    mWeekHeaderView.setDateSelectedChangeListener(new WeekHeaderView.DateSelectedChangeListener() {
      @Override
      public void onDateSelectedChange(Calendar oldSelectedDay, Calendar newSelectedDay) {
        mWeekView.goToDate(newSelectedDay);
      }
    });
    mWeekHeaderView.setScrollListener(new WeekHeaderView.ScrollListener() {
      @Override
      public void onFirstVisibleDayChanged(Calendar newFirstVisibleDay, Calendar oldFirstVisibleDay) {
        mWeekView.goToDate(mWeekHeaderView.getSelectedDay());
      }
    });
    setupDateTimeInterpreter(false); 

  } 

  /**
   * Set up a date time interpreter which will show short date values when in week view and long
   * date values otherwise.
   *
   * @param shortDate True if the date values should be short.
   */
  private void setupDateTimeInterpreter(final boolean shortDate) {
    final String[] weekLabels={"日","一","二","三","四","五","六"};
    mWeekView.setDateTimeInterpreter(new DateTimeInterpreter() {
      @Override
      public String interpretDate(Calendar date) {
        SimpleDateFormat weekdayNameFormat = new SimpleDateFormat("EEE", Locale.getDefault());
        String weekday = weekdayNameFormat.format(date.getTime());
        SimpleDateFormat format = new SimpleDateFormat("d", Locale.getDefault());
        return format.format(date.getTime());
      } 

      @Override
      public String interpretTime(int hour) {
        return String.format("%02d:00", hour); 

      } 

      @Override
      public String interpretWeek(int date) {
        if(date>7||date<1){
          return null;
        }
        return weekLabels[date-1];
      }
    });
  } 

  @Override
  public List<WeekViewEvent> onMonthChange(int newYear, int newMonth) { 

    // Populate the week view with some events.
    List<WeekViewEvent> events = new ArrayList<WeekViewEvent>(); 

    Calendar startTime = Calendar.getInstance();
    startTime.set(Calendar.HOUR_OF_DAY, 3);
    startTime.set(Calendar.MINUTE, 0);
    startTime.set(Calendar.MONTH, newMonth - 1);
    startTime.set(Calendar.YEAR, newYear);
    Calendar endTime = (Calendar) startTime.clone();
    endTime.add(Calendar.HOUR, 1);
    endTime.set(Calendar.MONTH, newMonth - 1);
    WeekViewEvent event = new WeekViewEvent(1, "This is a Event!!", startTime, endTime);
    event.setColor(getResources().getColor(R.color.event_color_01));
    events.add(event); 

    startTime = Calendar.getInstance();
    startTime.set(Calendar.HOUR_OF_DAY, 3);
    startTime.set(Calendar.MINUTE, 30);
    startTime.set(Calendar.MONTH, newMonth - 1);
    startTime.set(Calendar.YEAR, newYear);
    endTime = (Calendar) startTime.clone();
    endTime.set(Calendar.HOUR_OF_DAY, 4);
    endTime.set(Calendar.MINUTE, 30);
    endTime.set(Calendar.MONTH, newMonth - 1);
    event = new WeekViewEvent(10, getEventTitle(startTime), startTime, endTime);
    event.setColor(getResources().getColor(R.color.event_color_02));
    events.add(event); 

    startTime = Calendar.getInstance();
    startTime.set(Calendar.HOUR_OF_DAY, 4);
    startTime.set(Calendar.MINUTE, 20);
    startTime.set(Calendar.MONTH, newMonth - 1);
    startTime.set(Calendar.YEAR, newYear);
    endTime = (Calendar) startTime.clone();
    endTime.set(Calendar.HOUR_OF_DAY, 5);
    endTime.set(Calendar.MINUTE, 0);
    event = new WeekViewEvent(10, getEventTitle(startTime), startTime, endTime);
    event.setColor(getResources().getColor(R.color.event_color_03));
    events.add(event); 

    startTime = Calendar.getInstance();
    startTime.set(Calendar.HOUR_OF_DAY, 5);
    startTime.set(Calendar.MINUTE, 30);
    startTime.set(Calendar.MONTH, newMonth - 1);
    startTime.set(Calendar.YEAR, newYear);
    endTime = (Calendar) startTime.clone();
    endTime.add(Calendar.HOUR_OF_DAY, 2);
    endTime.set(Calendar.MONTH, newMonth - 1);
    event = new WeekViewEvent(2, getEventTitle(startTime), startTime, endTime);
    event.setColor(getResources().getColor(R.color.event_color_02));
    events.add(event);
    startTime = Calendar.getInstance();
    startTime.set(Calendar.HOUR_OF_DAY, 5);
    startTime.set(Calendar.MINUTE, 30);
    startTime.set(Calendar.MONTH, newMonth - 1);
    startTime.set(Calendar.YEAR, newYear);
    endTime = (Calendar) startTime.clone();
    endTime.add(Calendar.HOUR_OF_DAY, 2);
    endTime.set(Calendar.MONTH, newMonth - 1);
    event = new WeekViewEvent(2, "dddd", startTime, endTime);
    event.setColor(getResources().getColor(R.color.event_color_01));
    events.add(event);
    startTime = Calendar.getInstance();
    startTime.set(Calendar.HOUR_OF_DAY, 5);
    startTime.set(Calendar.MINUTE, 0);
    startTime.set(Calendar.MONTH, newMonth - 1);
    startTime.set(Calendar.YEAR, newYear);
    startTime.add(Calendar.DATE, 1);
    endTime = (Calendar) startTime.clone();
    endTime.add(Calendar.HOUR_OF_DAY, 3);
    endTime.set(Calendar.MONTH, newMonth - 1);
    event = new WeekViewEvent(3, getEventTitle(startTime), startTime, endTime);
    event.setColor(getResources().getColor(R.color.event_color_03));
    events.add(event); 

    startTime = Calendar.getInstance();
    startTime.set(Calendar.DAY_OF_MONTH, 15);
    startTime.set(Calendar.HOUR_OF_DAY, 3);
    startTime.set(Calendar.MINUTE, 0);
    startTime.set(Calendar.MONTH, newMonth - 1);
    startTime.set(Calendar.YEAR, newYear);
    endTime = (Calendar) startTime.clone();
    endTime.add(Calendar.HOUR_OF_DAY, 3);
    event = new WeekViewEvent(4, getEventTitle(startTime), startTime, endTime);
    event.setColor(getResources().getColor(R.color.event_color_04));
    events.add(event); 

    startTime = Calendar.getInstance();
    startTime.set(Calendar.DAY_OF_MONTH, 1);
    startTime.set(Calendar.HOUR_OF_DAY, 3);
    startTime.set(Calendar.MINUTE, 0);
    startTime.set(Calendar.MONTH, newMonth - 1);
    startTime.set(Calendar.YEAR, newYear);
    endTime = (Calendar) startTime.clone();
    endTime.add(Calendar.HOUR_OF_DAY, 3);
    event = new WeekViewEvent(5, getEventTitle(startTime), startTime, endTime);
    event.setColor(getResources().getColor(R.color.event_color_01));
    events.add(event); 

    startTime = Calendar.getInstance();
    startTime.set(Calendar.DAY_OF_MONTH, startTime.getActualMaximum(Calendar.DAY_OF_MONTH));
    startTime.set(Calendar.HOUR_OF_DAY, 15);
    startTime.set(Calendar.MINUTE, 0);
    startTime.set(Calendar.MONTH, newMonth - 1);
    startTime.set(Calendar.YEAR, newYear);
    endTime = (Calendar) startTime.clone();
    endTime.add(Calendar.HOUR_OF_DAY, 3);
    event = new WeekViewEvent(5, getEventTitle(startTime), startTime, endTime);
    event.setColor(getResources().getColor(R.color.event_color_02));
    events.add(event);
    events.addAll(mNewEvent);
    return events;
  } 

  private String getEventTitle(Calendar time) {
    return String.format("Event of %02d:%02d %s/%d", time.get(Calendar.HOUR_OF_DAY), time.get(Calendar.MINUTE), time.get(Calendar.MONTH) + 1, time.get(Calendar.DAY_OF_MONTH));
  } 

  @Override
  public void onEventClick(WeekViewEvent event, RectF eventRect) {
    Toast.makeText(MainActivity.this, "Clicked " + event.getName(), Toast.LENGTH_SHORT).show();
  } 

  @Override
  public void onEventLongPress(WeekViewEvent event, RectF eventRect) {
    Toast.makeText(MainActivity.this, "Long pressed event: " + event.getName(), Toast.LENGTH_SHORT).show();
  } 

  @Override
  public void onEmptyViewClicked(Calendar time) {
    Toast.makeText(MainActivity.this, "Empty View clicked " + time.get(Calendar.YEAR) + "/" + time.get(Calendar.MONTH) + "/" + time.get(Calendar.DAY_OF_MONTH), Toast.LENGTH_LONG).show();
  } 

  @Override
  public void onEmptyViewLongPress(Calendar time) {
    Toast.makeText(MainActivity.this, "Empty View long clicked " + time.get(Calendar.YEAR) + "/" + time.get(Calendar.MONTH) + "/" + time.get(Calendar.DAY_OF_MONTH), Toast.LENGTH_LONG).show(); 

  } 

  @Override
  public void onFirstVisibleDayChanged(Calendar newFirstVisibleDay, Calendar oldFirstVisibleDay) { 

  } 

  @Override
  public void onSelectedDaeChange(Calendar selectedDate) {
    mWeekHeaderView.setSelectedDay(selectedDate);
    mTv_date.setText(selectedDate.get(Calendar.YEAR)+"年"+(selectedDate.get(Calendar.MONTH)+1)+"月");
  }
} 

WeekHeaderView 和WeekDayView相互监听对方的滑动才能实现联动。第一次写博客,就说这么多了,有兴趣的朋友可以去github,下载源码看看,我就不再献丑了。

下载地址:Sample-android-week-view

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

(0)

相关推荐

  • android 开发教程之日历项目实践(二)

    一.创建 Android Project 在新建对话框中输入 App 属性,SDK版本全部选最新的,不作版本兼容.主题选择 Holo Dark. 下一步,使用默认设置 下一步,使用默认设置 下一步,使用默认配置 下一步,使用默认设置 创建完成后的初始画面 在上面的步骤中,我们选择了创建 MainActivity,ADT 帮我们在 src 目录下生成了 MainActivity.java 文件,在 res/layout/ 目录下生成了 activity_main.xml 文件,并在编辑窗口打开,如

  • Android实现日历控件示例代码

    做的是一个酒店的项目,可以选择入住和离开的日期.声明为了省事在网上找的资料,自己修改的逻辑,希望对需要的朋友有帮助.喜欢的给个好评.谢谢啦!祝生活愉快! 先上图 第一步,搭建布局xml <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_w

  • android 开发教程之日历项目实践(三)

    二.创建样式 日历显示的表格线,使用 Cell 填充图形的边框来实现,为了统一,我们先定义边框线的颜色及线条精细. 另外还要定义一系统填充样式等. 创建 color: color_calendar_border 表格线color_calendar_title_gregorian 标题栏日期年月文字的颜色color_calendar_title_lunar 标题栏农历color_calendar_title_startcolor_calendar_title_endcolor_calendar_t

  • Android实现自定义日历

    自定义日历控件,支持旧历.节气.日期标注.点击操作 (参考网络上的日历控件改写) 注:将下面的四张资源图片拷贝到所建包的下一个image目录中,如Calendar.java 所在包为 cc.util.android.view,则需要再创建一个包cc.util.android.view.image 然后将图片拷贝进去 /****************从此出开始将代码拷贝到一个文件中*******************/ package cc.util.android.view; import

  • android自定义view之实现日历界面实例

    现在网上有很多自定义view实现日历的demo,今天讲一讲如何自己实现这个自定义view. 看一下最终效果图: 在这个自定义view中,我使用了各种奇技淫巧的方法来实现这个日历,真是费尽心思.废话少说,开始进坑. 界面分析 头部是一个textview,显示年份和月份,然后下边一行是星期几,这两行可以固定住,不随月份切换而进出屏幕. 再下边就是我们自定义view 的主角,每个月的天数.目前规定是星期日为每星期第一天.上个月的天数填充满第一行,下个月的前几天填充完最后一行,颜色设置为灰色,本月日期中

  • java制作android 日历代码分享

    代码很简单,就不多废话了 复制代码 代码如下: //读取日历事件     public static void getCalendarInfo(Activity activity,String tag){         String[] projection = new String[]{CalendarContract.Events._ID,CalendarContract.Events.TITLE};         ContentResolver cr = activity.getCon

  • Android自定义日历Calender代码实现

    产品要做签到功能,签到功能要基于一个日历来进行,所以就根据 要求自定义了一个日历 自定义控件相信做android都知道: (1)首先创建一个类,继承一个容器类或者是一个控件 (2)然后就是你需要设置的属性等的,在attrs文件夹中 (3)然后就是在类里边进行属性的设置以及布局等等功能的添加 其实自定义一个日历问题都不多,很多人都会想到通过一个gridView然后填充就可以,确实是这样,主要是在显示每个月的第一天的位置以及每个月显示多少天有点绕. 思路:通过判断当前星期几然后进行日历的填充,但是填

  • Android自定义日历控件实例详解

    为什么要自定义控件 有时,原生控件不能满足我们对于外观和功能的需求,这时候可以自定义控件来定制外观或功能:有时,原生控件可以通过复杂的编码实现想要的功能,这时候可以自定义控件来提高代码的可复用性. 如何自定义控件 下面我通过我在github上开源的Android-CalendarView项目为例,来介绍一下自定义控件的方法.该项目中自定义的控件类名是CalendarView.这个自定义控件覆盖了一些自定义控件时常需要重写的一些方法. 构造函数 为了支持本控件既能使用xml布局文件声明,也可在ja

  • Android 一个日历控件的实现代码

    先看几张动态的效果图吧! 项目地址:https://github.com/Othershe/CalendarView 这里主要记录一下在编写日历控件过程中一些主要的点: 一.主要功能 1.支持农历.节气.常用节假日 2.日期范围设置,默认支持的最大日期范围[1900.1~2049.12] 3.默认选中日期设置 4.单选.多选 5.跳转到指定日期 6.通过自定义属性定制日期外观,以及简单的日期item布局配置 二.基本结构 我们要实现的日历控件采用ViewPager作为主框架,CalendarVi

  • android 开发教程之日历项目实践(一)

    前言:决定开始学习 Android 平台下的软件开发,以日历作为实践项目,进行一周后,基本完成. 为了总结及笔记,并给有需要的朋友借鉴,开始整理本教程. 开始之前: 在编写程序之前,需要进行项目设计,因为是练习项目,主要是确定软件 UI 界面,这是已经完成的屏幕截图: 对这个画面,进一步作分解: 这里总共分解为三个 View 文件: 1:activity_main.xml 作为启动的主画面,新建项目时,首先生成. 2:view_calendar_table.xml 定义月历视图,头部固定,其它行

随机推荐