KLWPでカレンダーその2:月間カレンダーを作ってみる(当日印つき)

20161119-klwp-1

前回の週間カレンダーに引き続き、今回はKLWPを使って月間カレンダーを作ります。

月間カレンダー自体はGlaejaでもZooper Widgetでも作成できましたが、KLWPで作ってみたところ、面倒なのは変わりませんが、配布した時に利用者がある程度簡単にカスタマイズできるもの(コンポーネント)を作ることができました。もちろん、今回作成したものも最後にダウンロードできるようにします。

0.はじめに

まず最初に。今回私もコンポーネントを配布しますが、Playストアにも月間カレンダーのコンポーネントを配布している人は複数います。はっきり言って、自分で作るよりもこれらのコンポーネントを利用したほうが楽です。どれもある程度は自分でカスタマイズできるようになっていると思います。

Google playkCalendar for Kustom
kCalendar for Kustom
制作: I Am Topher
評価: 4.5 / 5段階中
価格: 無料 (2016/11/19 時点)

ダウンロードposted by: AndroidHTML v3.0

Google playSimple Calendar for KLWP
Simple Calendar for KLWP
制作: easy.dev
評価: 3.9 / 5段階中
価格: 無料 (2016/11/19 時点)

ダウンロードposted by: AndroidHTML v3.0

今回私が作成して配布するコンポーネントは、おそらくこれらよりも機能的には劣っていると思います。上記のものは週始まりの曜日を選べたりもします。なのでこれらを使っておけばOKです。

どうしても、どうしてもカスタマイズしたい部分がどうにもならない場合は、自分で作るしかありませんが、面倒です。ええ、本当に面倒でした。

とりあえず、私が作成したものは以下の様なものです。

20161119-klwp-220161119-klwp-320161119-klwp-4

一応、フォントやそのサイズ、余白などはある程度変更できるようになっています。今日を示す部分は丸、四角、六角形を選べて、枠か塗りつぶしかも選べます。もちろんうるう年にも対応してます。

1.考え方

月間カレンダーを作る上で、まず必要なのは考え方です。考え方によって作り方は変わってきます。今回は「◯週目×曜日という『枠』があり、そこに表示される数字はなにか?」という考えで作っています。なので枠は固定され、今月の日数や曜日配置に関わらず6週間表示されます。

この方式で作成する場合、月間カレンダーを3つの領域に分けて考えました。

20161119-klwp-5s

1週間は7日。月間カレンダーの最小は28日4週で終わるものです。対して最大は31日6週に渡る場合です。これを考えた時、上から

  • 前月の最終週が表示される可能性がある週(×1)
  • 当月の数字のみが表示される週(×3)
  • 来月の最初週が表示される可能性がある週(×2)

となります。
なので、この3つの週の作り方も分けて考える必要があります。

20161119-klwp-9

それぞれの「週」ごとにグループ化(並べる)で作成し、中にある「日」はグループ化(重ねる)で作成しています。つまり6週×7日で42個の「日」を作っていくことになります。

ある程度はコピペでなんとかなりますが、微妙に数値を変えていくことが多いので面倒です。

2.グローバル変数

月間カレンダーを作る上で必要な値があります。KLWPの標準で取得できない値なので計算式で算出し、それをグローバル変数として簡単に取り出せるようにしておきます。

前月最終日 pmld

20161119-klwp-6

まずは前月最終日です。これは前項の「前月の最終週が表示される可能性がある週」で使います。

求め方は簡単で、現在の月から前月が30日終わりなのか31日終わりなのかを表示させているだけです。スマートな計算式ではなく、単純に「今月が11月なら前月は10月なので30日終わり」ということをやっています。

ただしうるう年だけは計算しています。

$if(df(M)=3&(df(y)%4=0&df(y)%100!=0|df(y)%400=0),29,df(M)=3,28,df(M)=5|df(M)=7|df(M)=10|df(M)=12,30,31)$

今月の最終日 rmld

20161119-klwp-7

続いて今月の最終日です。これは前項の「来月の最初週が表示される可能性がある週」で使います。

基本的には先ほどの「前月の最終日」と同じで、数字を入れ替えているだけですね。

$if(df(M)=2&(df(y)%4=0&df(y)%100!=0|df(y)%400=0),29,df(M)=2,28,df(M)=4|df(M)=6|df(M)=9|df(M)=11,30,31)$

2週目最初の日 day

20161119-klwp-8

最後は2週目最初の日です。これは前項の「当月の数字のみが表示される週」で主に使います。

$if(df(f,1d)=7,2,df(f,1d)=6,3,df(f,1d)=5,4,df(f,1d)=4,5,df(f,1d)=3,6,df(f,1d)=2,7,8)$

これは、$df(f,1d)$で当月1日の曜日を数字で取得できるので、それに合わせて求めています。単純に、1日の曜日が7、つまり日曜なら2週目最初の日は2、1日の曜日が6、つまり土曜なら2週目最初の日は3ということです。

その他

今回重要なのは上の3つですが、ほかにもグローバル変数を作っておくと便利です。今回の方法は日ごとに別のアイテムとなるので、まとめてフォントを変更したい、色を変えたい、という時に備えます。フォントサイズや色などをグローバル変数で作っておけば全部をまとめて変更できます。

私が作成したものの場合は、「フォント」「平日の色」「土曜の色」「日曜の色」「前月・次月の色」「フォントサイズ」「数時間の余白」「当日を現す図形」「当日を現す図形のモード」といった項目をグローバル変数化しました。

3.前月の最終週が表示される可能性がある週

20161119-klwp-1020161119-klwp-11

まずは「前月の最終週が表示される可能性がある週」です。上の画像は1週目水曜日部分の表示です。日付は以下の式で表示されます。

$if(df(f,1d)=7,gv(pmld)-3,df(f,1d)=6,gv(pmld)-2,df(f,1d)=5,gv(pmld)-1,df(f,1d)=4,gv(pmld),df(f,1d)=3,1,df(f,1d)=2,2,3

基本的にif文です。最初の方から説明すると、df(f,1d)=7,gv(pmld)-3はdf(f,1d)=7、つまり「今月の1日が日曜なら」という条件です。それが正ならgv(pmld)-3を返します。
gv(pmld)というのは先に作ったグローバル変数pmld、「前月最終日の値」です。今月1日が日曜なら水曜であるこの枠に表示されるのはその4日前、前月最終日の3日前なので「gv(pmld)-3」ということです。

基本の考えはこれで、最初週の他の日はこれをコピペして数値をずらしていきます。木曜日の枠なら…

$if(df(f,1d)=7,gv(pmld)-2,df(f,1d)=6,gv(pmld)-1,df(f,1d)=5,gv(pmld),df(f,1d)=4,1,df(f,1d)=3,2,df(f,1d)=2,3,4

となります。
これで1週目が完成です。

4.当月の数字のみが表示される週

2週目から4週目までの3週間はかなり単純です。

20161119-klwp-1220161119-klwp-13

まず2週目最初の枠は、あらかじめグローバル変数で作っています。なのでそれを呼び出す$gv(day)$だけで終わりです。

20161119-klwp-1420161119-klwp-15

それ以降、4週目の最終日までは、単純に「2週目最初の日から何日後か」というのを表示しています。3週目水曜日なら「2週目最初の日から9日後」なので$gv(day)+9$です。(画像だと$(gv(day)+9)$と括弧が付いていますが、この括弧は無くても大丈夫です。

これで2-4週目が完成です。

5.来月の最初週が表示される可能性がある週

最後の2週については、単純に$gv(day)+x$とすると32日だとか、6月なのに31日だとかになってしまいます。なので今月が何日までなのか、という判定を入れます。

20161119-klwp-1620161119-klwp-17

これは5週水曜日の枠です。

$if(gv(rmld)<gv(day)+23,gv(day)+23-gv(rmld),gv(day)+23)$

if文です。「gv(rmld)<gv(day)+23」が正なら「gv(day)+23-gv(rmld)」を、そうでなければ「gv(day)+23」を表示します。
gv(rmld)というのは先に作ったグローバル変数で「今月の最終日」を現します。また、gv(day)+23というのは2から4週までと同じ(続き)です。つまり「今月の最終日が第2週の最初の日+23よりも小さければ」というのが条件になっています。逆に言うと「第2週の最初の日+23」が最終日よりも大きな数字になっている状態、32日などになっている場合です。

この時に表示されるのは「gv(day)+23-gv(rmld)」となります。「gv(day)+23」から「gv(rmld)」を引くことで、今月最終日からプラス何日なのか、という表示です。つまりこれは来月の日付そのものです。

条件が負の場合は、そのまま「gv(day)+23」が表示されます。

5.6週目はこれを元にコピペして数字をずらしていけば完成です。

20161119-klwp-1820161119-klwp-19

ただし、今月の数字が表示されるのは最大(1日が日曜で31日までの月)でも6週の火曜日までです。なので6週水曜以降の枠は先ほどの条件式が正の場合しかありませんので、式自体も$gv(day)+30-gv(rmld)$といった部分だけで大丈夫です。

これで1週から6週まで、すべて数字は表示できました。一応の月間カレンダーの完成です。

6.当日に◯などの印を表示

せっかくの月間カレンダーなので、当日を示す図形を表示します。
こう書くと「図形のアイテムを表示させて、その位置を計算式で調整する」という方法がまず浮かびますが、それは(できるのかもしれませんが考えるのが)面倒なので、もっと単純な方法で実現します。

20161119-klwp-2020161119-klwp-2120161119-klwp-22

まず日付を収納する「グループ化(重ねる)」の中に「図形」を作成します。(このために日付を「グループ化(重ねる)」に収納しています。)

図形の色や形は自由です。私の場合はこれもカスタマイズできるようにグローバル変数化しています。そしてこの図形の「色」を計算式で入力できるようにし、以下のようにします。(3週目木曜日の場合)

$if(gv(day)+10=df(d),gc(daycolor),#00000000)$

if文の条件であるgv(day)+10=df(d)というのは、ここに表示される数値gv(day)+10df(d)つまり今日の日付と一致する場合、という意味です。「ここの枠が今日の枠なら」とも言えます。

これが正ならgc(daycolor)を返します。これは別で作ったグローバル変数で「平日のフォントカラー」です。これに限らず今日を示す図形の色用のグローバル変数を別で作ってもいいかもしれません。

負の場合は#00000000を返します。これは透明です。つまり、この枠が今日なら指定した色を、そうでない場合は透明で表示、ということです。これをif文で切り替えているだけです。

見えないだけですべての日付部分に図形があると思ってください。ともかく、これで当日部分に図形を表示できました。

7.完成

月間カレンダーの基本となる部分はこれで完成です。応用すれば前月や次月を含んだ3ヶ月カレンダーも作れるのではないでしょうか。また、配布用に「週の始まりの曜日を選べるようにする」など工夫のしどころはまだまだあります。

いくらか省略した部分もありますが、考え方自体はここまで説明したとおりです。ほかにも方法があるかもしれませんが、私の場合はこれで月間カレンダーを実現しました。けっこう力技ですよね…。コピペ→数値を修正という作業が地味に面倒でした…。

今回作ったものはコンポーネントとしてダウンロードできるようにしますので、興味ある方は中身を見てみてください。普通に使うだけでもOKです。使いやすいようにある程度ロックを掛けたもの(orecalendar.komp)と、中身を見られるようにロックを掛けていないもの(orecalendar_customizable.komp)の2種類があります。

zooper-iconorecalendar
制作: orefolder
価格: 無料

ダウンロード

zooper-iconorecalendar_customizable
制作: orefolder
価格: 無料

ダウンロード

興味ある方はぜひダウンロードしてみてください。


KLWPの使い方についてはこちらのページにてまとめています。使い方に困ったときなど、こちらのページも参考にしてください。

この記事が気に入ったら
いいね!しよう
 シェアする  ツイートする
PREVIOUS POST
NEXT POST
ANDROID
GIVES YOU
MORE