首页 > 系统 > Android > 正文

Android实现日历控件示例代码

2019-12-12 03:29:53
字体:
来源:转载
供稿:网友

做的是一个酒店的项目,可以选择入住和离开的日期。声明为了省事在网上找的资料,自己修改的逻辑,希望对需要的朋友有帮助。喜欢的给个好评。谢谢啦!祝生活愉快!

先上图

日历的样式,可以上下纵向滑动 

第一步,搭建布局xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:app="http://schemas.android.com/apk/res-auto"  android:layout_width="match_parent"  android:layout_height="match_parent">  <LinearLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="vertical">    <FrameLayout      android:layout_width="match_parent"      android:layout_height="wrap_content">      <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="@color/days_detail"        android:gravity="center"        android:padding="16dp"        android:text="选择住店离店日期"        android:textColor="@color/white"        android:textSize="18sp" />      <ImageView        android:id="@+id/back_to_up"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="10dp"        android:layout_marginTop="10dp"        android:src="@drawable/backto" />    </FrameLayout>    <FrameLayout      android:layout_width="match_parent"      android:layout_height="wrap_content">      <View        android:layout_width="match_parent"        android:layout_height="30dp"        android:background="@color/days_detail" />      <android.support.v7.widget.CardView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_margin="10dp"        android:layout_marginTop="20dp"        android:padding="10dp"        app:cardCornerRadius="10dp"        app:cardElevation="16dp">        <LinearLayout          android:id="@+id/ll"          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:orientation="vertical" />      </android.support.v7.widget.CardView>    </FrameLayout>  </LinearLayout></ScrollView>

第二部在编写逻辑

 LinearLayout ll;  MyCalendar c1;  Date date;  String nowday;  long nd = 1000 * 24L * 60L * 60L;//一天的毫秒数  SimpleDateFormat simpleDateFormat, sd1, sd2;  SharedPreferences sp;  SharedPreferences.Editor editor;  private String inday, outday//日期   sp_inday, sp_outday;//周几 Activity  extends BaseActivity implements MyCalendar.OnDaySelectListener {

继承BaseActivity实现点击日历的监听回调

 private void init() {    List<String> listDate = getDateList();    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,        ViewGroup.LayoutParams.WRAP_CONTENT);    for (int i = 0; i < listDate.size(); i++) {      c1 = new MyCalendar(this);      c1.setLayoutParams(params);      Date date = null;      try {        date = simpleDateFormat.parse(listDate.get(i));      } catch (ParseException e) {        e.printStackTrace();      }      if (!"".equals(sp_inday)) {        c1.setInDay(sp_inday);      }      if (!"".equals(sp_outday)) {        c1.setOutDay(sp_outday);      }      c1.setTheDay(date);      c1.setOnDaySelectListener(this);      ll.addView(c1);    }  }  @Override  public void onDaySelectListener(View view, String date) {    //若日历日期小于当前日期,或日历日期-当前日期超过三个月,则不能点击    try {      if (simpleDateFormat.parse(date).getTime() < simpleDateFormat.parse(nowday).getTime()) {        return;      }      long dayxc = (simpleDateFormat.parse(date).getTime() - simpleDateFormat.parse(nowday).getTime()) / nd;      if (dayxc > 90) {        return;      }    } catch (ParseException e) {      e.printStackTrace();    }    //若以前已经选择了日期,则在进入日历后会显示以选择的日期,该部分作用则是重新点击日历时,清空以前选择的数据(包括背景图案)    if (!"".equals(sp_inday)) {      c1.viewIn.setBackgroundColor(Color.WHITE);      ((TextView) c1.viewIn.findViewById(R.id.tv_calendar_day)).setTextColor(Color.BLACK);      ((TextView) c1.viewIn.findViewById(R.id.tv_calendar)).setText("");    }    if (!"".equals(sp_outday)) {      c1.viewOut.setBackgroundColor(Color.WHITE);      ((TextView) c1.viewOut.findViewById(R.id.tv_calendar_day)).setTextColor(Color.BLACK);      ((TextView) c1.viewOut.findViewById(R.id.tv_calendar)).setText("");    }    String dateDay = date.split("-")[2];    if (Integer.parseInt(dateDay) < 10) {      dateDay = date.split("-")[2].replace("0", "");    }    TextView textDayView = (TextView) view.findViewById(R.id.tv_calendar_day);    TextView textView = (TextView) view.findViewById(R.id.tv_calendar);    view.setBackgroundColor(Color.parseColor("#33B5E5"));    textDayView.setTextColor(Color.WHITE);    if (null == inday || inday.equals("")) {      textDayView.setText(dateDay);      textView.setText("入住");      inday = date;    } else {      if (inday.equals(date)) {        view.setBackgroundColor(Color.WHITE);        textDayView.setText(dateDay);        textDayView.setTextColor(Color.BLACK);        textView.setText("");        inday = "";      } else {        try {          if (simpleDateFormat.parse(date).getTime() < simpleDateFormat.parse(inday).getTime()) {            view.setBackgroundColor(Color.WHITE);            textDayView.setTextColor(Color.BLACK);            Toast.makeText(CalendarActivity.this, "离开日期不能小于入住日期", Toast.LENGTH_SHORT).show();            return;          }        } catch (ParseException e) {          e.printStackTrace();        }        textDayView.setText(dateDay);        textView.setText("离开");        outday = date;        editor.putString("dateIn", inday);        editor.putString("dateOut", outday);        editor.commit();        finish();      }    }  }  //根据当前日期,向后数三个月(若当前day不是1号,为满足至少90天,则需要向后数4个月)  @SuppressLint("SimpleDateFormat")  public List<String> getDateList() {    List<String> list = new ArrayList<String>();    Date date = new Date();    int nowMon = date.getMonth() + 1;    String yyyy = sd1.format(date);    String dd = sd2.format(date);    if (nowMon == 9) {      list.add(simpleDateFormat.format(date));      list.add(yyyy + "-10-" + dd);      list.add(yyyy + "-11-" + dd);      if (!dd.equals("01")) {        list.add(yyyy + "-12-" + dd);      }    } else if (nowMon == 10) {      list.add(yyyy + "-10-" + dd);      list.add(yyyy + "-11-" + dd);      list.add(yyyy + "-12-" + dd);      if (!dd.equals("01")) {        list.add((Integer.parseInt(yyyy) + 1) + "-01-" + dd);      }    } else if (nowMon == 11) {      list.add(yyyy + "-11-" + dd);      list.add(yyyy + "-12-" + dd);      list.add((Integer.parseInt(yyyy) + 1) + "-01-" + dd);      if (!dd.equals("01")) {        list.add((Integer.parseInt(yyyy) + 1) + "-02-" + dd);      }    } else if (nowMon == 12) {      list.add(yyyy + "-12-" + dd);      list.add((Integer.parseInt(yyyy) + 1) + "-01-" + dd);      list.add((Integer.parseInt(yyyy) + 1) + "-02-" + dd);      if (!dd.equals("01")) {        list.add((Integer.parseInt(yyyy) + 1) + "-03-" + dd);      }    } else {      list.add(yyyy + "-" + getMon(nowMon) + "-" + dd);      list.add(yyyy + "-" + getMon((nowMon + 1)) + "-" + dd);      list.add(yyyy + "-" + getMon((nowMon + 2)) + "-" + dd);      if (!dd.equals("01")) {        list.add(yyyy + "-" + getMon((nowMon + 3)) + "-" + dd);      }    }    return list;  }  public String getMon(int mon) {    String month = "";    if (mon < 10) {      month = "0" + mon;    } else {      month = "" + mon;    }    return month;  }

第三部 编写监听,自定义的控件

public class MyCalendar extends LinearLayout {  private static Context context;  private Date theInDay;  private String inday = "", outday = "";  public static View viewIn;  public static View viewOut;  public static String positionIn;  public static String positionOut;  public static final int WEEKDAYS = 7;  public static String[] WEEK = {      "周日",      "周一",      "周二",      "周三",      "周四",      "周五",      "周六"  };  static long nd = 1000 * 24L * 60L * 60L;//一天的毫秒数  private List<String> gvList;//存放天  private OnDaySelectListener callBack;//回调函数  private static String nowday = new SimpleDateFormat("yyyy-MM-dd").format(new Date());  private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMM");//日期格式化  private static SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd");//日期格式化  /**   * 构造函数   *   * @param context   */  public MyCalendar(Context context) {    super(context);    MyCalendar.context = context;  }  /**   * 日期变量转成对应的星期字符串   *   * @param date   * @return   */  public static String DateToWeek(Date date) {    Calendar calendar = Calendar.getInstance();    calendar.setTime(date);    int dayIndex = calendar.get(Calendar.DAY_OF_WEEK);    if (dayIndex < 1 || dayIndex > WEEKDAYS) {      return null;    }    return WEEK[dayIndex - 1];  }  /**   * 获得天数差   *   * @param begin   * @param end   * @return   */  public static long getDayDiff(Date begin, Date end) {    long day = 1;    if (end.getTime() < begin.getTime()) {      day = -1;    } else if (end.getTime() == begin.getTime()) {      day = 1;    } else {      day += (end.getTime() - begin.getTime()) / (24 * 60 * 60 * 1000);    }    return day;  }  /**   * 将yyyy-MM-dd类型转换成MM.dd   *   * @param time   * @return   * @throws ParseException   */  public static String format1(String time) throws ParseException {    SimpleDateFormat from = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);    SimpleDateFormat to = new SimpleDateFormat("MM.dd", Locale.CHINA);    return to.format(from.parse(time));  }  /**   * 获得指定日期的后一天   *   * @param specifiedDay   * @return   */  public static String getSpecifiedDayAfter(String specifiedDay) {    Calendar c = Calendar.getInstance();    Date date = null;    try {      date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);    } catch (ParseException e) {      e.printStackTrace();    }    c.setTime(date);    int day = c.get(Calendar.DATE);    c.set(Calendar.DATE, day + 1);    String dayAfter = new SimpleDateFormat("yyyy-MM-dd")        .format(c.getTime());    return dayAfter;  }  /**   * 构造函数   *   * @param context   */  public MyCalendar(Context context, AttributeSet attrs) {    super(context, attrs);    MyCalendar.context = context;  }  public void setInDay(String inday) {    this.inday = inday;  }  public void setOutDay(String outday) {    this.outday = outday;  }  public void setTheDay(Date dateIn) {    this.theInDay = dateIn;    init();  }  /**   * 初始化日期以及view等控件   */  private void init() {    gvList = new ArrayList<String>();//存放天    final Calendar cal = Calendar.getInstance();//获取日历实例    cal.setTime(theInDay);//cal设置为当天的    cal.set(Calendar.DATE, 1);//cal设置当前day为当前月第一天    int tempSum = countNeedHowMuchEmpety(cal);//获取当前月第一天为星期几    int dayNumInMonth = getDayNumInMonth(cal);//获取当前月有多少天    setGvListData(tempSum, dayNumInMonth, cal.get(Calendar.YEAR) + "-" + getMonth((cal.get(Calendar.MONTH) + 1)));    View view = LayoutInflater.from(context).inflate(R.layout.comm_calendar, this, true);//获取布局,开始初始化    TextView tv_year = (TextView) view.findViewById(R.id.tv_year);    if (cal.get(Calendar.YEAR) > new Date().getYear()) {      tv_year.setVisibility(View.VISIBLE);      tv_year.setText(cal.get(Calendar.YEAR) + "年");    }    TextView tv_month = (TextView) view.findViewById(R.id.tv_month);    tv_month.setText(String.valueOf(theInDay.getMonth() + 1));    MyGridView gv = (MyGridView) view.findViewById(R.id.gv_calendar);    calendarGridViewAdapter gridViewAdapter = new calendarGridViewAdapter(gvList, inday, outday);    gv.setAdapter(gridViewAdapter);    gv.setOnItemClickListener(new OnItemClickListener() {      @Override      public void onItemClick(AdapterView<?> adapterView, View arg1, int position, long arg3) {        String choiceDay = (String) adapterView.getAdapter().getItem(position);        String[] date = choiceDay.split(",");        String day = date[1];        if (!" ".equals(day)) {          if (Integer.parseInt(day) < 10) {            day = "0" + date[1];          }          choiceDay = date[0] + "-" + day;          if (callBack != null) {//调用回调函数回调数据            callBack.onDaySelectListener(arg1, choiceDay);          }        }      }    });  }  /**   * 为gridview中添加需要展示的数据   *   * @param tempSum   * @param dayNumInMonth   */  private void setGvListData(int tempSum, int dayNumInMonth, String YM) {    gvList.clear();    for (int i = 0; i < tempSum; i++) {      gvList.add(" , ");    }    for (int j = 1; j <= dayNumInMonth; j++) {      gvList.add(YM + "," + String.valueOf(j));    }  }  private String getMonth(int month) {    String mon = "";    if (month < 10) {      mon = "0" + month;    } else {      mon = "" + month;    }    return mon;  }  /**   * 获取当前月的总共天数   *   * @param cal   * @return cal.getActualMaximum(Calendar.DATE)   */  private int getDayNumInMonth(Calendar cal) {    return cal.getActualMaximum(Calendar.DATE);  }  /**   * 获取当前月第一天在第一个礼拜的第几天,得出第一天是星期几   *   * @param cal   * @return firstDayInWeek   */  private int countNeedHowMuchEmpety(Calendar cal) {    int firstDayInWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;    Log.e("MyCalendar", String.valueOf(firstDayInWeek));    return firstDayInWeek;  }  /**   * gridview中adapter的viewholder   *   * @author wx   */  static class GrideViewHolder {    TextView tvDay, tv;  }  /**   * gridview的adapter   *   * @author Administrator   */  static class calendarGridViewAdapter extends BaseAdapter {    List<String> gvList;//存放天    String inday, outday;    public calendarGridViewAdapter(List<String> gvList, String inday, String outday) {      super();      this.gvList = gvList;      this.inday = inday;      this.outday = outday;    }    @Override    public int getCount() {      return gvList.size();    }    @Override    public String getItem(int position) {      return gvList.get(position);    }    @Override    public long getItemId(int position) {      return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {      GrideViewHolder holder;      if (convertView == null) {        holder = new GrideViewHolder();        convertView = inflate(context, R.layout.common_calendar_gridview_item, null);        holder.tv = (TextView) convertView.findViewById(R.id.tv_calendar);        holder.tvDay = (TextView) convertView.findViewById(R.id.tv_calendar_day);        convertView.setTag(holder);      } else {        holder = (GrideViewHolder) convertView.getTag();      }      String[] date = getItem(position).split(",");      holder.tvDay.setText(date[1]);      if ((position + 1) % 7 == 0 || (position) % 7 == 0) {        holder.tvDay.setTextColor(Color.parseColor("#339900"));      }      if (!date[1].equals(" ")) {        String day = date[1];        if (Integer.parseInt(date[1]) < 10) {          day = "0" + date[1];        }        if ((date[0] + "-" + day).equals(nowday)) {          holder.tvDay.setTextColor(Color.parseColor("#FF6600"));          holder.tvDay.setTextSize(15);          holder.tvDay.setText("今天");        }        if (!"".equals(inday) && (date[0] + "-" + day).equals(inday)) {          convertView.setBackgroundColor(Color.parseColor("#33B5E5"));          holder.tvDay.setTextColor(Color.WHITE);          holder.tvDay.setText(date[1]);          holder.tv.setText("入住");          viewIn = convertView;          positionIn = date[1];        }        if (!"".equals(outday) && (date[0] + "-" + day).equals(outday)) {          convertView.setBackgroundColor(Color.parseColor("#33B5E5"));          holder.tvDay.setTextColor(Color.WHITE);          holder.tvDay.setText(date[1]);          holder.tv.setText("离开");          viewOut = convertView;          positionOut = date[1];        }        try {          //若日历日期<当前日期,则不能选择          if (dateFormat2.parse(date[0] + "-" + day).getTime() < dateFormat2.parse(nowday).getTime()) {            holder.tvDay.setTextColor(Color.parseColor("#999999"));          }          //若日历日期-当前日期>90天,则不能选择          long dayxc = (dateFormat2.parse(date[0] + "-" + day).getTime() - dateFormat2.parse(nowday).getTime()) / nd;          if (dayxc > 90) {            holder.tvDay.setTextColor(Color.parseColor("#999999"));          }        } catch (ParseException e) {          e.printStackTrace();        }      }      return convertView;    }  }  /**   * 自定义监听接口   *   * @author Administrator   */  public interface OnDaySelectListener {    void onDaySelectListener(View view, String date);  }  /**   * 自定义监听接口设置对象   *   * @param o   */  public void setOnDaySelectListener(OnDaySelectListener o) {    callBack = o;  }}

在界面显示选择的日期

看图 

接下来就是为了显示选择的日期进行逻辑判断,包括字符串的转换以及日期格式的转换,日期的计算等。

simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");    if ("".equals(home_into_date.getText().toString())        && "".equals(home_out_date.getText().toString())) {      inday = simpleDateFormat.format(new Date());      try {        //转换时间格式        String changeDate = MyCalendar.format1(inday);        Date dateIn = simpleDateFormat.parse(inday);        //将日期转换成周        String weekIn = MyCalendar.DateToWeek(dateIn);        home_into_date.setText("" + changeDate + weekIn);        String nextDay = MyCalendar.format1(MyCalendar.getSpecifiedDayAfter(inday));        Date dateOut = simpleDateFormat.parse(MyCalendar.getSpecifiedDayAfter(inday));        String weekOut = MyCalendar.DateToWeek(dateOut);        home_out_date.setText("" + nextDay + weekOut);        long days = MyCalendar.getDayDiff(dateIn, dateOut);        home_total_days.setText("共" + (days - 1) + "晚");      } catch (ParseException e) {        e.printStackTrace();      }    } else {    //这里使用sp传的值      inday = pro.getString("dateIn", "");      outday = pro.getString("dateOut", "");      try {        String changeDate = MyCalendar.format1(inday);        Date dateIn = simpleDateFormat.parse(inday);        //将日期转换成周        String weekIn = MyCalendar.DateToWeek(dateIn);        home_into_date.setText("" + changeDate + weekIn);        String outDay = MyCalendar.format1(outday);        Date dateOut = simpleDateFormat.parse(outday);        String weekOut = MyCalendar.DateToWeek(dateOut);        home_out_date.setText("" + outDay + weekOut);        long days = MyCalendar.getDayDiff(dateIn, dateOut);        home_total_days.setText("共" + (days - 1) + "晚");      } catch (ParseException e) {        e.printStackTrace();      }

其中有几个布局,给图自己写吧

comm_calendar

这里写图片描述 

common_calendar_gridview_item

<LinearLayout    android:layout_width="0dp"    android:layout_height="match_parent"    android:layout_weight="1"    android:gravity="center"    android:orientation="vertical">    <LinearLayout      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:layout_gravity="center"      android:gravity="center"      android:orientation="vertical">      <TextView        android:id="@+id/tv_calendar_day"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:gravity="center"        android:textSize="15sp" />      <TextView        android:id="@+id/tv_calendar"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:gravity="center"        android:textColor="#FFFFFF"        android:textSize="15sp" />    </LinearLayout>    <View      android:layout_width="match_parent"      android:layout_height="0.5dp"      android:background="#E4E4E4" />  </LinearLayout>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表