我的Sprint2冲刺——日历表的事件处理和管理(刘铸辉,刘静)

      我的Sprint2冲刺计划领到的任务是和刘铸辉结对编程,完成日历表的事件处理和管理,下面详细讲解下技术细节。

1.设计结构图

 


     首先要画出整个UI设计图,方便理解这个日历布局和日历样式的绘制。

        

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

        1:calender_main.xml(Calender.java用来绘制日历表和日历表中的事件)

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

           schedule_toptext:用来显示年月日,闰几月,年份和干支

          flipper:因为要实现左右滑屏,这里采用的方案是使用 ViewFlipper。我们设计的目标是显示公历 1901 - 2100 年区间的月历,相应的帧画面有 (2100 - 1900) * 12 幅帧画面,如果多创建出来,将占用非常大的内存资源。将由 ViewFlipper 来管理,由它决定某一帧何时创建,何时销毁,以节约内存资源。

        2:calender_main.xml(代码在CalenderView.java中)

           tvtext:日历gridview中的每一个item显示的textview

 

2.开始制作 Activity 画面


 

        1.首先绘制整个日历的框架

          这里有android指定的类,相关资源都从这里获取

          http://developer.android.com/guide/topics/providers/calendar-provider.html#intents

CalendarView

        2.给每一个gridview添加相应的文字,月份,农历,节日等信息

          这里面有一个要注意的是

          农历计算:农历计算的算法,来源于:http://sean.o4u.com/ap/calendar/,包名是LunarCalendar,就不贴代码了,我也是参考的这篇文章

  1 //给Gridview添加值
  2     @SuppressLint("ResourceAsColor")
  3     public View getView(int position, View convertView, ViewGroup parent) {
  4 
  5         if(convertView == null){
  6             convertView = LayoutInflater.from(context).inflate(R.layout.calendar, null);
  7          }
  8         TextView textView = (TextView) convertView.findViewById(R.id.tvtext);
  9         String d = dayNumber[position].split("\\.")[0];
 10         String dv = dayNumber[position].split("\\.")[1];
 11         Log.i("calendarview", d+","+dv);
 12         SpannableString sp = new SpannableString(d+"\n"+dv);
 13         
 14         Log.i(Tag, "SpannableString---"+sp);
 15         
 16         sp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, d.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 17         sp.setSpan(new RelativeSizeSpan(1.2f) , 0, d.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 18         sp.setSpan(new TypefaceSpan("monospace"), 0, d.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 19         
 20         if(dv != null || dv != ""){
 21             //农历显示的样式
 22             sp.setSpan(new RelativeSizeSpan(0.75f), d.length()+1, dayNumber[position].length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 23             
 24         }
 25         
 26         textView.setText(sp);
 27         textView.setTextColor(Color.RED);
 28         
 29         // 当前月字体属性,设字体和背景
 30         if (position < daysOfMonth + firstDayOfMonth+7 && position >= firstDayOfMonth+7) {
 31             
 32             textView.setTextColor(Color.BLACK);// 当月字体设黑
 33             drawable = res.getDrawable(R.drawable.item);
 34             textView.setBackgroundDrawable(drawable);
 35             //星期日和星期六加红
 36             if(position%7==0||position%7==6){
 37                 textView.setTextColor(Color.rgb(255,120,20));
 38             }
 39             
 40         }else {
 41 
 42             //设置周的字体属性,如果position为0-6
 43             if(position<7){
 44                 
 45                 textView.setTextColor(Color.BLACK);
 46                 textView.setTextSize(14.0f);
 47 //                textView.setGravity(45);
 48                 drawable = res.getDrawable(R.drawable.week_top);
 49                 textView.setBackgroundDrawable(drawable);
 50             }
 51             //设置当月其他不在月内显示的字体为浅灰色
 52             else{
 53         
 54                 textView.setTextColor(Color.rgb(200, 195, 200));
 55             }
 56         }
 57         if(schDateTagFlag != null && schDateTagFlag.length >0){
 58             for(int i = 0; i < schDateTagFlag.length; i++){
 59                 if(schDateTagFlag[i] == position){
 60                     //设置有日程安排的标记背景
 61                     textView.setBackgroundResource(R.drawable.mark);
 62                 }
 63             }
 64         }
 65         //设置当天的背景
 66         if(currentFlag == position){ 
 67             
 68             drawable = res.getDrawable(R.drawable.current_day_bgc);
 69             textView.setBackgroundDrawable(drawable);
 70             textView.setTextColor(Color.WHITE);
 71         }
 72         //获得每个月的周末
 73         Calendar calendar=Calendar.getInstance();
 74         if(calendar.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY||calendar.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY){
 75             textView.setTextColor(Color.rgb(255, 145, 90));
 76         }
 77         
 78         return convertView;
 79     }
 80     
 81     //得到某年的某月的天数且这月的第一天是星期几
 82     public void getCalendar(int year, int month){
 83         isLeapyear = specialCalendar.isLeapYear(year);              //是否为闰年
 84         daysOfMonth = specialCalendar.getDaysOfMonth(isLeapyear, month);  //某月的总天数
 85         firstDayOfMonth = specialCalendar.getWeekdayOfMonth(year, month);      //某月第一天为星期几
 86         lastDaysOfMonth = specialCalendar.getDaysOfMonth(isLeapyear, month-1);  //上一个月的总天数
 87         
 88         Log.d("DAY", isLeapyear+" ======  "+daysOfMonth+"  ============  "+firstDayOfMonth+"  =========   "+lastDaysOfMonth);
 89         getweek(year,month);
 90     }
 91     
 92     //将一个月中的每一天的值添加入数组dayNuMber中
 93     private void getweek(int year, int month) {
 94         int j = 1;
 95         int flag = 0;
 96         String lunarDay = "";
 97         
 98         //得到当前月的所有日程日期(这些日期需要标记并计数)
 99         dao = new ScheduleDAO(context);
100         ArrayList<ScheduleDateTag> dateTagList = dao.getTagDate(year,month);
101         if(dateTagList != null && dateTagList.size() > 0){
102             schDateTagFlag = new int[dateTagList.size()];
103         }
104         
105         for (int i = 0; i < dayNumber.length; i++) {
106             // 周一
107             if(i<7){
108                 dayNumber[i]=week[i]+"."+" ";
109             }
110             else if(i < firstDayOfMonth+7){  //前一个月
111                 int temp = lastDaysOfMonth - firstDayOfMonth+1-7;
112                 //获得阳历对应的农历
113                 lunarDay = lunarCalendar.getLunarDate(year, month-1, temp+i,false);
114                 dayNumber[i] = (temp + i)+"."+lunarDay;
115             }else if(i < daysOfMonth + firstDayOfMonth+7){   //本月
116                 String day = String.valueOf(i-firstDayOfMonth+1-7); 
117                 //得到的日期
118                 lunarDay = lunarCalendar.getLunarDate(year, month, i-firstDayOfMonth+1-7,false);
119                 dayNumber[i] = i-firstDayOfMonth+1-7+"."+lunarDay;
120                 //对于当前月才去标记当前日期
121                 if(sys_year.equals(String.valueOf(year)) && sys_month.equals(String.valueOf(month)) && sys_day.equals(day)){
122                     //标记当前日期
123                     currentFlag = i;
124                 }
125                 
126                 //标记日程日期
127                 if(dateTagList != null && dateTagList.size() > 0){
128                     for(int m = 0; m < dateTagList.size(); m++){
129                         ScheduleDateTag dateTag = dateTagList.get(m);
130                         int matchYear = dateTag.getYear();
131                         int matchMonth = dateTag.getMonth();
132                         int matchDay = dateTag.getDay();
133                         if(matchYear == year && matchMonth == month && matchDay == Integer.parseInt(day)){
134                             schDateTagFlag[flag] = i;
135                             flag++;
136                         }
137                     }
138                 }
139                 
140                 setShowYear(String.valueOf(year));
141                 setShowMonth(String.valueOf(month));
142                 setAnimalsYear(lunarCalendar.animalsYear(year));
143                 setLeapMonth(lunarCalendar.leapMonth == 0?"":String.valueOf(lunarCalendar.leapMonth));
144                 setCyclical(lunarCalendar.cyclical(year));
145             }else{   //下一个月
146                 lunarDay = lunarCalendar.getLunarDate(year, month+1, j,false);
147                 dayNumber[i] = j+"."+lunarDay;
148                 j++; 
149             }
150         }
151         
152         String dayStr = "";
153         for(int i = 0; i < dayNumber.length; i++){
154             dayStr = dayStr+dayNumber[i]+":";
155         }
156         Log.d("calendarview",dayStr);
157 
158 
159     }
160     
给Gridview添加值

        3.设计滑动效果ViewFlipper,给每一个滑动过去的gridview,添加一个addGridView

 1 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
 2             float velocityY) {
 3         int gvFlag = 0;         //每次添加gridview到viewflipper中时给的标记
 4         if (e1.getX() - e2.getX() > 50) {
 5             //像左滑动
 6             addGridView();   //添加一个gridView
 7             jumpMonth++;     //下一个月
 8             
 9             calV = new CalendarView(this, getResources(),jumpMonth,jumpYear,year_c,month_c,day_c);
10             gridView.setAdapter(calV);
11             //flipper.addView(gridView);
12             addTextToTopTextView(topText);
13             gvFlag++;
14             flipper.addView(gridView, gvFlag);
15             this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,R.anim.push_left_in));
16             this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.push_left_out));
17             this.flipper.showNext();
18             flipper.removeViewAt(0);
19             return true;
20         } else if (e1.getX() - e2.getX() < -50) {
21             //向右滑动
22             addGridView();   //添加一个gridView
23             jumpMonth--;     //上一个月
24             
25             calV = new CalendarView(this, getResources(),jumpMonth,jumpYear,year_c,month_c,day_c);
26             gridView.setAdapter(calV);
27             gvFlag++;
28             addTextToTopTextView(topText);
29             flipper.addView(gridView,gvFlag);
30             
31             this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,R.anim.push_right_in));
32             this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.push_right_out));
33             this.flipper.showPrevious();
34             flipper.removeViewAt(0);
35             return true;
36         }
37         return false;
38     }
onFling

        4.添加一个addGridView,并设置GridView的点击事件

  1 //添加gridview,显示具体的日期
  2     @SuppressLint("ResourceAsColor")
  3     private void addGridView() {
  4         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
  5                 LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
  6         //取得屏幕的宽度和高度
  7         WindowManager windowManager = getWindowManager();
  8         Display display = windowManager.getDefaultDisplay();
  9         int Width = display.getWidth(); 
 10         int Height = display.getHeight();
 11         
 12         Log.d(Tag, "屏幕分辨率=="+"height*weight"+Height+Width);
 13         
 14         gridView = new GridView(this);
 15         gridView.setNumColumns(7);
 16         gridView.setColumnWidth(46);
 17         if(Width == 480 && Height == 800){
 18             gridView.setColumnWidth(69);
 19         }else if(Width==800&&Height==1280){
 20             gridView.setColumnWidth(69);
 21         }
 22         
 23         
 24         gridView.setGravity(Gravity.CENTER_VERTICAL);
 25         gridView.setSelector(new ColorDrawable(Color.TRANSPARENT)); // 去除gridView边框
 26         gridView.setVerticalSpacing(1);
 27         gridView.setHorizontalSpacing(1);
 28         gridView.setBackgroundResource(R.drawable.gridview_bk);
 29         gridView.setOnTouchListener(new OnTouchListener() {
 30             //将gridview中的触摸事件回传给gestureDetector
 31             
 32             public boolean onTouch(View v, MotionEvent event) {
 33                 // TODO Auto-generated method stub
 34                 return CalendarActivity.this.gestureDetector
 35                         .onTouchEvent(event);
 36             }
 37         });
 38 
 39         
 40         gridView.setOnItemClickListener(new OnItemClickListener() {
 41             //gridView中的每一个item的点击事件
 42             
 43             public void onItemClick(AdapterView<?> arg0, View arg1, int position,
 44                     long arg3) {
 45                   //点击任何一个item,得到这个item的日期(排除点击的是周日到周六(点击不响应))
 46                   int startPosition = calV.getStartPositon();
 47                   int endPosition = calV.getEndPosition();
 48                   if(startPosition <= position  && position <= endPosition){
 49                       String scheduleDay = calV.getDateByClickItem(position).split("\\.")[0];  //这一天的阳历
 50                       //String scheduleLunarDay = calV.getDateByClickItem(position).split("\\.")[1];  //这一天的阴历
 51                       String scheduleYear = calV.getShowYear();
 52                       String scheduleMonth = calV.getShowMonth();
 53                       String week = "";
 54                      
 55                       Log.i("日程历史浏览", scheduleDay);
 56                       
 57                       //通过日期查询这一天是否被标记,如果标记了日程就查询出这天的所有日程信息
 58                       scheduleIDs = dao.getScheduleByTagDate(Integer.parseInt(scheduleYear)
 59                               , Integer.parseInt(scheduleMonth), Integer.parseInt(scheduleDay));
 60                       
 61                       //得到这一天是星期几
 62                       switch(position%7){
 63                       case 0:
 64                           week = "星期日";
 65                           break;
 66                       case 1:
 67                           week = "星期一";
 68                           break;
 69                       case 2:
 70                           week = "星期二";
 71                           break;
 72                       case 3:
 73                           week = "星期三";
 74                           break;
 75                       case 4:
 76                           week = "星期四";
 77                           break;
 78                       case 5:
 79                           week = "星期五";
 80                           break;
 81                       case 6:
 82                           week = "星期六";
 83                           break;
 84                       }
 85                      
 86                       scheduleDate = new ArrayList<String>();
 87                       scheduleDate.add(scheduleYear);
 88                       scheduleDate.add(scheduleMonth);
 89                       scheduleDate.add(scheduleDay);
 90                       scheduleDate.add(week);
 91                       
 92                       
 93                        LayoutInflater inflater=getLayoutInflater();
 94                           View linearlayout= inflater.inflate(R.layout.schedule_detail, null);
 95                            add=(Button)linearlayout.findViewById(R.id.btn_add);
 96                            quit=(Button) linearlayout.findViewById(R.id.btn_back);
 97                        day_tv=(TextView) linearlayout.findViewById(R.id.todayDate);
 98                           launarDay=(TextView)linearlayout.findViewById(R.id.tv_launar);
 99                       schdule_tip=(com.dream.tdzhushou.base.BorderTextView)linearlayout.findViewById(R.id.schdule_tip);
100                        listView=(ListView)linearlayout.findViewById(R.id.schedulelist1);
101                           //星期
102                            weekday=(TextView)linearlayout.findViewById(R.id.dayofweek);
103                           //农历日期
104                            lunarTime=(TextView)linearlayout.findViewById(R.id.lunarTime);
105                           list=(ListView)linearlayout.findViewById(R.id.schedulelist1);
106                       
107                        dateInfo=scheduleYear+"年"+scheduleMonth+"月"+scheduleDay+"日";
108                       //添加农历信息    
109                       String scheduleLunarDay = getLunarDay(Integer.parseInt(scheduleYear),
110                             Integer.parseInt(scheduleMonth), Integer.parseInt(scheduleDay));
111                       
112                       Log.i("LunarDay", scheduleLunarDay);
113                       //设置选中的日期的阳历,星期和农历信息
114                           day_tv.setText(dateInfo);
115                           weekday.setText(week);
116                           addLunarDayInfo(lunarTime);
117                           launarDay.setText( scheduleLunarDay);
118                           
119                           Log.i("scheduleDate", "scheduleDate的所有信息:"+scheduleDate);
120                           //添加日程按钮
121                           //TableLayout dialog_tab=(TableLayout) linearlayout.findViewById(R.id.dialog_tab);
122                           add.setOnClickListener(new OnClickListener() {
123                             
124                             public void onClick(View v) {
125                                 // TODO Auto-generated method stub
126                                 if(builder!=null&&builder.isShowing()){
127                                     builder.dismiss();
128                                     Intent intent = new Intent();
129                                       intent.putStringArrayListExtra("scheduleDate", scheduleDate);
130                                       intent.setClass(CalendarActivity.this, ScheduleViewAddActivity.class);
131                                       startActivity(intent);
132                                 }
133                             }
134                         });
135                           //返回按钮
136                           quit.setOnClickListener(new OnClickListener() {
137                             
138                             public void onClick(View v) {
139                                 // TODO Auto-generated method stub
140                                 if(builder!=null&&builder.isShowing()){
141                                     builder.dismiss();
142                                 }
143                             }
144                         });
145                       
146                       //如果被标记,则加载相应的日程信息列表
147                   if(scheduleIDs != null && scheduleIDs.length > 0){
148                       
149                       
150                               //list.setAdapter(new MyAdapter());
151                               View inflate=getLayoutInflater().inflate(R.layout.schedule_detail_item, null);
152                         //通过arraylist绑定数据导listview中去
153                               ArrayList<HashMap<String,String>> Data = new ArrayList<HashMap<String, String>>();  
154                             ScheduleDAO dao=new ScheduleDAO(CalendarActivity.this);
155                              String time="";
156                               String content="";
157                           for(int i=0;i<scheduleIDs.length;i++){
158                           scheduleVO=dao.getScheduleByID(CalendarActivity.this,Integer.parseInt(scheduleIDs[i]));
159                          time="";
160                          content="";
161                           
162                           time=dateInfo+" "+scheduleVO.getTime();
163                           content=scheduleVO.getScheduleContent();
164                             
165                          
166                          
167                               HashMap<String, String> map=new HashMap<String, String>();
168                               map.put("date", time);
169                               map.put("content", content);
170                                   Data.add(map);
171                                   
172                           }
173                          String  from[]={"date","content"};
174                           int to[]={R.id.itemTime,R.id.itemContent};
175                           
176                           SimpleAdapter adapter=new SimpleAdapter(CalendarActivity.this, Data, R.layout.schedule_detail_item, from, to);
177                           
178                           list.setAdapter(adapter);
179                           
180                           //点击list的item相应事件
181 //                          list.setOnClickListener(CalendarActivity.this);
182 //                          list.setOnLongClickListener(CalendarActivity.this);
183             
184                           
185                       }else{ //如果没有标记位直接则跟换为“暂无安排”
186                      
187                           
188                           schdule_tip.setText("暂无安排");
189                           listView.setVisibility(View.INVISIBLE);
190                           
191 
192                       }
193                       
194                   builder =    new Dialog(CalendarActivity.this,R.style.FullScreenDialog);
195                   builder.setContentView(linearlayout);
196                   WindowManager windowManager = getWindowManager();
197                   Display display = windowManager.getDefaultDisplay();
198                   WindowManager.LayoutParams lp = builder.getWindow().getAttributes();
199                   lp.width = (int)(display.getWidth()); //设置宽度
200                   lp.height=display.getHeight();
201                   builder.getWindow().setAttributes(lp); 
202                   builder.setCanceledOnTouchOutside(true);
203                   builder.show();
204                       
205                   list.setOnItemClickListener(new OnItemClickListener() {
206 
207                     @Override
208                         public void onItemClick(AdapterView<?> adapterview,
209                                 View view, int position, long id) {
210 
211                             
212                             Log.i("日程item点击", "第"+position+"个item");
213                             Intent intent=new Intent();
214                             
215                             if(view!=null){
216                             
217                                 HashMap<String, String> map=(HashMap<String, String>) adapterview.getItemAtPosition(position);
218                                 
219                                 ScheduleVO scheduleVO=  (ScheduleVO) view.getTag();//                                
220                                 Log.i("scheduleVo", "scheduleVO的值="+scheduleVO);
221                                 
222                                 if(scheduleDate!=null){
223                                     //intent.putStringArrayListExtra("scheduleDate", scheduleDate);
224                                     intent.setClass(CalendarActivity.this,ScheduleInfoDetailActivity.class);
225                                     intent.putStringArrayListExtra("scheduleDate", scheduleDate);
226                                 intent.putExtra("scheduleVO", scheduleVO);
227                                     
228                                     Log.i("scheduleVo", "往intent存放的值"+scheduleVO);
229                                           startActivity(intent);
230                                     
231                                 }
232                             }
233                             
234                     }
235                 }); 
236                   }
237             }
238         });
239         gridView.setLayoutParams(params);
240     }
241     
addGridView

 

        使用 ViewPager 是因为我在官方教程里看到了这篇文章:Using ViewPager for Screen Slides,里面还提供了例程下载,再结合上图,可以了解整个过程。

        运行的流程按我的理解如下:

         <!--[if !supportLists]-->1 首先要点击到每周日历表CalendarActivity执行,当屏幕初始化显示时,调用 onCreate() (这里用回调方式,可以避免对象在内存中创建,但未让屏幕显示时被执行画图处理,可以节约系统开支)

         <!--[if !supportLists]-->2 <!--[endif]-->onCreate() 中初始化 ViewFlipper,给出用于页帧管理的对象 CalendarView;并且初始化gridView的设置addGridView设置初始要显示的页码。

         <!--[if !supportLists]-->3 初始化日历表和日历表中每一个GridView中的信息后,滑动屏幕,会自动跳转到下一个月的信息,并再次初始化CalendarView,addGridView中的信息,并释放上一个ViewFlipper的资源。

         <!--[if !supportLists]-->4 <!--[endif]-->当某一帧要在屏幕上显示时,CalendarView,addGridView类的 onCreateView() 方法被回调,在 onCreateView() 方法里,CalendarView类的 getView 方法接着被调用,在循环里反复调用,直到一整个月所有的单元格被创建。

        5.在点击其中一个gridView时,跳转到ScheduleViewAddActivity,给相应的日期添加日程,并保存在数据库中。

posted on 2014-05-06 18:42  夜雨闻香  阅读(612)  评论(0编辑  收藏  举报