实现去哪儿来回机票选择的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.lang.NullPointerException
最近做一个新闻客户端的应用,经常出现空指针的问题,我想一方面可能是自己水平有限,二是开发过程中有一些遗漏的地方.一般情况下新手出现空指针的概率较高.下面来总结一下经常出现的问题. 1.所谓的指针,就是 ...
- 【环境配置】配置maven
Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. Maven 除了以程序构建能力为特色之外,还提供高级项目管理工具.由于 Maven 的缺 ...
- 【UNIX环境高级编程】文件 IO 操作 一 ( open | close | creat | lseek | write | read )
博客地址 : http://blog.csdn.net/shulianghan/article/details/46980271 一. 文件打开关闭操作相关函数介绍 1. open 函数 (1) op ...
- Android 导入v7包常见错误,以及项目引用v7包错误解决
android下v4 v7 v21等包是android系统的扩展支持包,就想windows的系统补丁一个道理. android的扩展包主要是用来兼容低版本的,比如android3.0以后出现 ...
- Request中Attribute 和 Parameter 的区别
Attribute 和 Parameter 的区别 (1)HttpServletRequest类有setAttribute()方法,而没有setParameter()方法 (2)当两个Web组件之间为 ...
- Android面试之高级篇
结合自己之前去很多大公司的面试经历和自己面别人的一些题,这里做一些总结,Android面试中常见的面试题. 1,Android的Handler运行机制 要解释Handler的运行机制就要讲几个对象:M ...
- PHP(PHP-FPM)手动编译安装
1安装PHP 1.1下载解压 wget http://museum.php.net/php5/php-5.3.5.tar.gz tarxzvf php-5.3.5.tar.gz cdphp-5.3.5 ...
- 利用OpenCV的人脸检测给头像带上圣诞帽
我们来看下效果 原图: 效果: 原理其实很简单: 采用一张圣诞帽的png图像作为素材, 利用png图像背景是透明的,贴在背景图片上就是戴帽子的效果了. 人脸检测的目的主要是为了确定贴帽子的位置,类似p ...
- A*寻路算法入门(五)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
- 求解n皇后
要求:在国际象棋上摆放n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法 思路:很直观的想法就是在棋盘上一个一个皇后的摆,如果冲突,则摆放在另一个位置,直至 ...