Android实现可滑动的自定义日历控件

Android实现可滑动的自定义日历控件,第1张

概述最近用到的一个日历控件,记录下,效果如图代码下载地址:点击打开链接布局文件

最近用到的一个日历控件,记录下,效果如图

代码下载地址:点击打开链接

布局文件

<linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:orIEntation="vertical" androID:visibility="visible">  <linearLayout  androID:layout_wIDth="match_parent"  androID:layout_height="wrap_content"  androID:background="@color/bg_gray"  androID:orIEntation="horizontal">   <ImageVIEw   androID:ID="@+ID/prevMonth"   androID:layout_wIDth="0dp"   androID:layout_height="wrap_content"   androID:layout_gravity="center"   androID:layout_weight="1"   androID:src="@drawable/prev_month" />   <TextVIEw   androID:ID="@+ID/currentMonth"   androID:layout_wIDth="0dp"   androID:layout_height="35dp"   androID:layout_weight="3"   androID:gravity="center"   androID:text="2016年9月"   androID:textcolor="@color/black"   androID:textSize="18sp" />   <ImageVIEw   androID:ID="@+ID/nextMonth"   androID:layout_wIDth="0dp"   androID:layout_height="wrap_content"   androID:layout_gravity="center"   androID:layout_weight="1"   androID:src="@drawable/next_month" /> </linearLayout>  <linearLayout  androID:layout_wIDth="match_parent"  androID:layout_height="20dp"  androID:background="@color/bg_gray">   <TextVIEw      androID:text="周日"   androID:textcolor="@color/green" />   <TextVIEw      androID:text="周一" />   <TextVIEw      androID:text="周二" />   <TextVIEw      androID:text="周三" />   <TextVIEw      androID:text="周四" />   <TextVIEw      androID:text="周五" />   <TextVIEw      androID:text="周六"   androID:textcolor="@color/green" /> </linearLayout>  <VIEw  androID:layout_wIDth="match_parent"  androID:layout_height="1dp"  androID:background="@color/line" />  <VIEwFlipper  androID:ID="@+ID/flipper"  androID:layout_wIDth="fill_parent"  androID:layout_height="wrap_content"  androID:background="@color/line"  androID:padding="1dp" />  <VIEw  androID:layout_wIDth="match_parent"  androID:layout_height="1dp"  androID:background="@color/line" /> </linearLayout>

日历PopCalendar.class的代码

public class PopCalendar extends PopupWindow implements VIEw.OnClickListener { private VIEw contentVIEw; private Context mContext; private WindowManager windowManager; private GestureDetector gestureDetector = null; private Calendaradapter calV = null; private VIEwFlipper flipper = null; private GrIDVIEw gvCalendar = null; private static int jumpMonth = 0; // 每次滑动,增加或减去一个月,默认为0(即显示当前月) private static int jumpYear = 0; // 滑动跨越一年,则增加或者减去一年,默认为0(即当前年) private int yearC = 0; private int monthC = 0; private int dayC = 0; private String currentDate = ""; //当前年月,显示在日历顶端 private TextVIEw currentMonthTv; //上个月,下个月的图标 private ImageVIEw prevMonthIv; private ImageVIEw nextMonthIv;  public PopCalendar(final Activity context) {  this.mContext = context;  this.windowManager = context.getwindowManager();;  Date date = new Date();  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d");  currentDate = sdf.format(date); // 当期日期  yearC = Integer.parseInt(currentDate.split("-")[0]);  monthC = Integer.parseInt(currentDate.split("-")[1]);  dayC = Integer.parseInt(currentDate.split("-")[2]);  jumpMonth = 0;  jumpYear = 0;   //设置PopWindow的属性  LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  contentVIEw = inflater.inflate(R.layout.pop_calendar,null);  this.setContentVIEw(contentVIEw);  this.setWIDth(WindowManager.LayoutParams.FILL_PARENT);  this.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);  this.setFocusable(true);  this.setoutsIDetouchable(true);  this.update();  colorDrawable DW = new colorDrawable(0000000000);  this.setBackgroundDrawable(DW);   currentMonthTv = (TextVIEw) contentVIEw.findVIEwByID(R.ID.currentMonth);  prevMonthIv = (ImageVIEw) contentVIEw.findVIEwByID(R.ID.prevMonth);  nextMonthIv = (ImageVIEw) contentVIEw.findVIEwByID(R.ID.nextMonth);  setListener();   gestureDetector = new GestureDetector(mContext,new MyGestureListener());  flipper = (VIEwFlipper) contentVIEw.findVIEwByID(R.ID.flipper);  flipper.removeAllVIEws();  calV = new Calendaradapter(mContext,mContext.getResources(),jumpMonth,jumpYear,yearC,monthC,dayC);  addGrIDVIEw();  gvCalendar.setAdapter(calV);  flipper.addVIEw(gvCalendar,0);  addTextTotopTextVIEw(currentMonthTv); }  private class MyGestureListener extends GestureDetector.SimpleOnGestureListener {  @OverrIDe  public boolean onFling(MotionEvent e1,MotionEvent e2,float veLocityX,float veLocityY) {   if (e1.getX() - e2.getX() > 120) {    // 像左滑动    enterNextMonth();    return true;   } else if (e1.getX() - e2.getX() < -120) {    // 向右滑动    enterPrevMonth();    return true;   }   return false;  } }  /**  * 移动到下一个月  *  */ private voID enterNextMonth() {  addGrIDVIEw(); // 添加一个grIDVIEw  jumpMonth++; // 下一个月   calV = new Calendaradapter(mContext,dayC);  gvCalendar.setAdapter(calV);  addTextTotopTextVIEw(currentMonthTv); // 移动到下一月后,将当月显示在头标题中  flipper.addVIEw(gvCalendar,1);  flipper.setInAnimation(AnimationUtils.loadAnimation(mContext,R.anim.push_left_in));  flipper.setoutAnimation(AnimationUtils.loadAnimation(mContext,R.anim.push_left_out));  flipper.showNext();  flipper.removeVIEwAt(0); }  /**  * 移动到上一个月  *  */ private voID enterPrevMonth() {  addGrIDVIEw(); // 添加一个grIDVIEw  jumpMonth--; // 上一个月   calV = new Calendaradapter(mContext,dayC);  gvCalendar.setAdapter(calV);  addTextTotopTextVIEw(currentMonthTv); // 移动到上一月后,将当月显示在头标题中  flipper.addVIEw(gvCalendar,1);   flipper.setInAnimation(AnimationUtils.loadAnimation(mContext,R.anim.push_right_in));  flipper.setoutAnimation(AnimationUtils.loadAnimation(mContext,R.anim.push_right_out));  flipper.showPrevIoUs();  flipper.removeVIEwAt(0); }  /**  * 添加头部的年份 闰哪月等信息  * @param vIEw  */ public voID addTextTotopTextVIEw(TextVIEw vIEw) {  StringBuffer textDate = new StringBuffer();  textDate.append(calV.getShowYear()).append("年").append(calV.getShowMonth()).append("月").append("\t");  vIEw.setText(textDate); }  private voID addGrIDVIEw() {  linearLayout.LayoutParams params = new linearLayout.LayoutParams(AbsListVIEw.LayoutParams.MATCH_PARENT,AbsListVIEw.LayoutParams.MATCH_PARENT);  // 取得屏幕的宽度和高度  display display = windowManager.getDefaultdisplay();  int WIDth = display.getWIDth();  int Height = display.getHeight();  gvCalendar = new GrIDVIEw(mContext);  gvCalendar.setNumColumns(7);  gvCalendar.setColumnWIDth(40);  // grIDVIEw.setStretchMode(GrIDVIEw.STRETCH_ColUMN_WIDTH);  if (WIDth == 720 && Height == 1280) {   gvCalendar.setColumnWIDth(40);  }  gvCalendar.setGravity(Gravity.CENTER_VERTICAL);  gvCalendar.setSelector(new colorDrawable(color.transparent));  // 去除grIDVIEw边框  gvCalendar.setVerticalSpacing(2);  gvCalendar.setHorizontalSpacing(2);  gvCalendar.setontouchListener(new VIEw.OntouchListener() {   // 将grIDVIEw中的触摸事件回传给gestureDetector   public boolean ontouch(VIEw v,MotionEvent event) {    // Todo auto-generated method stub    return PopCalendar.this.gestureDetector.ontouchEvent(event);   }  });   gvCalendar.setonItemClickListener(new AdapterVIEw.OnItemClickListener() {    @OverrIDe   public voID onItemClick(AdapterVIEw<?> arg0,VIEw arg1,int position,long arg3) {    // Todo auto-generated method stub    // 点击任何一个item,得到这个item的日期(排除点击的是周日到周六(点击不响应))    int startposition = calV.getStartposition();    int endposition = calV.getEndposition();    if (startposition <= position + 7 && position <= endposition - 7) {     String scheduleDay = calV.getDateByClickItem(position); // 这一天的阳历     String scheduleYear = calV.getShowYear();     String scheduleMonth = calV.getShowMonth();     Toast.makeText(mContext,scheduleYear + "-" + scheduleMonth + "-" + scheduleDay,Toast.LENGTH_SHORT).show();    }   }  });  gvCalendar.setLayoutParams(params); }  private voID setListener() {  prevMonthIv.setonClickListener(this);  nextMonthIv.setonClickListener(this); }  @OverrIDe public voID onClick(VIEw v) {  // Todo auto-generated method stub  switch (v.getID()) {   case R.ID.nextMonth: // 下一个月    enterNextMonth();    break;   case R.ID.prevMonth: // 上一个月    enterPrevMonth();    break;   default:    break;  } }  /**  * 显示popWindow  */ public voID showPopupWindow(VIEw parent) {  if (!this.isShowing()) {   // 以下拉方式显示popupwindow   this.showAsDropDown(parent);  } else {   this.dismiss();  } }}

日历的内容是一个GrIDVIEw,可以自定义类似签到效果的图标

<relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="fill_parent" androID:layout_height="fill_parent" androID:background="@color/bg_gray" >  <TextVIEw  androID:ID="@+ID/tv_text"  androID:layout_wIDth="fill_parent"  androID:layout_height="30dp"  androID:gravity="center" />  <ImageVIEw  androID:layout_wIDth="15dp"  androID:layout_height="15dp"  androID:visibility="invisible"  androID:layout_alignParentBottom="true"  androID:background="@drawable/pen"  androID:layout_alignParentEnd="true"  androID:ID="@+ID/iv_pen" />  </relativeLayout>

日历的adapter

public class Calendaradapter extends BaseAdapter { private boolean isLeapYear = false; // 是否为闰年 private int daysOfMonth = 0; // 某月的天数 private int dayOfWeek = 0; // 具体某一天是星期几 private int lastDaysOfMonth = 0; // 上一个月的总天数 private Context context; private String[] dayNumber = new String[42]; // 一个grIDvIEw中的日期存入此数组中 private SpecialCalendar sc = null; private Resources res = null;  private String currentYear = ""; private String currentMonth = "";  private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d"); private int currentFlag = -1; // 用于标记当天  private String showYear = ""; // 用于在头部显示的年份 private String showMonth = ""; // 用于在头部显示的月份  // 系统当前时间 private String sysDate = ""; private String sys_year = ""; private String sys_month = ""; private String sys_day = ""; public Calendaradapter() {  Date date = new Date();  sysDate = sdf.format(date); // 当期日期  sys_year = sysDate.split("-")[0];  sys_month = sysDate.split("-")[1];  sys_day = sysDate.split("-")[2]; }  public Calendaradapter(Context context,Resources rs,int jumpMonth,int jumpYear,int year_c,int month_c,int day_c) {  this();  this.context = context;  sc = new SpecialCalendar();  this.res = rs;   int stepYear = year_c + jumpYear;  int stepMonth = month_c + jumpMonth;  if (stepMonth > 0) {   // 往下一个月滑动   if (stepMonth % 12 == 0) {    stepYear = year_c + stepMonth / 12 - 1;    stepMonth = 12;   } else {    stepYear = year_c + stepMonth / 12;    stepMonth = stepMonth % 12;   }  } else {   // 往上一个月滑动   stepYear = year_c - 1 + stepMonth / 12;   stepMonth = stepMonth % 12 + 12;   if (stepMonth % 12 == 0) {    }  }   currentYear = String.valueOf(stepYear); // 得到当前的年份  currentMonth = String.valueOf(stepMonth); // 得到本月  // (jumpMonth为滑动的次数,每滑动一次就增加一月或减一月)   getCalendar(Integer.parseInt(currentYear),Integer.parseInt(currentMonth));  }  @OverrIDe public int getCount() {  // Todo auto-generated method stub  return dayNumber.length; }  @OverrIDe public Object getItem(int position) {  // Todo auto-generated method stub  return position; }  @OverrIDe public long getItemID(int position) {  // Todo auto-generated method stub  return position; }  @OverrIDe public VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup parent) {   if (convertVIEw == null) {   convertVIEw = LayoutInflater.from(context).inflate(R.layout.calendar_item,null);  }  TextVIEw textVIEw = (TextVIEw) convertVIEw.findVIEwByID(R.ID.tv_text);  ImageVIEw ivPen = (ImageVIEw) convertVIEw.findVIEwByID(R.ID.iv_pen);  String d = dayNumber[position];   SpannableString sp = new SpannableString(d);  sp.setSpan(new StyleSpan(androID.graphics.Typeface.BolD),d.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  sp.setSpan(new relativeSizeSpan(1.2f),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);   textVIEw.setText(sp);  textVIEw.setTextcolor(color.BLACK);// 字体设黑  if (position % 7 == 0 || position % 7 == 6) {   // 当前月信息显示   textVIEw.setTextcolor(res.getcolor(R.color.green));// 周末字体设绿色  }   if (position >= dayOfWeek && position < daysOfMonth + dayOfWeek    && (Integer.parseInt(sys_month) >= Integer.parseInt(currentMonth)&&Integer.parseInt(sys_year)==Integer.parseInt(currentYear)    ||Integer.parseInt(sys_year)> Integer.parseInt(currentYear))) {   // 当前月信息显示   int a[] = {2,6,29};//每个月不标记的天数   for (int i = 0; i < a.length; i++) {    if (position == a[i]+dayOfWeek-1) {     textVIEw.setBackgroundcolor(res.getcolor(R.color.yellow));//为写日记日期填充黄色     ivPen.setVisibility(VIEw.INVISIBLE);     break;    } else {     ivPen.setVisibility(VIEw.VISIBLE);    }   }  } else if (position < dayOfWeek || position >= daysOfMonth + dayOfWeek) {   textVIEw.setTextcolor(res.getcolor(R.color.bg_gray));  }   if (Integer.parseInt(sys_year)==Integer.parseInt(currentYear)    &&Integer.parseInt(sys_month) == Integer.parseInt(currentMonth)&& currentFlag < position) {   // 设置本月当天之后的背景   textVIEw.setBackgroundcolor(res.getcolor(R.color.bg_gray));//全部填充灰色   ivPen.setVisibility(VIEw.INVISIBLE);  }   if (currentFlag == position) {   //设置当天的背景   textVIEw.setBackgroundcolor(res.getcolor(R.color.blue));   textVIEw.setTextcolor(color.WHITE);  }  return convertVIEw; }  // 得到某年的某月的天数且这月的第一天是星期几 public voID getCalendar(int year,int month) {  isLeapYear = sc.isLeapYear(year); // 是否为闰年  daysOfMonth = sc.getDaysOfMonth(isLeapYear,month); // 某月的总天数  dayOfWeek = sc.getWeekdayOfMonth(year,month); // 某月第一天为星期几  lastDaysOfMonth = sc.getDaysOfMonth(isLeapYear,month - 1); // 上一个月的总天数  getWeek(year,month); }  // 将一个月中的每一天的值添加入数组dayNuber中 private voID getWeek(int year,int month) {  int j = 1;  // 得到当前月的所有日程日期(这些日期需要标记)  for (int i = 0; i < dayNumber.length; i++) {   if (i < dayOfWeek) { // 前一个月    int temp = lastDaysOfMonth - dayOfWeek + 1;    dayNumber[i] = (temp + i) + "" ;   } else if (i < daysOfMonth + dayOfWeek) { // 本月    String day = String.valueOf(i - dayOfWeek + 1); // 得到的日期    dayNumber[i] = i - dayOfWeek + 1 + "";    // 对于当前月才去标记当前日期    if (sys_year.equals(String.valueOf(year)) && sys_month.equals(String.valueOf(month)) && sys_day.equals(day)) {     // 标记当前日期     currentFlag = i;    }    setShowYear(String.valueOf(year));    setShowMonth(String.valueOf(month));   } else { // 下一个月    dayNumber[i] = j + "";    j++;   }  } }  /**  * 点击每一个item时返回item中的日期  * @param position  * @return  */ public String getDateByClickItem(int position) {  return dayNumber[position]; }  /**  * 在点击grIDVIEw时,得到这个月中第一天的位置  * @return  */ public int getStartposition() {  return dayOfWeek + 7; }  /**  * 在点击grIDVIEw时,得到这个月中最后一天的位置  * @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; }}

在MainActivity点击显示日历,可以指定PopWindow在哪一个控件的下方出现

public class MainActivity extends AppCompatActivity {  @OverrIDe protected voID onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentVIEw(R.layout.activity_main);   final button button = (button)findVIEwByID(R.ID.button);  button.setonClickListener(new VIEw.OnClickListener() {   @OverrIDe   public voID onClick(VIEw vIEw) {    PopCalendar popCalendar = new PopCalendar(MainActivity.this);    popCalendar.showPopupWindow(button);   }  }); }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

您可能感兴趣的文章:Android可签到日历控件的实现方法Android 一个日历控件的实现代码Android实现日历控件示例代码Android学习教程之日历控件使用(7)Android使用GridLayout绘制自定义日历控件Android自定义日历控件实例详解 总结

以上是内存溢出为你收集整理的Android实现可滑动的自定义日历控件全部内容,希望文章能够帮你解决Android实现可滑动的自定义日历控件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1142627.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存