Android使用GridView實(shí)現(xiàn)日歷的方法

在開(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ù)需求自行修改

效果圖

Android使用GridView實(shí)現(xiàn)日歷的方法

圖中的紅點(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)

成都網(wǎng)站建設(shè)公司