实现去哪儿来回机票选择的view
最近有个控件是实现和去哪儿和阿里旅行的app的选择日历效果,反编译没有效果的情况下我自己实现了个,大致的原理是:
上面是产品需要实现的效果,我看了下不就是一个ListView+gridView就能实现么,方案有了,自定义的CalendarView实现对日期的计算,然后可以按ios显示的风格显示日历
public class MyCalendar extends LinearLayout { private static Context context; private Date theInDay; private String inday = "", outday = ""; private List<String> gvList;//存放天 private CalGridViewAdapter calAdapter; private OnDaySelectListener callBack;//回调函数 public MyCalendar(Context context) { super(context); this.context = context; } public MyCalendar(Context context, AttributeSet attrs) { super(context, attrs); this.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>();//存放天 Calendar cal = Calendar.getInstance();//获取日历实例 cal.setTime(theInDay);//cal设置为当天的 );//cal设置当前day为当前月第一天 int tempSum = countNeedHowMuchEmpety(cal);//获取当前月第一天为星期几 int dayNumInMonth = getDayNumInMonth(cal);//获取当前月有多少天 ))); 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() + "月"); MyGridView gv = (MyGridView) view.findViewById(R.id.gv_calendar); calAdapter = new CalGridViewAdapter(context,gvList, inday, outday); gv.setAdapter(calAdapter); 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[]; if (!" ".equals(day)) { ) { day = ]; } choiceDay = date[] + "-" + day; if (callBack != null) {//调用回调函数回调数据 callBack.onDaySelectListener(arg1, choiceDay); } } } }); } /** * 为gridview中添加需要展示的数据 * * @param tempSum * @param dayNumInMonth */ private void setGvListData(int tempSum, int dayNumInMonth, String YM) { if (gvList!=null){ gvList.clear(); ; i < tempSum; i++) { gvList.add(" , "); } ; j <= dayNumInMonth; j++) { gvList.add(YM + "," + String.valueOf(j)); } } } private String getMonth(int month) { String mon = ""; ) { mon = "0" + month; } else { mon = "" + month; } return mon; } /** * 获取当前月的总共天数 * * @param cal * @return */ private int getDayNumInMonth(Calendar cal) { return cal.getActualMaximum(Calendar.DATE); } /** * 获取当前月第一天在第一个礼拜的第几天,得出第一天是星期几 * * @param cal * @return */ private int countNeedHowMuchEmpety(Calendar cal) { ; return firstDayInWeek; } public void setDefaultInView(int color,int textColor){ if (calAdapter!=null){ calAdapter.viewIn.setBackgroundColor(color); ((TextView)calAdapter.viewIn.findViewById(R.id.tv_calendar_day)).setTextColor(textColor); } } public void setDefaultOutView(int color,int textColor){ if (calAdapter!=null){ calAdapter.viewOut.setBackgroundColor(color); ((TextView)calAdapter.viewOut.findViewById(R.id.tv_calendar_day)).setTextColor(textColor); } } //监听是否点击接口 public interface OnDaySelectListener { void onDaySelectListener(View view, String date); } public void setOnDaySelectListener(OnDaySelectListener o) { callBack = o; } }
接下来是在Activity中实现绘制,由于我项目的需要只可以选择当前日期后90的时间,具体看代码
public class MainActivity extends Activity implements OnDaySelectListener { private LinearLayout ll; private TextView cancel; private MyCalendar c1; private TextView toast; String nowday; ***;//一天的毫秒数 SimpleDateFormat simpleDateFormat, formatYear, formatDay; SharedPreferences sp; SharedPreferences.Editor editor; private String inday,outday,sp_inday,sp_outday; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sp=getSharedPreferences("date", Context.MODE_PRIVATE); //本地保存 sp_inday=sp.getString("dateIn", ""); sp_outday=sp.getString("dateOut", ""); editor=sp.edit(); simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd"); nowday=simpleDateFormat.format(new Date()); formatYear =new SimpleDateFormat("yyyy"); formatDay =new SimpleDateFormat("dd"); initView(); init(); } private void initView() { ll=(LinearLayout) findViewById(R.id.ll); cancel= (TextView) findViewById(R.id.cancel); cancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); toast= (TextView) findViewById(R.id.choose_toast); } private void init(){ List<String> listDate=getDateList(); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); ;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; ){ return; } } catch (ParseException e) { e.printStackTrace(); } //若以前已经选择了日期,则在进入日历后会显示以选择的日期,该部分作用则是重新点击日历时,清空以前选择的数据(包括背景图案) if(!"".equals(sp_inday)){ CalGridViewAdapter.viewIn.setBackgroundColor(Color.WHITE); ((TextView) CalGridViewAdapter.viewIn.findViewById(R.id.tv_calendar_day)).setTextColor(getResources().getColor(R.color.color_default)); } if(!"".equals(sp_outday)){ CalGridViewAdapter.viewOut.setBackgroundColor(Color.WHITE); ((TextView) CalGridViewAdapter.viewOut.findViewById(R.id.tv_calendar_day)).setTextColor(getResources().getColor(R.color.color_default)); // 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(]; ){ dateDay=date.split(].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("入住"); toast.setText("请选择返程日期"); inday=date; }else{ if(inday.equals(date)){ view.setBackgroundColor(Color.WHITE); textDayView.setText(dateDay); textDayView.setTextColor(getResources().getColor(R.color.color_default)); textView.setText(""); inday=""; }else{ try { if(simpleDateFormat.parse(date).getTime()<simpleDateFormat.parse(inday).getTime()){ view.setBackgroundColor(Color.WHITE); textDayView.setTextColor(getResources().getColor(R.color.color_default)); Toast.makeText(MainActivity.this, "离开日期不能小于入住日期", Toast.LENGTH_SHORT).show(); return; } } catch (ParseException e) { e.printStackTrace(); } textDayView.setText(dateDay); textView.setText("离开"); toast.setVisibility(View.GONE); outday=date; editor.putString("dateIn", inday); editor.putString("dateOut", outday); editor.commit(); finish(); } } } //根据当前日期,向后数三个月(若当前day不是1号,为满足至少90天,则需要向后数4个月) public List<String> getDateList(){ List<String> list=new ArrayList<String>(); Date date=new Date(); ; String yyyy= formatYear.format(date); String dd= formatDay.format(date); ){ list.add(simpleDateFormat.format(date)); list.add(yyyy+"-10-"+dd); list.add(yyyy+"-11-"+dd); if(!dd.equals("01")){ list.add(yyyy+"-12-"+dd); } }){ list.add(yyyy+"-10-"+dd); list.add(yyyy+"-11-"+dd); list.add(yyyy+"-12-"+dd); if(!dd.equals("01")){ list.add((Integer.parseInt(yyyy)+)+"-01-"+dd); } }){ list.add(yyyy+"-11-"+dd); list.add(yyyy+"-12-"+dd); list.add((Integer.parseInt(yyyy)+)+"-01-"+dd); if(!dd.equals("01")){ list.add((Integer.parseInt(yyyy)+)+"-02-"+dd); } }){ list.add(yyyy+"-12-"+dd); list.add((Integer.parseInt(yyyy)+)+"-01-"+dd); list.add((Integer.parseInt(yyyy)+)+"-02-"+dd); if(!dd.equals("01")){ list.add((Integer.parseInt(yyyy)+)+"-03-"+dd); } }else{ list.add(yyyy+"-"+getMon(nowMon)+"-"+dd); list.add(yyyy+))+"-"+dd); list.add(yyyy+))+"-"+dd); if(!dd.equals("01")){ list.add(yyyy+))+"-"+dd); } } return list; } public String getMon(int mon){ String month=""; ){ month="0"+mon; }else{ month=""+mon; } return month; } }
最后贴上实现的效果
最后需要代码的请到下面的地址下载:http://download.csdn.net/detail/xiangzhihong8/9435606,有问题的可以留言
实现去哪儿来回机票选择的view的更多相关文章
- UGUI 用手柄或者键盘控制选择Scroll View中的游戏对象时,滚动条跟着移动
原预制体以及脚本的下载地址:https://download.csdn.net/download/qq_15017279/10404010 1.新建一个Scroll View,删掉横向的滚动条,并且把 ...
- IOS APP开发中View的几种实现方式
xib文件有以下几个重要的属性: xib文件名 File’s Owner xib文件中的视图的Class xib文件中的视图的Outlet指向 File’s Owner 可以关联到某类,然后通过IBO ...
- iOS应用架构谈(二):View层的组织和调用方案(中)
iOS客户端应用架构看似简单,但实际上要考虑的事情不少.本文作者将以系列文章的形式来回答iOS应用架构中的种种问题,本文是其中的第二篇,主要讲View层的组织和调用方案.中篇主要讨论MVC.MVCS. ...
- iOS应用架构谈 view层的组织和调用方案
当我们开始设计View层的架构时,往往是这个App还没有开始开发,或者这个App已经发过几个版本了,然后此时需要做非常彻底的重构. 一般也就是这两种时机会去做View层架构,基于这个时机的特殊性,我们 ...
- Android -- 自定义View小Demo,绘制四位数随机码(一)
1,现在有这样一个需求,实现显示随机随机数可能在代码中直接很简单的就实现了,但是现在我们直接自定义View来实现这个效果,那么我们来分析一波吧,我们允许开发者自己设置这个textview的大小,颜色, ...
- 自定义view实现水波纹效果
水波纹效果: 1.标准正余弦水波纹: 2.非标准圆形液柱水波纹: 虽说都是水波纹,但两者在实现上差异是比较大的,一个通过正余弦函数模拟水波纹效果,另外一个会运用到图像的混合模式(PorterDuffX ...
- (转)iOS应用架构谈 view层的组织和调用方案
前言 <iOS应用架构谈 开篇>出来之后,很多人来催我赶紧出第二篇.这一篇文章出得相当艰难,因为公司里的破事儿特别多,我自己又有点私事儿,以至于能用来写博客的时间不够充分. 现在好啦,第二 ...
- view, surfaceView, invalidate, postInvalidate, 刷新屏幕
http://blog.csdn.net/linghu_java/article/details/9985489 1.view view在api中的结构 Java.lang.Object Androi ...
- ASP.NET MVC 第三回 Controller与View
这节我们让ASP.NET MVC真正的跑起来 一.新建Controller 首先我们自己新建一个新的Controller在Controllers上点右键,添加,Controller选项 之后出现一 ...
随机推荐
- 使用Java正则表达式去掉Double类型的数据后面多余的0
方法 /** * 使用java正则表达式去掉多余的.与0 * @param s * @return */ public static String subZeroAndDot(String s){ i ...
- UNIX网络编程——TCP—经受时延与nagle算法、滑动窗口、拥塞窗口
1.经受时延: TCP在接收到数据时并不立即发送ACK,相反,它推迟发送,以便将ACK与需要沿该方向发送的数据一起发送,时延为200ms,超过时延范围,发送确认. 2.nagle算法: 一个TCP连接 ...
- 学习Tensorflow,使用源码安装
PC上装好Ubuntu系统,我们一步一步来讲解如何使用源码安装tensorflow?(我的Ubuntu系统是15.10) 安装cuda 根据你的系统型号选择相应的cuda版本下载 https://de ...
- 新手学python(2):C语言调用完成数据库操作
继续介绍本人的python学习过程.本节介绍如何利用python调用c代码.内容还是基于音乐信息提取的过程,架构如图一.Python调用c实现的功能是利用python访问c语言完成mysql数据库操作 ...
- 秒懂ASP.NET中的内置对象
上篇博客,小编主要简单的介绍了一下ASP.NET中的控件,这篇博客,小编主要简单总结一下ASP.NET中的内置对象,七个内置对象分别是:Request.Response.Application.Coo ...
- 01_Weblogic课程之概念篇:代理服务器,web服务器,应用程序服务器,JNDI概念,JTA概念,Java消息服务,Java验证和授权(JAAS),Java管理扩展,Web客户机,客户机应用程序
1 什么是服务器 Weblogic中服务器分为两种,一种是受管服务器,另外一种是管理服务器. Weblogic课程(Weblogic是Oracle公司的,最开始的是BEA公司的) 一 系统管理 ...
- 【一天一道LeetCode】#97. Interleaving String
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given s ...
- foreach 内嵌的使用
foreach内部处理数据流的每条记录,进行关系操作,最后用generate返回数据给外部.但注意关系操作符不能作用于表达式,要将表达式提取成关系. foreach内部只支持distinct, fil ...
- Chipmunk僵尸物理对象的出现和解决(五)
,因为将反弹棒变长和缩短的代码是类似的所以我们只看一个即可,就让我们详细看看缩短的方法吧. +(void)doStickShorterWork:(Stick *)stick{ GameScene *g ...
- Spring揭秘 读书笔记 四----方法注入
我们知道,拥有prototype类型scope的bean,在请求方每次向容器请求该类型对象的时候,容器都会返回一个全新的该对象实例. 我们看下面的例子: public class MockNewsPe ...