安卓简单日历的实现
                            
                            
                            最近無聊在做一個項目,需要用到日歷。日歷并不需要太復雜,只需要能夠簡單的查看就行,所以我選用了java提供的Calendar類,和安卓的gridView組合的形式.
 
先看效果圖:
 
 
背景什么的先不要管他。只看主體部分,左箭頭查看上個月的,右箭頭查看下個月的.
 
接下來開始我們的日歷。
 
首先,需要使用Calendar自己構造一個DateUtils類,這個相當簡單。
 
import java.util.Calendar;/*** Created by 91905 on 2016/8/22 0022.*/public class DateUtils {/*** 獲取當前年份** @return*/public static int getYear() {return Calendar.getInstance().get(Calendar.YEAR);}/*** 獲取當前月份** @return*/public static int getMonth() {return Calendar.getInstance().get(Calendar.MONTH) + 1;}/*** 獲取當前日期是該月的第幾天** @return*/public static int getCurrentDayOfMonth() {return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);}/*** 獲取當前日期是該周的第幾天** @return*/public static int getCurrentDayOfWeek() {return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);}/*** 獲取當前是幾點*/public static int getHour() {return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);//二十四小時制}/*** 獲取當前是幾分** @return*/public static int getMinute() {return Calendar.getInstance().get(Calendar.MINUTE);}/*** 獲取當前秒** @return*/public static int getSecond() {return Calendar.getInstance().get(Calendar.SECOND);}/*** 根據傳入的年份和月份,獲取當前月份的日歷分布** @param year* @param month* @return*/public static int[][] getDayOfMonthFormat(int year, int month) {Calendar calendar = Calendar.getInstance();calendar.set(year, month - 1, 1);//設置時間為每月的第一天//設置日歷格式數組,6行7列int days[][] = new int[6][7];//設置該月的第一天是周幾int daysOfFirstWeek = calendar.get(Calendar.DAY_OF_WEEK);//設置本月有多少天int daysOfMonth = getDaysOfMonth(year, month);//設置上個月有多少天int daysOfLastMonth = getLastDaysOfMonth(year, month);int dayNum = 1;int nextDayNum = 1;//將日期格式填充數組for (int i = 0; i < days.length; i++) {for (int j = 0; j < days[i].length; j++) {if (i == 0 && j < daysOfFirstWeek - 1) {days[i][j] = daysOfLastMonth - daysOfFirstWeek + 2 + j;} else if (dayNum <= daysOfMonth) {days[i][j] = dayNum++;} else {days[i][j] = nextDayNum++;}}}return days;}/*** 根據傳入的年份和月份,判斷上一個有多少天** @param year* @param month* @return*/public static int getLastDaysOfMonth(int year, int month) {int lastDaysOfMonth = 0;if (month == 1) {lastDaysOfMonth = getDaysOfMonth(year - 1, 12);} else {lastDaysOfMonth = getDaysOfMonth(year, month - 1);}return lastDaysOfMonth;}/*** 根據傳入的年份和月份,判斷當前月有多少天** @param year* @param month* @return*/public static int getDaysOfMonth(int year, int month) {switch (month) {case 1:case 3:case 5:case 7:case 8:case 10:case 12:return 31;case 2:if (isLeap(year)) {return 29;} else {return 28;}case 4:case 6:case 9:case 11:return 30;}return -1;}/*** 判斷是否為閏年** @param year* @return*/public static boolean isLeap(int year) {if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {return true;}return false;}
} 
其中DateUtils類中的 public static int[][] getDayOfMonthFormat(int year, int month) {Calendar calendar = Calendar.getInstance();
    calendar.set(year, month - 1, 1);//設置時間為每月的第一天
    //設置日歷格式數組,6行7列
    int days[][] = new int[6][7];
    //設置該月的第一天是周幾
    int daysOfFirstWeek = calendar.get(Calendar.DAY_OF_WEEK);
    //設置本月有多少天
    int daysOfMonth = getDaysOfMonth(year, month);
    //設置上個月有多少天
    int daysOfLastMonth = getLastDaysOfMonth(year, month);
    int dayNum = 1;
    int nextDayNum = 1;
    //將日期格式填充數組
    for (int i = 0; i < days.length; i++) {for (int j = 0; j < days[i].length; j++) {if (i == 0 && j < daysOfFirstWeek - 1) {days[i][j] = daysOfLastMonth - daysOfFirstWeek + 2 + j;
            } else if (dayNum <= daysOfMonth) {days[i][j] = dayNum++;
            } else {days[i][j] = nextDayNum++;
            }}}return days;
} 
 
是將當前月份的日期分布保存到數組中返回.
 
接下來,布局文件
 
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="center"><ImageViewandroid:id="@+id/record_left"android:layout_width="40dp"android:layout_height="40dp"android:background="@drawable/record_left_press" /></LinearLayout><RelativeLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="2"android:gravity="center"><TextViewandroid:id="@+id/record_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_gravity="center"android:maxLines="1"android:text="2016年8月21日"android:textColor="@color/colorWhite"android:textSize="16sp" /></RelativeLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:layout_weight="1"android:gravity="center"><ImageViewandroid:id="@+id/record_right"android:layout_width="40dp"android:layout_height="40dp"android:background="@drawable/record_right_press" /></LinearLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:layout_marginRight="20dp"android:layout_marginTop="10dp"android:orientation="horizontal"><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="日"android:textColor="@color/colorWhite"android:textSize="16sp" /></LinearLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="一"android:textColor="@color/colorWhite"android:textSize="16sp" /></LinearLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="二"android:textColor="@color/colorWhite"android:textSize="16sp" /></LinearLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="三"android:textColor="@color/colorWhite"android:textSize="16sp" /></LinearLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="四"android:textColor="@color/colorWhite"android:textSize="16sp" /></LinearLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="五"android:textColor="@color/colorWhite"android:textSize="16sp" /></LinearLayout><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="六"android:textColor="@color/colorWhite"android:textSize="16sp" /></LinearLayout></LinearLayout><GridViewandroid:id="@+id/record_gridView"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="20dp"android:numColumns="7" /></LinearLayout> 
GridView的item文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="horizontal"><TextViewandroid:id="@+id/date_item"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/colorWhite"android:textSize="16sp" /> </LinearLayout>
GridView的Adapter文件 import android.content.Context; import android.graphics.Color; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView;import com.jiaoml.smallmusic.MusicApp; import com.jiaoml.smallmusic.R; import com.jiaoml.smallmusic.music.Record; import com.lidroid.xutils.db.sqlite.Selector; import com.lidroid.xutils.db.sqlite.WhereBuilder; import com.lidroid.xutils.exception.DbException;/*** Created by 91905 on 2016/8/24 0024.*/public class DateAdapter extends BaseAdapter {private int[] days = new int[42];private Context context;private int year;private int month;public DateAdapter(Context context, int[][] days, int year, int month) {this.context = context;int dayNum = 0; //將二維數組轉化為一維數組,方便使用for (int i = 0; i < days.length; i++) {for (int j = 0; j < days[i].length; j++) {this.days[dayNum] = days[i][j];dayNum++;}}this.year = year;this.month = month;}@Overridepublic int getCount() {return days.length;}@Overridepublic Object getItem(int i) {return days[i];}@Overridepublic long getItemId(int i) {return i;}@Overridepublic View getView(int i, View view, ViewGroup viewGroup) {ViewHolder viewHolder;if (view == null) {view = LayoutInflater.from(context).inflate(R.layout.date_item, null);viewHolder = new ViewHolder();viewHolder.date_item = (TextView) view.findViewById(R.id.date_item);view.setTag(viewHolder);} else {viewHolder = (ViewHolder) view.getTag();}if (i < 7 && days[i] > 20) {viewHolder.date_item.setTextColor(Color.rgb(204, 204, 204));//將上個月的和下個月的設置為灰色} else if (i > 20 && days[i] < 15) {viewHolder.date_item.setTextColor(Color.rgb(204, 204, 204));} viewHolder.date_item.setText(days[i] + "");return view;}/*** 優化Adapter*/class ViewHolder {TextView date_item;}
接下來是Activity文件 import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.GridView; import android.widget.ImageView; import android.widget.TextView;import com.jiaoml.smallmusic.R; import com.jiaoml.smallmusic.adapter.DateAdapter;/*** Created by 91905 on 2016/8/24 0024.*/public class MainActivity extends Activity implements View.OnClickListener {private GridView record_gridView;//定義gridViewprivate DateAdapter dateAdapter;//定義adapterprivate ImageView record_left;//左箭頭private ImageView record_right;//右箭頭private TextView record_title;//標題private int year;private int month;private String title;private int[][] days = new int[6][7];@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//初始化日期數據initData();//初始化組件initView();//組件點擊監聽事件initEvent();}private void initData() {year = DateUtils.getYear();month = DateUtils.getMonth();}private void initEvent() {record_left.setOnClickListener(this);record_right.setOnClickListener(this);}private void initView() {/*** 以下是初始化GridView*/record_gridView = (GridView) findViewById(R.id.record_gridView);days = DateUtils.getDayOfMonthFormat(2016, 8);dateAdapter = new DateAdapter(this, days, year, month);//傳入當前月的年record_gridView.setAdapter(dateAdapter);record_gridView.setVerticalSpacing(60);record_gridView.setEnabled(false);/*** 以下是初始化其他組件*/record_left = (ImageView) findViewById(R.id.record_left);record_right = (ImageView) findViewById(R.id.record_right);record_title = (TextView) findViewById(R.id.record_title);}/*** 下一個月** @return*/private int[][] nextMonth() {if (month == 12) {month = 1;year++;} else {month++;}days = DateUtils.getDayOfMonthFormat(year, month);return days;}/*** 上一個月** @return*/private int[][] prevMonth() {if (month == 1) {month = 12;year--;} else {month--;}days = DateUtils.getDayOfMonthFormat(year, month);return days;}/*** 設置標題*/private void setTile() {title = year + "年" + month + "月";record_title.setText(title);}@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.record_left:days = prevMonth();dateAdapter = new DateAdapter(this, days, year, month);record_gridView.setAdapter(dateAdapter);dateAdapter.notifyDataSetChanged();setTile();break;case R.id.record_right:days = nextMonth();dateAdapter = new DateAdapter(this, days, year, month);record_gridView.setAdapter(dateAdapter);dateAdapter.notifyDataSetChanged();setTile();break;}} }
OK,一個簡單的日歷就完成了
                            
                        
                        
                        GridView的item文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="horizontal"><TextViewandroid:id="@+id/date_item"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/colorWhite"android:textSize="16sp" /> </LinearLayout>
GridView的Adapter文件 import android.content.Context; import android.graphics.Color; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView;import com.jiaoml.smallmusic.MusicApp; import com.jiaoml.smallmusic.R; import com.jiaoml.smallmusic.music.Record; import com.lidroid.xutils.db.sqlite.Selector; import com.lidroid.xutils.db.sqlite.WhereBuilder; import com.lidroid.xutils.exception.DbException;/*** Created by 91905 on 2016/8/24 0024.*/public class DateAdapter extends BaseAdapter {private int[] days = new int[42];private Context context;private int year;private int month;public DateAdapter(Context context, int[][] days, int year, int month) {this.context = context;int dayNum = 0; //將二維數組轉化為一維數組,方便使用for (int i = 0; i < days.length; i++) {for (int j = 0; j < days[i].length; j++) {this.days[dayNum] = days[i][j];dayNum++;}}this.year = year;this.month = month;}@Overridepublic int getCount() {return days.length;}@Overridepublic Object getItem(int i) {return days[i];}@Overridepublic long getItemId(int i) {return i;}@Overridepublic View getView(int i, View view, ViewGroup viewGroup) {ViewHolder viewHolder;if (view == null) {view = LayoutInflater.from(context).inflate(R.layout.date_item, null);viewHolder = new ViewHolder();viewHolder.date_item = (TextView) view.findViewById(R.id.date_item);view.setTag(viewHolder);} else {viewHolder = (ViewHolder) view.getTag();}if (i < 7 && days[i] > 20) {viewHolder.date_item.setTextColor(Color.rgb(204, 204, 204));//將上個月的和下個月的設置為灰色} else if (i > 20 && days[i] < 15) {viewHolder.date_item.setTextColor(Color.rgb(204, 204, 204));} viewHolder.date_item.setText(days[i] + "");return view;}/*** 優化Adapter*/class ViewHolder {TextView date_item;}
接下來是Activity文件 import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.GridView; import android.widget.ImageView; import android.widget.TextView;import com.jiaoml.smallmusic.R; import com.jiaoml.smallmusic.adapter.DateAdapter;/*** Created by 91905 on 2016/8/24 0024.*/public class MainActivity extends Activity implements View.OnClickListener {private GridView record_gridView;//定義gridViewprivate DateAdapter dateAdapter;//定義adapterprivate ImageView record_left;//左箭頭private ImageView record_right;//右箭頭private TextView record_title;//標題private int year;private int month;private String title;private int[][] days = new int[6][7];@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//初始化日期數據initData();//初始化組件initView();//組件點擊監聽事件initEvent();}private void initData() {year = DateUtils.getYear();month = DateUtils.getMonth();}private void initEvent() {record_left.setOnClickListener(this);record_right.setOnClickListener(this);}private void initView() {/*** 以下是初始化GridView*/record_gridView = (GridView) findViewById(R.id.record_gridView);days = DateUtils.getDayOfMonthFormat(2016, 8);dateAdapter = new DateAdapter(this, days, year, month);//傳入當前月的年record_gridView.setAdapter(dateAdapter);record_gridView.setVerticalSpacing(60);record_gridView.setEnabled(false);/*** 以下是初始化其他組件*/record_left = (ImageView) findViewById(R.id.record_left);record_right = (ImageView) findViewById(R.id.record_right);record_title = (TextView) findViewById(R.id.record_title);}/*** 下一個月** @return*/private int[][] nextMonth() {if (month == 12) {month = 1;year++;} else {month++;}days = DateUtils.getDayOfMonthFormat(year, month);return days;}/*** 上一個月** @return*/private int[][] prevMonth() {if (month == 1) {month = 12;year--;} else {month--;}days = DateUtils.getDayOfMonthFormat(year, month);return days;}/*** 設置標題*/private void setTile() {title = year + "年" + month + "月";record_title.setText(title);}@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.record_left:days = prevMonth();dateAdapter = new DateAdapter(this, days, year, month);record_gridView.setAdapter(dateAdapter);dateAdapter.notifyDataSetChanged();setTile();break;case R.id.record_right:days = nextMonth();dateAdapter = new DateAdapter(this, days, year, month);record_gridView.setAdapter(dateAdapter);dateAdapter.notifyDataSetChanged();setTile();break;}} }
OK,一個簡單的日歷就完成了
總結
                            
                        - 上一篇: 素雅极简线条中国风PPT模板
 - 下一篇: 家庭消耗品跟踪管理软件HomeLists