基于Android week view仿小米和iphone日歷效果
前言
最近由于項(xiàng)目需求,要做一個(gè)仿小米日歷的功能,下面顯示一天的日程,header以周為單位進(jìn)行滑動(dòng),github上找了很久也沒(méi)有找到合適的,但找到一相近的開(kāi)源項(xiàng)目Android-week-view,它不是我們項(xiàng)目所需要的效果,但是它幫我們實(shí)現(xiàn)的Event的添加和事件的處理,這讓我們省了不少工作,Android-week-view效果如下圖

廢話不多說(shuō),先看看我項(xiàng)目中的效果


主要包括兩個(gè)核心的類,兩個(gè)定義控件,上面的WeekHeaderView和下面的WeekDayView,都是繼承的view,然后計(jì)算位置,將上面的week label 和下面的Day text 畫上去,通過(guò)Scroller和 GestureDetector控制滑動(dòng)和處理各種事件。廢話不多說(shuō),直接教大家怎么用。
首先是布局文件,大家可以通過(guò)屬性去控件文字的大小,背影顏色、焦點(diǎn)顏色等等。
<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相互監(jiān)聽(tīng)對(duì)方的滑動(dòng)才能實(shí)現(xiàn)聯(lián)動(dòng)。第一次寫博客,就說(shuō)這么多了,有興趣的朋友可以去github,下載源碼看看,我就不再獻(xiàn)丑了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實(shí)現(xiàn)可滑動(dòng)的自定義日歷控件
- Android實(shí)現(xiàn)帶簽到贏積分功能的日歷
- Android可簽到日歷控件的實(shí)現(xiàn)方法
- Android自定義日歷滑動(dòng)控件
- Android自定義可標(biāo)記日歷效果
- Android自定義控件實(shí)現(xiàn)可多選課程日歷CalendarView
- Android 一個(gè)日歷控件的實(shí)現(xiàn)代碼
- Android實(shí)現(xiàn)自定義日歷
- android 開(kāi)發(fā)教程之日歷項(xiàng)目實(shí)踐(一)
- Android自定義日歷效果
相關(guān)文章
Android UI設(shè)計(jì)與開(kāi)發(fā)之PopupWindow仿騰訊新聞底部彈出菜單
這篇文章主要為大家詳細(xì)介紹了Android UI設(shè)計(jì)與開(kāi)發(fā)之PopupWindow仿騰訊新聞底部彈出菜單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android中利用xml文件布局修改Helloworld程序
這篇文章主要介紹了Android中利用xml文件布局修改Helloworld程序 的相關(guān)資料,需要的朋友可以參考下2016-07-07
Android 實(shí)現(xiàn)自定義圓形listview功能的實(shí)例代碼
這篇文章主要介紹了Android 實(shí)現(xiàn)自定義圓形listview功能的實(shí)例代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
Android自定義View實(shí)現(xiàn)時(shí)鐘效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)時(shí)鐘效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
android okhttp的基礎(chǔ)使用【入門推薦】
本文主要總結(jié)了Android著名網(wǎng)絡(luò)框架-okhttp的基礎(chǔ)使用。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-01-01
android配合viewpager實(shí)現(xiàn)可滑動(dòng)的標(biāo)簽欄示例分享
本文主要介紹了android實(shí)現(xiàn)可滑動(dòng)的標(biāo)簽欄示例,配合viewpager作為標(biāo)簽欄,且可以設(shè)置每頁(yè)顯示的標(biāo)簽個(gè)數(shù),超出可滑動(dòng)顯示,需要的朋友可以參考下2014-02-02
Android布局——Preference自定義layout的方法
PreferenceActivity是一個(gè)方便設(shè)置管理的界面,但是對(duì)于界面顯示來(lái)說(shuō)比較單調(diào),所以自定義布局就很有必要了,下面與大家分享下Preference中自定義layout的方法2013-06-06

