在開(kāi)發(fā)中可能會(huì)遇到某些情況下需要用到日歷的功能,并且還要在日歷上加標(biāo)簽什么的,最重要的就是android自帶的日歷由于各個(gè)系統(tǒng)版本不同導(dǎo)致日歷的樣式也不同,這樣就會(huì)導(dǎo)致使用起來(lái)比較麻煩..而且在日歷中加標(biāo)簽也不好實(shí)現(xiàn)...所以很多時(shí)候日歷都是自己去實(shí)現(xiàn)的...由于自定義日歷會(huì)比較麻煩...這里就教大家使用GridView來(lái)實(shí)現(xiàn),主要是我們比較熟悉這個(gè)控件...到時(shí)候也可以根據(jù)自己的情況進(jìn)行封裝為自定義View
創(chuàng)新互聯(lián)建站是一家專(zhuān)注于成都做網(wǎng)站、網(wǎng)站建設(shè)與策劃設(shè)計(jì),孝感網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)十年,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:孝感等地區(qū)。孝感做網(wǎng)站價(jià)格咨詢(xún):13518219792
下面就先看看效果圖.由于是從項(xiàng)目中抽取出來(lái)的,某些地方定制性比較強(qiáng), 可以根據(jù)需求自行修改
效果圖
圖中的紅點(diǎn)就是標(biāo)簽,藍(lán)色背景就是選中的意思.
下面開(kāi)始擼代碼:
先上核心的GridView的適配器:
CalendarAdapter.java
/** * 日歷gridview中的每一個(gè)item顯示的textview */ public class CalendarAdapter extends BaseAdapter { private static String TAG = "CalendarAdapter"; private boolean isLeapyear = false; //是否為閏年 private int daysOfMonth = 0; //某月的天數(shù) private int dayOfWeek = 0; //具體某一天是星期幾 private int lastDaysOfMonth = 0; //上一個(gè)月的總天數(shù) private Context context; private String[] dayNumber = new String[42]; //一個(gè)gridview中的日期存入此數(shù)組中 private SpecialCalendar sc = null; private int currentYear = 0; private int currentMonth = 0; /** * 當(dāng)前選中的日期位置 */ private int currentFlag = -1; /** * 當(dāng)前選中天的字符串 例:20170830 */ private String currentDayStr; private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d"); private Set<Integer> schDateTagFlag = new ArraySet<>(); //存儲(chǔ)當(dāng)月所有的日程日期(標(biāo)簽) private String showYear = ""; //用于在頭部顯示的年份 private String showMonth = ""; //用于在頭部顯示的月份 private String animalsYear = ""; private String leapMonth = ""; //閏哪一個(gè)月 private Set<String> mSet = null; /** * 距離當(dāng)前月的差(上一個(gè)月-1,當(dāng)前月0,下一個(gè)月+1) */ private int jumpMonth = 0; public CalendarAdapter(Context context, int year, int month, String currentDayStr) { this.context = context; sc = new SpecialCalendar(); currentYear = year; currentMonth = month; //得到跳轉(zhuǎn)到的月份 this.currentDayStr = currentDayStr; getCalendar(currentYear, currentMonth); } @Override public int getCount() { return dayNumber.length; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder myViewHolder = null; if (convertView == null || convertView.getTag() == null) { convertView = LayoutInflater.from(context).inflate(R.layout.item_select_time, null); myViewHolder = new ViewHolder(convertView); convertView.setTag(myViewHolder); } else { myViewHolder = (ViewHolder) convertView.getTag(); } myViewHolder.mIdTvItemSelectTimeDay.setText(dayNumber[position]); myViewHolder.mIdTvItemSelectTimeDay.setTextColor(Color.GRAY);//不是當(dāng)前月為灰 if (position < daysOfMonth + dayOfWeek && position >= dayOfWeek) { // 當(dāng)前月信息顯示 myViewHolder.mIdTvItemSelectTimeDay.setTextColor(Color.BLACK);// 當(dāng)月字體設(shè)黑 myViewHolder.mIdTvItemSelectTimeDay.setTag(true);// 當(dāng)月字體設(shè)黑 }else { myViewHolder.mIdTvItemSelectTimeDay.setTag(false);// 當(dāng)月字體設(shè)黑 } if (currentFlag != -1 && currentFlag == position) { //設(shè)置當(dāng)天的背景 myViewHolder.mIdTvItemSelectTimeDay.setBackgroundResource(R.color.mainMenu); myViewHolder.mIdTvItemSelectTimeDay.setTextColor(Color.WHITE); } else { myViewHolder.mIdTvItemSelectTimeDay.setBackgroundColor(0); } //顯示小圓點(diǎn) if (schDateTagFlag != null && schDateTagFlag.size() > 0) { if (schDateTagFlag.contains(position)) { if (myViewHolder.mIdImgItemSelectTimeLogo.getVisibility()!=View.VISIBLE) { myViewHolder.mIdImgItemSelectTimeLogo.setVisibility(View.VISIBLE); } } else { if (myViewHolder.mIdImgItemSelectTimeLogo.getVisibility()!=View.GONE) { myViewHolder.mIdImgItemSelectTimeLogo.setVisibility(View.GONE); } } } else { if (myViewHolder.mIdImgItemSelectTimeLogo.getVisibility()!=View.GONE) { myViewHolder.mIdImgItemSelectTimeLogo.setVisibility(View.GONE); } } return convertView; } /** * 下一個(gè)月 */ public void addMonth() { jumpMonth++; } /** * 上一個(gè)月 */ public void lessMonth() { jumpMonth--; } /** * 更新日歷數(shù)據(jù) */ public void upDataMonth() { int stepYear; int stepMonth = currentMonth + jumpMonth; if (stepMonth > 0) { //下一個(gè)月 if (stepMonth % 12 == 0) { stepYear = currentYear + stepMonth / 12 - 1; stepMonth = 12; } else { stepYear = currentYear + stepMonth / 12; stepMonth = stepMonth % 12; } } else { //上一個(gè)月 stepYear = currentYear - 1 + stepMonth / 12; stepMonth = stepMonth % 12 + 12; } getCalendar(stepYear, stepMonth); } /** * 得到某年的某月的天數(shù)且這月的第一天是星期幾 * * @param year * @param month */ private void getCalendar(int year, int month) { isLeapyear = sc.isLeapYear(year); //是否為閏年 daysOfMonth = sc.getDaysOfMonth(isLeapyear, month); //某月的總天數(shù) dayOfWeek = sc.getWeekdayOfMonth(year, month); //某月第一天為星期幾 lastDaysOfMonth = sc.getDaysOfMonth(isLeapyear, month - 1); //上一個(gè)月的總天數(shù) getWeek(year, month); } /** * 將一個(gè)月中的每一天的值添加入數(shù)組dayNuber中 * * @param year * @param month */ private void getWeek(int year, int month) { schDateTagFlag.clear(); currentFlag = -1; int j = 1; //得到當(dāng)前月的所有日程日期(這些日期需要標(biāo)記) for (int i = 0; i < dayNumber.length; i++) { if (i < dayOfWeek) { //前一個(gè)月 int temp = lastDaysOfMonth - dayOfWeek + 1; dayNumber[i] = (temp + i) + ""; } else if (i < daysOfMonth + dayOfWeek) {//本月 int day = i - dayOfWeek + 1; //得到的日期 dayNumber[i] = i - dayOfWeek + 1 + ""; //對(duì)于當(dāng)前月才去標(biāo)記當(dāng)前日期 String yearStr = String.valueOf(year); String monthStr =getStr(String.valueOf(month),2); String dayStr =getStr(String.valueOf(day),2); String timeAll = yearStr + monthStr + dayStr; if (timeAll.equals(currentDayStr)) {//判斷選中的位置 currentFlag = i; } if (mSet != null && mSet.size() > 0) { for (String s : mSet) {//迭代器遍歷判斷是否需要帶標(biāo)簽 if (timeAll.equals(s)) { schDateTagFlag.add(i); } } } setShowYear(yearStr); setShowMonth(String.valueOf(month)); } else { //下一個(gè)月 dayNumber[i] = j + ""; j++; } } } /** * 獲取當(dāng)前時(shí)間 樣式:20170830 * @param position * @return */ public String getItemTime(int position) { String month = getStr(getShowMonth(), 2); String day = getStr(getDateByClickItem(position), 2); return getShowYear() + month + day; } /** * 保留N位整數(shù),不足前面補(bǔ)0 * * @param file String * @param bit 位數(shù) * @return */ public static String getStr(String file,int bit) { while (file.length() < bit) file = "0" + file; return file; } /** * 點(diǎn)擊每一個(gè)item時(shí)返回item中的日期 * * @param position * @return */ public String getDateByClickItem(int position) { return dayNumber[position]; } /** * 在點(diǎn)擊gridView時(shí),得到這個(gè)月中第一天的位置 * * @return */ public int getStartPositon() { return dayOfWeek + 7; } /** * 在點(diǎn)擊gridView時(shí),得到這個(gè)月中最后一天的位置 * * @return */ public int getEndPosition() { return (dayOfWeek + daysOfMonth + 7) - 1; } public String getShowYear() { return showYear; } public void setShowYear(String showYear) { this.showYear = showYear; } public String getShowMonth() { return showMonth; } public void setShowMonth(String showMonth) { this.showMonth = showMonth; } public String getAnimalsYear() { return animalsYear; } public void setAnimalsYear(String animalsYear) { this.animalsYear = animalsYear; } public String getLeapMonth() { return leapMonth; } public void setLeapMonth(String leapMonth) { this.leapMonth = leapMonth; } public Set<String> getSet() { return mSet; } public void setSet(Set<String> set) { mSet = set; } static class ViewHolder { @BindView(R.id.id_img_item_select_time_logo) ImageView mIdImgItemSelectTimeLogo; @BindView(R.id.id_tv_item_select_time_day) TextView mIdTvItemSelectTimeDay; ViewHolder(View view) { ButterKnife.bind(this, view); } } }
日歷工具類(lèi):
/** * 日歷工具類(lèi) */ public class SpecialCalendar { private int daysOfMonth = 0; //某月的天數(shù) private int dayOfWeek = 0; //具體某一天是星期幾 /** * 判斷是否為閏年 * @param year * @return */ public boolean isLeapYear(int year) { if (year % 100 == 0 && year % 400 == 0) { return true; } else if (year % 100 != 0 && year % 4 == 0) { return true; } return false; } /** * 得到某月有多少天數(shù) * @param isLeapyear * @param month * @return */ public int getDaysOfMonth(boolean isLeapyear, int month) { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: daysOfMonth = 31; break; case 4: case 6: case 9: case 11: daysOfMonth = 30; break; case 2: if (isLeapyear) { daysOfMonth = 29; } else { daysOfMonth = 28; } } return daysOfMonth; } /** * 指定某年中的某月的第一天是星期幾 * @param year * @param month * @return */ public int getWeekdayOfMonth(int year, int month){ Calendar cal = Calendar.getInstance(); cal.set(year, month-1, 1); dayOfWeek = cal.get(Calendar.DAY_OF_WEEK)-1; return dayOfWeek; } }
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/layout_public_finish_menu" /> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:background="@color/bg_home_gone_menu" android:gravity="center" android:orientation="horizontal" > <ImageView android:id="@+id/id_img_select_time_less" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:padding="5dp" android:src="@mipmap/ic_sd_time_less" android:background="@drawable/selector_public_btn_bg" /> <TextView android:id="@+id/id_tv_select_time_show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="4" android:gravity="center" android:text="年月" android:textColor="@color/white" android:textSize="@dimen/default_big" /> <ImageView android:id="@+id/id_img_select_time_add" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:padding="5dp" android:src="@mipmap/ic_sd_time_add" android:background="@drawable/selector_public_btn_bg" /> </LinearLayout> <GridView android:id="@+id/id_gv_select_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/bg_rectangle_null_black_1" android:clickable="true" android:gravity="center" android:layout_gravity="center" android:clipChildren="true" android:listSelector="@null" android:numColumns="7" android:padding="1dp" android:layout_margin="5dp" android:stretchMode="columnWidth" /> </LinearLayout>
Item布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/bg_rectangle_null_black_1"> <TextView android:id="@+id/id_tv_item_select_time_day" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="天" android:textSize="@dimen/default_big" android:layout_margin="1dp" android:textStyle="bold" /> <ImageView android:id="@+id/id_img_item_select_time_logo" android:layout_width="5dp" android:layout_height="5dp" android:layout_margin="3dp" android:src="@drawable/shap_doorbell_oval_red" android:visibility="gone" /> </RelativeLayout>
布局只供參考...可以根據(jù)需求進(jìn)行修改
下面就看看簡(jiǎn)單的調(diào)用
//傳入當(dāng)前的年,月..已經(jīng)選中的時(shí)間(20170830) mAdapter = new CalendarAdapter(mContext, year_c, month_c, currentDayStr); mIdGvSelectItem.setAdapter(mAdapter); /** * GridView Item的點(diǎn)擊事件 */ private class MyGvListener implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { TextView mTv = (TextView) view.findViewById(R.id.id_tv_item_select_time_day); boolean isOnClick = (boolean) mTv.getTag(); if (isOnClick) { String time = mAdapter.getItemTime(position); Intent mIntent = getIntent(); mIntent.putExtra("fileDate", time); setResult(AppStart.SDVA_SDTA, mIntent); finish(); Log.i(TAG,"當(dāng)前選擇的時(shí)間:" + time); } } } /** * 點(diǎn)擊事件邏輯處理 */ private class MyListener implements View.OnClickListener { @Override public void onClick(View v) { switch (v.getId()) { //上一個(gè)月 case R.id.id_img_select_time_less: mAdapter.lessMonth(); mHandler.sendEmptyMessage(UPDATA_TIME); addTextToTopTextView(mIdTvSelectTimeShow); break; //下一個(gè)月 case R.id.id_img_select_time_add: mAdapter.addMonth(); mHandler.sendEmptyMessage(UPDATA_TIME); addTextToTopTextView(mIdTvSelectTimeShow); break; } } } private Set<String> dayEventCount = new HashSet<>(); //設(shè)置需要顯示標(biāo)簽的實(shí)際 mAdapter.setSet(dayEventCount); //更新 @Override protected void uiHandlerMessage(Message msg) { switch (msg.what) { case UPDATA_TIME: mAdapter.upDataMonth(); mAdapter.notifyDataSetChanged(); break; } }
調(diào)用部分的代碼由于是從項(xiàng)目中直接復(fù)制出來(lái)的..代碼的前后沒(méi)有什么關(guān)聯(lián)性,主要是說(shuō)明功能的..請(qǐng)根據(jù)自己的項(xiàng)目進(jìn)行調(diào)整..
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
本文名稱(chēng):Android使用GridView實(shí)現(xiàn)日歷的方法
URL鏈接:http://muchs.cn/article22/pioecc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開(kāi)發(fā)、企業(yè)建站、App開(kāi)發(fā)、軟件開(kāi)發(fā)、靜態(tài)網(wǎng)站、
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)