精华内容
下载资源
问答
  • Android日历开发详解

    2021-06-05 03:03:10
    [TOC]对于一款轻度使用的日历,很多开源库都可以直接使用。看了不少开源的日历,很多一旦重度使用,就会出现性能问题,也有的代码重复率太高了,周历和月历的代码几乎80%都是重复的,一旦改动月历,周历也得跟着改。...

    66b52468c121889b900d4956032f1009.png

    8种机械键盘轴体对比

    本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

    [TOC]

    对于一款轻度使用的日历,很多开源库都可以直接使用。看了不少开源的日历,很多一旦重度使用,就会出现性能问题,也有的代码重复率太高了,周历和月历的代码几乎80%都是重复的,一旦改动月历,周历也得跟着改。所以对于重度使用的日历,就需要自己写了。

    先来看看我们需要的效果:

    14957105595303.gif

    我们的目标是:月视图和周视图可以切换

    月视图左右滑动切换一个月,周视图左右滑动切换一周````````````````

    月视图可以指定是否显示节假日和农历

    月视图可以指定是否自动根据当月天数设置总行数

    月视图可以指定起始日期,比如从每月5日开始算,那么显示的这个个月的日期就是当月5日到下个月4日。

    月视图可以根据数据大小显示波浪图(三阶贝塞尔曲线)

    手指往上滑可以切换为周视图,继续上滑可以隐藏日历,显示汇总数据

    基本实现思路

    布局

    1.最外层:日历和日历下方的内容都放在一个Layout容器里面,在这个容器里处理各种滑动事件。

    2.中间层:日历放在一个ViewPager中,可以左右滑动切换

    3.最内层:根据经验,日历视图如果采用layout文件,那么将会inflate几十次layout,性能将会非常差,如果采用RecycleView,做成几十个格子,也是需要inflate几十次的,性能上也不行。所以,只能手动绘制,缺点是跟layout文件比起来,没有layout布局方便,需要手动绘制,优点是性能很好。

    结构

    结构上我们尽量增加代码复用,减少重复的代码。在日历视图和ViewPager,通过类型判断当前是周视图还是月视图。

    采用MVP模式,分离视图的显示和数据的加载

    日历数据

    使用List存储日历上的数据,遍历这个list,依次绘制出整个页面。每个日历格子需要的数据都存放在一个DaySumInfo对象中,根据这个对象的属性绘制相应的日期和其他数据。

    我们需要一个日期数据中心,用来缓存日期数据,存放全局变量(比如当前页面选中的日期,这个是多个类共用的)。如果日历需要显示自定义的数据的话,还需要一个APP数据中心,用来缓存需要显示在日历中的APP数据。

    我们统一采用Calendar对象作为日历的日期标识。

    展开全文
  • android 日历开发附源码(附源码)

    千次阅读 2020-05-20 23:21:01
    这里主要记录一下在编写日历控件过程中一些主要的点: 一、主要功能 1、支持农历、节气、常用节假日 2、日期范围设置,默认支持的最大日期范围[1900.1~2049.12] 3、禁用日期范围设置 4、初始化选中单个或多个...

    这里主要记录一下在编写日历apk过程中一些主要的点:先看下效果图

    一、主要功能

    • 1、支持农历、节气、常用节假日
    • 2、使用数据库,设置计划

    二、基本结构

    我们要实现的日历控件采用GestureDetector构造器,使用OnGestureListener监听滑动。目前我们设定日历左右滑动为月份切换的操作,每一个月份显示通过GridView实现,里面的数据是通过构造CalendarView,将其绑定到GridView。每次左右滑动,都会刷新CalendarView。布局上,会在GridView上显示当前日期农历时间。

    三、主要代码及解析

    CalendarActivity.java
    
    
    /**
     * 日历显示activity
     *
     * @author 孔乙己大叔
     */
    public class CalendarActivity extends Activity implements OnGestureListener {
    
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            gestureDetector = new GestureDetector(this, this);
            flipper = (ViewFlipper) findViewById(R.id.flipper);
            flipper.removeAllViews();
            calV = new CalendarView(this, getResources(), jumpMonth, jumpYear, year_c, month_c, day_c);
            addGridView();
            gridView.setAdapter(calV);
            flipper.addView(gridView, 0);
            topText = (BorderText) findViewById(R.id.toptext);
            addTextToTopTextView(topText);
        }
    
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            int gvFlag = 0;         //每次添加gridview到viewflipper中时给的标记
            if (e1.getX() - e2.getX() > 120) {
                //像左滑动
                addGridView();   //添加一个gridView
                jumpMonth++;     //下一个月
                calV = new CalendarView(this, getResources(), jumpMonth, jumpYear, year_c, month_c, day_c);
                gridView.setAdapter(calV);
                addTextToTopTextView(topText);
                gvFlag++;
                flipper.addView(gridView, gvFlag);
                this.flipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
                this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out));
                this.flipper.showNext();
                flipper.removeViewAt(0);
                return true;
            } else if (e1.getX() - e2.getX() < -120) {
                //向右滑动
                addGridView();   //添加一个gridView
                jumpMonth--;     //上一个月
    
                calV = new CalendarView(this, getResources(), jumpMonth, jumpYear, year_c, month_c, day_c);
                gridView.setAdapter(calV);
                gvFlag++;
                addTextToTopTextView(topText);
                //flipper.addView(gridView);
                flipper.addView(gridView, gvFlag);
                this.flipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_in));
                this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_out));
                this.flipper.showPrevious();
                flipper.removeViewAt(0);
                return true;
            }
            return false;
        }
    
        /**
         * 创建菜单
         */
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            menu.add(0, menu.FIRST, menu.FIRST, "今天");
            menu.add(0, menu.FIRST + 1, menu.FIRST + 1, "跳转");
            menu.add(0, menu.FIRST + 2, menu.FIRST + 2, "日程");
            menu.add(0, menu.FIRST + 3, menu.FIRST + 3, "日期转换");
            return super.onCreateOptionsMenu(menu);
        }
    
        /**
         * 选择菜单
         */
        @Override
        public boolean onMenuItemSelected(int featureId, MenuItem item) {
            switch (item.getItemId()) {
                case Menu.FIRST:
                    //跳转到今天
                    int xMonth = jumpMonth;
                    int xYear = jumpYear;
                    int gvFlag = 0;
                    jumpMonth = 0;
                    jumpYear = 0;
                    addGridView();   //添加一个gridView
                    year_c = Integer.parseInt(currentDate.split("-")[0]);
                    month_c = Integer.parseInt(currentDate.split("-")[1]);
                    day_c = Integer.parseInt(currentDate.split("-")[2]);
                    calV = new CalendarView(this, getResources(), jumpMonth, jumpYear, year_c, month_c, day_c);
                    gridView.setAdapter(calV);
                    addTextToTopTextView(topText);
                    gvFlag++;
                    flipper.addView(gridView, gvFlag);
                    if (xMonth == 0 && xYear == 0) {
                        //nothing to do
                    } else if ((xYear == 0 && xMonth > 0) || xYear > 0) {
                        this.flipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));
                        this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out));
                        this.flipper.showNext();
                    } else {
                        this.flipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_in));
                        this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_out));
                        this.flipper.showPrevious();
                    }
                    flipper.removeViewAt(0);
                    break;
                case Menu.FIRST + 1:
    
                    new DatePickerDialog(this, new OnDateSetListener() {
    
                        @Override
                        public void onDateSet(DatePicker view, int year, int monthOfYear,
                                              int dayOfMonth) {
                            //1901-1-1 ----> 2049-12-31
                            if (year < 1901 || year > 2049) {
                                //不在查询范围内
                                new AlertDialog.Builder(CalendarActivity.this).setTitle("错误日期").setMessage("跳转日期范围(1901/1/1-2049/12/31)").setPositiveButton("确认", null).show();
                            } else {
                                int gvFlag = 0;
                                addGridView();   //添加一个gridView
                                calV = new CalendarView(CalendarActivity.this, CalendarActivity.this.getResources(), year, monthOfYear + 1, dayOfMonth);
                                gridView.setAdapter(calV);
                                addTextToTopTextView(topText);
                                gvFlag++;
                                flipper.addView(gridView, gvFlag);
                                if (year == year_c && monthOfYear + 1 == month_c) {
                                    //nothing to do
                                }
                                if ((year == year_c && monthOfYear + 1 > month_c) || year > year_c) {
                                    CalendarActivity.this.flipper.setInAnimation(AnimationUtils.loadAnimation(CalendarActivity.this, R.anim.push_left_in));
                                    CalendarActivity.this.flipper.setOutAnimation(AnimationUtils.loadAnimation(CalendarActivity.this, R.anim.push_left_out));
                                    CalendarActivity.this.flipper.showNext();
                                } else {
                                    CalendarActivity.this.flipper.setInAnimation(AnimationUtils.loadAnimation(CalendarActivity.this, R.anim.push_right_in));
                                    CalendarActivity.this.flipper.setOutAnimation(AnimationUtils.loadAnimation(CalendarActivity.this, R.anim.push_right_out));
                                    CalendarActivity.this.flipper.showPrevious();
                                }
                                flipper.removeViewAt(0);
                                //跳转之后将跳转之后的日期设置为当期日期
                                year_c = year;
                                month_c = monthOfYear + 1;
                                day_c = dayOfMonth;
                                jumpMonth = 0;
                                jumpYear = 0;
                            }
                        }
                    }, year_c, month_c - 1, day_c).show();
                    break;
                case Menu.FIRST + 2:
                    Intent intent = new Intent();
                    intent.setClass(CalendarActivity.this, ScheduleAll.class);
                    startActivity(intent);
                    break;
                case Menu.FIRST + 3:
                    Intent intent1 = new Intent();
                    intent1.setClass(CalendarActivity.this, CalendarConvert.class);
                    intent1.putExtra("date", new int[]{year_c, month_c, day_c});
                    startActivity(intent1);
                    break;
            }
            return super.onMenuItemSelected(featureId, item);
        }
    
        
    
        //添加头部的年份 闰哪月等信息
        public void addTextToTopTextView(TextView view) {
            StringBuffer textDate = new StringBuffer();
            view.setBackgroundResource(R.drawable.top_day);
            view.setBackground(getResources().getDrawable(R.drawable.top_day));
            textDate.append(calV.getShowYear()).append("年").append(calV.getShowMonth()).append("月").append("\t");
            if (!calV.getLeapMonth().equals("") && calV.getLeapMonth() != null) {
                textDate.append("闰").append(calV.getLeapMonth()).append("月").append("\t");
            }
            textDate.append(calV.getAnimalsYear()).append("年").append("(").append(calV.getCyclical()).append("年)");
            view.setText(textDate);
            view.setTextColor(Color.BLACK);
            view.setTypeface(Typeface.DEFAULT_BOLD);
        }
    
        //添加gridview
        private void addGridView() {
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    
            DisplayMetrics displayMetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
            int Width = displayMetrics.widthPixels;
            int Height = displayMetrics.heightPixels;
            gridView = new GridView(this);
            gridView.setNumColumns(7);
            gridView.setColumnWidth(46);
    
            if (Width == 480 && Height == 800) {
                gridView.setColumnWidth(69);
            }
            gridView.setGravity(Gravity.CENTER_VERTICAL);
            gridView.setSelector(new ColorDrawable(Color.TRANSPARENT)); // 去除gridView边框
            gridView.setVerticalSpacing(1);
            gridView.setHorizontalSpacing(1);
            gridView.setBackgroundResource(R.drawable.gridview_bk);
            gridView.setOnTouchListener(new OnTouchListener() {
                //将gridview中的触摸事件回传给gestureDetector
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    return CalendarActivity.this.gestureDetector
                            .onTouchEvent(event);
                }
            });
    
            gridView.setOnItemClickListener(new OnItemClickListener() {
                //gridView中的每一个item的点击事件
                @Override
                public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                                        long arg3) {
                    //点击任何一个item,得到这个item的日期(排除点击的是周日到周六(点击不响应))
                    int startPosition = calV.getStartPositon();
                    int endPosition = calV.getEndPosition();
                    if (startPosition <= position && position <= endPosition) {
                        String scheduleDay = calV.getDateByClickItem(position).split("\\.")[0];  //这一天的阳历
                        String scheduleYear = calV.getShowYear();
                        String scheduleMonth = calV.getShowMonth();
                        String week = "";
    
                        //通过日期查询这一天是否被标记,如果标记了日程就查询出这天的所有日程信息
                        String[] scheduleIDs = dao.getScheduleByTagDate(Integer.parseInt(scheduleYear), Integer.parseInt(scheduleMonth), Integer.parseInt(scheduleDay));
                        if (scheduleIDs != null && scheduleIDs.length > 0) {
                            //跳转到显示这一天的所有日程信息界面
                            Intent intent = new Intent();
                            intent.setClass(CalendarActivity.this, ScheduleInfoView.class);
                            intent.putExtra("scheduleID", scheduleIDs);
                            startActivity(intent);
                        } else {
                            //直接跳转到需要添加日程的界面
    
                            //得到这一天是星期几
                            switch (position % 7) {
                                case 0:
                                    week = "星期日";
                                    break;
                                case 1:
                                    week = "星期一";
                                    break;
                                case 2:
                                    week = "星期二";
                                    break;
                                case 3:
                                    week = "星期三";
                                    break;
                                case 4:
                                    week = "星期四";
                                    break;
                                case 5:
                                    week = "星期五";
                                    break;
                                case 6:
                                    week = "星期六";
                                    break;
                            }
    
                            ArrayList<String> scheduleDate = new ArrayList<String>();
                            scheduleDate.add(scheduleYear);
                            scheduleDate.add(scheduleMonth);
                            scheduleDate.add(scheduleDay);
                            scheduleDate.add(week);
                            //scheduleDate.add(scheduleLunarDay);
    
                            Intent intent = new Intent();
                            intent.putStringArrayListExtra("scheduleDate", scheduleDate);
                            intent.setClass(CalendarActivity.this, ScheduleView.class);
                            startActivity(intent);
                        }
                    }
                }
            });
            gridView.setLayoutParams(params);
        }
    }

    自定义view实现:

    
    
    /**
     * 日历gridview中的每一个item显示的textview
     *
     * @author 孔乙己大叔
     */
    public class CalendarView extends BaseAdapter {
    
    
        public CalendarView(Context context, Resources rs, int jumpMonth, int jumpYear, int year_c, int month_c, int day_c) {
            this();
            this.context = context;
            sc = new SpecialCalendar();
            lc = new LunarCalendar();
            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为滑动的次数,每滑动一次就增加一月或减一月)
            currentDay = String.valueOf(day_c);  //得到当前日期是哪天
            getCalendar(Integer.parseInt(currentYear), Integer.parseInt(currentMonth));
        }
    
        public CalendarView(Context context, Resources rs, int year, int month, int day) {
            this();
            this.context = context;
            sc = new SpecialCalendar();
            lc = new LunarCalendar();
            this.res = rs;
            currentYear = String.valueOf(year);
            ;  //得到跳转到的年份
            currentMonth = String.valueOf(month);  //得到跳转到的月份
            currentDay = String.valueOf(day);  //得到跳转到的天
    
            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, null);
            }
            TextView textView = (TextView) convertView.findViewById(R.id.tvtext);
            String d = dayNumber[position].split("\\.")[0];
            String dv = dayNumber[position].split("\\.")[1];
            //Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Helvetica.ttf");
            //textView.setTypeface(typeface);
            SpannableString sp = new SpannableString(d + "\n" + dv);
            sp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, d.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            sp.setSpan(new RelativeSizeSpan(1.2f), 0, d.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            if (dv != null || dv != "") {
                sp.setSpan(new RelativeSizeSpan(0.75f), d.length() + 1, dayNumber[position].length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            //sp.setSpan(new ForegroundColorSpan(Color.MAGENTA), 14, 16, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            textView.setText(sp);
            textView.setTextColor(Color.GRAY);
            if (position < 7) {
                //设置周
                textView.setTextColor(Color.BLACK);
                textView.setBackgroundResource(R.drawable.week_top);
            }
    
            if (position < daysOfMonth + dayOfWeek + 7 && position >= dayOfWeek + 7) {
                // 当前月信息显示
                textView.setTextColor(Color.BLACK);// 当月字体设黑
                drawable = res.getDrawable(R.drawable.item);
                //textView.setBackgroundDrawable(drawable);
                //textView.setBackgroundColor(Color.WHITE);
    
            }
            if (schDateTagFlag != null && schDateTagFlag.length > 0) {
                for (int i = 0; i < schDateTagFlag.length; i++) {
                    if (schDateTagFlag[i] == position) {
                        //设置日程标记背景
                        textView.setBackgroundResource(R.drawable.mark);
                    }
                }
            }
            if (currentFlag == position) {
                //设置当天的背景
                textView.setBackgroundResource(R.drawable.current_day_bgc);
                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);  //上一个月的总天数
            Log.d("DAY", isLeapyear + " ======  " + daysOfMonth + "  ============  " + dayOfWeek + "  =========   " + lastDaysOfMonth);
            getweek(year, month);
        }
    
        //将一个月中的每一天的值添加入数组dayNuber中
        private void getweek(int year, int month) {
            int j = 1;
            int flag = 0;
            String lunarDay = "";
            //得到当前月的所有日程日期(这些日期需要标记)
            dao = new ScheduleDAO(context);
            ArrayList<ScheduleDateTag> dateTagList = dao.getTagDate(year, month);
            if (dateTagList != null && dateTagList.size() > 0) {
                schDateTagFlag = new int[dateTagList.size()];
            }
            for (int i = 0; i < dayNumber.length; i++) {
                // 周一
                if (i < 7) {
                    dayNumber[i] = week[i] + "." + " ";
                } else if (i < dayOfWeek + 7) {  //前一个月
                    int temp = lastDaysOfMonth - dayOfWeek + 1 - 7;
                    lunarDay = lc.getLunarDate(year, month - 1, temp + i, false);
                    dayNumber[i] = (temp + i) + "." + lunarDay;
                } else if (i < daysOfMonth + dayOfWeek + 7) {   //本月
                    String day = String.valueOf(i - dayOfWeek + 1 - 7);   //得到的日期
                    lunarDay = lc.getLunarDate(year, month, i - dayOfWeek + 1 - 7, false);
                    dayNumber[i] = i - dayOfWeek + 1 - 7 + "." + lunarDay;
                    //对于当前月才去标记当前日期
                    if (sys_year.equals(String.valueOf(year)) && sys_month.equals(String.valueOf(month)) && sys_day.equals(day)) {
                        //笔记当前日期
                        currentFlag = i;
                    }
                    //标记日程日期
                    if (dateTagList != null && dateTagList.size() > 0) {
                        for (int m = 0; m < dateTagList.size(); m++) {
                            ScheduleDateTag dateTag = dateTagList.get(m);
                            int matchYear = dateTag.getYear();
                            int matchMonth = dateTag.getMonth();
                            int matchDay = dateTag.getDay();
                            if (matchYear == year && matchMonth == month && matchDay == Integer.parseInt(day)) {
                                schDateTagFlag[flag] = i;
                                flag++;
                            }
                        }
                    }
                    setShowYear(String.valueOf(year));
                    setShowMonth(String.valueOf(month));
                    setAnimalsYear(lc.animalsYear(year));
                    setLeapMonth(lc.leapMonth == 0 ? "" : String.valueOf(lc.leapMonth));
                    setCyclical(lc.cyclical(year));
                } else {   //下一个月
                    lunarDay = lc.getLunarDate(year, month + 1, j, false);
                    dayNumber[i] = j + "." + lunarDay;
                    j++;
                }
            }
            String abc = "";
            for (int i = 0; i < dayNumber.length; i++) {
                abc = abc + dayNumber[i] + ":";
            }
            Log.d("DAYNUMBER", abc);
        }
      
    }
    

    判断是否为闰年,当月多少天数,当天是星期几代码实现:

    // 判断是否为闰年
        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;
        }
    
        //得到某月有多少天数
        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;
        }
    
        //指定某年中的某月的第一天是星期几
        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;
        }

    四、小结

    这里我们只介绍了日历的基本实现原理,和一些关键的点,其实这种实现方式相对还是比较简单的,容易理解,当然难免有不足的地方,后边根据需要再逐步完善和扩展吧。数据库操作暂时没进行解析,后面会单独用demo说明。

    源码下载地址:https://download.csdn.net/download/Ctrl_qun/12436629

    展开全文
  • 决定开始学习 Android 平台下的软件开发,以日历作为实践项目,进行一周后,基本完成,有需要的朋友可以参考下
  • 自己用android stdio 写的日历APP,把源代码上传到这里供大家交流学习!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  • Android 日历开发教程[一]

    万次阅读 多人点赞 2013-01-02 21:49:13
    前言:决定开始学习 Android 平台下的软件开发,以日历作为实践项目,进行一周后,基本完成。 为了总结及笔记,并给有需要的朋友借鉴,开始整理本教程。  开始之前:  在编写程序之前,需要进行项目设计,...

      前言:决定开始学习 Android 平台下的软件开发,以日历作为实践项目,进行一周后,基本完成。 为了总结及笔记,并给有需要的朋友借鉴,开始整理本教程。


      开始之前:

        在编写程序之前,需要进行项目设计,因为是练习项目,主要是确定软件 UI 界面,这是已经完成的屏幕截图:



    对这个画面,进一步作分解:


    这里总共分解为三个 View 文件:

    1:activity_main.xml

      作为启动的主画面,新建项目时,首先生成。

    2:view_calendar_table.xml

      定义月历视图,头部固定,其它行由代码动态添加。

    3:view_calendar_day_cell.xml

      定义每一天的视图,主要由三个元素组成:公历日期,农历信息,是否是今天的标记图像。


    相应的代码类定义:


    因为要实现左右滑屏,这里采用的方案是使用 ViewPager。CalendarPagerAdapter 为 ViewPager 提供多帧管理,我们设计的目标是显示公历 1901 - 2100 年区间的月历,相应的帧画面有 (2100 - 1900) * 12 幅帧画面,如果多创建出来,将占用非常大的内存资源。将由 ViewPager 来管理,由它决定某一帧何时创建,何时销毁,以节约内存资源。更多信息请参考:http://developer.android.com/reference/android/support/v4/view/ViewPager.html


    [待续] 下节图解创建 view

    展开全文
  • 【IT168技术】我们大家都知道,在Android平台3.0中才新增了日历视图控件,可以显示网格状的日历内容,那么对于3.0以下的版本要使用日历控件只能借助第三方,目前用的最多的是CalendarView。先简单介绍下CalendarView...

    【IT168技术】我们大家都知道,在Android平台3.0中才新增了日历视图控件,可以显示网格状的日历内容,那么对于3.0以下的版本要使用日历控件只能借助第三方,目前用的最多的是CalendarView。

    先简单介绍下CalendarView日历控件的使用。

    android.widget.CalendarView是从android.widget.FrameLayout中继承。

    CalendarView 类提供了基本的日历设置方法:

    long getDate() 获取从1970年,1月1日,0点0分0秒到现在的毫秒数,因为返回是long型最终只能截止到2038年

    int getFirstDayOfWeek() //获取当天是本周的第几天,Android123提示返回的定义在java.util.Calendar类中,比如Calendar.Monday为星期一,定义值为2。

    long getMaxDate() //获取CalendarView支持1970年到那天的最大天数

    long getMinDate() //获取CalendarView支持1970年到那天的最小天数

    boolean getShowWeekNumber() //获取是否显示星期号

    boolean isEnabled() //是否显示本日历视图

    public void setDate (long date, boolean animate, boolean center) //设置选择日期到1970年的描述

    void setDate(long date) //设置选择的日期描述到1970年

    void setEnabled(boolean enabled) //设置是否启用视图

    void setFirstDayOfWeek(int firstDayOfWeek) //设置本周起始天数

    void setMaxDate(long maxDate)

    void setMinDate(long minDate)

    void setOnDateChangeListener(CalendarView.OnDateChangeListener listener) //日历视图修改的接口,这个介绍看下面。

    void setShowWeekNumber(boolean showWeekNumber) //设置是否显示周号

    有关日历控件CalendarView的设置接口 android.widget.CalendarView.OnDateChangeListener 只实现了一个回调方法void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth)。

    这四个参数的具体介绍为

    view The view associated with this listener.

    year The year that was set.

    month The month that was set [0-11].

    dayOfMonth The day of the month that was set.

    下面给大家展示这几种有用的日历控件效果图:

    7f1d75c562ee39b6e10aeb894de00b98.png

    这是CalendarView的效果图。可以实现上月和下月翻页,设置事件等。

    7dd5677053cbc2f0aab38a49c6cc6839.png

    这个日历控件也比较强大,但外观不够友好。

    9dc6215b6b79fcb79246d4b76067669c.png

    cbd7529f4782a6d27b0e085e691b1f9f.png

    这是我们自己实现的日历控件。可以通过选择日期查询相关数据等操作。

    6abffbf723b4e20513a1c7a95b0b96d5.png

    这是Android3.0及以上版本自带的日历控件。

    展开全文
  • 基于 Android日历系统的完整实现过程
  • Android又一个超漂亮的日历控件

    千次下载 热门讨论 2014-07-23 14:09:49
    Android又一个超漂亮的日历控件,非常好用!
  • 自己做的一个日历实现了一个记事本功能,希望对大家有用
  • 安卓-一个简单的日历,可折叠,可打开,可单行滑动,选择等等
  • Android日历签到

    2015-12-25 17:35:35
    Android获取当天的日子进行签到标记
  • PAGE I摘 要Android系统凭借其良好的用户体验,低廉的成本及高开放性产生了巨大的应用量和广阔的应用面。如今,基于android系统的...而日历应用作为智能终端的出场必备控件,更是android系统中不可或缺的一部分。...
  • 安卓打造自己的日历控件

    千次阅读 2019-11-10 20:11:22
    /** * 日历 */ public static List getCalendar(int currentYear, int currentMonth) { //实例化集合 List list = new ArrayList(); Calendar c = Calendar.getInstance(); c.clear(); /** * 处理上个月月末 */ if ...
  • android项目开发日历

    2014-05-31 16:57:30
    美观的日历切换界面,以及优化的背景图片。适用于初学者研究学习,更好的借鉴。
  • Android实现自定义日历

    2021-01-04 02:37:15
    自定义日历控件,支持旧历、节气、日期标注、点击操作 (参考网络上的日历控件改写) 注:将下面的四张资源图片拷贝到所建包的下一个image目录中,如Calendar.java 所在包为 cc.util.android.view,则需要再创建一个...
  • android日历记事本

    热门讨论 2014-07-01 09:50:33
    日历记事本,可用于日程安排等,包括日历,日程安排,定时提醒等记事本全部功能。
  • 主要介绍了Android开发日历CalendarView用法,简单分析了日历CalendarView组件的功能、属性设置方法、界面布局、事件监听等相关操作技巧,需要的朋友可以参考下
  • Android 日历开发教程[四]

    万次阅读 热门讨论 2013-01-03 16:43:26
    这节开始制作 Activity 视图。 视图的设计,在原理上可以借鉴 ...同样,Android 的视图也可以分为 Activity XML 文件 与 style.xml 及其它资源文件(color, dimens, string, share ...),尽可能将布局样式的定
  • Android 日历开发教程[二]

    千次阅读 2013-01-03 07:25:52
    一、创建 Android Project 在新建对话框中输入 App 属性,SDK版本全部选最新的,不作版本兼容。主题选择 Holo Dark。 下一步,使用默认设置 下一步,使用默认设置 下一步,使用默认配置 下...
  • 决定开始学习 Android 平台下的软件开发,以日历作为实践项目,进行一周后,基本完成,有需要的朋友可以参考下
  • android日历的实现

    2014-03-18 15:04:28
    android 日历自己的实现,如何快速简单的实现,日历的循环实现!!!
  • 昨天实现了一个日历控件,主要包含公历和农历的展示,今天将其完成全部功能,主要包含节假日的展示、二十四节气展示。支持手势滑动显示下一个月.如有实现不合理的地方希望大家提供宝贵的意见。
  • Android 实现日历功能特别简单

    千次阅读 2021-04-25 18:14:48
    接下来讲一下安卓实现日历功能,网上也有很多,我感觉这个相对简单一点. 效果图: 日期选择 效果图:时间选择 二.这个特别简单哈这,边弄了一个方法直接复制代码就可以使用了. 主要是下面单独写的那两个方法哦....
  • 主要介绍了Android 仿日历翻页、仿htc时钟翻页、数字翻页切换效果,需要的朋友可以参考下
  • 安卓简单日历的实现

    万次阅读 热门讨论 2016-08-24 17:02:01
    最近无聊在做一个项目,需要用到日历日历并不需要太复杂,只需要能够简单的查看就行,所以我选用了java提供的Calendar类,和安卓的gridView组合的形式.
  • 背景开发过程中,我们经常会遇见使用日历组件,有时候需要我们自己做高度自定义。因此下面我们来讲一下如何使用合适的算法来绘制我们自己的日历组件。需求分析要显示一个日历组件,我们需要知道日历的大致外观是怎么...
  • 酒店预订时选择时间日期的控件Demo,希望是你想要得东西 原地址 https://blog.csdn.net/RingoPaul/article/details/79528858 gitHub: https://github.com/AndroidJet/HotelCalendar
  • Android-CalendarView-masterAndroid开发实现自定义日历、日期选择控件 最近项目需要日历效果,考虑用第三方的反而不太适合设计需求,修改复杂,与其这样不入自己重新写一个干净的控件。虽不是什么牛逼控件,但是也...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,672
精华内容 6,668
关键字:

安卓日历开发