实现去哪儿来回机票选择的view

简介: <p>最近有个控件是实现和去哪儿和阿里旅行的app的选择日历效果,反编译没有效果的情况下我自己实现了个,大致的原理是:</p> <p><img src="" alt=""><img src="" alt=""><br></p> <p>上面是产品需要实现的效果,我看了下不就是一个ListView+gridView就能实现么,方案有了,自定义的CalendarView实现对日期的计算,然后

最近有个控件是实现和去哪儿和阿里旅行的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.set(Calendar.DATE, 1);//cal设置当前day为当前月第一天
        int tempSum = countNeedHowMuchEmpety(cal);//获取当前月第一天为星期几
        int dayNumInMonth = getDayNumInMonth(cal);//获取当前月有多少天
        setGvListData(tempSum, dayNumInMonth, cal.get(Calendar.YEAR) + "-" + getMonth((cal.get(Calendar.MONTH) + 1)));

        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(theInDay.getMonth() + 1) + "月");
        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[1];
                if (!" ".equals(day)) {
                    if (Integer.parseInt(day) < 10) {
                        day = "0" + date[1];
                    }
                    choiceDay = date[0] + "-" + 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();
           for (int i = 0; i < tempSum; i++) {
               gvList.add(" , ");
           }
           for (int j = 1; j <= dayNumInMonth; j++) {
               gvList.add(YM + "," + String.valueOf(j));
           }
       }
    }

    private String getMonth(int month) {
        String mon = "";
        if (month < 10) {
            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) {
        int firstDayInWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
        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;
    long nd = 1000*24*60*60;//一天的毫秒数
    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);
        for(int i=0;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;
            if(dayxc>90){
                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("-")[2];
        if(Integer.parseInt(dateDay)<10){
            dateDay=date.split("-")[2].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();
        int nowMon=date.getMonth()+1;
        String yyyy= formatYear.format(date);
        String dd= formatDay.format(date);
        if(nowMon==9){
            list.add(simpleDateFormat.format(date));
            list.add(yyyy+"-10-"+dd);
            list.add(yyyy+"-11-"+dd);
            if(!dd.equals("01")){
                list.add(yyyy+"-12-"+dd);
            }
        }else if(nowMon==10){
            list.add(yyyy+"-10-"+dd);
            list.add(yyyy+"-11-"+dd);
            list.add(yyyy+"-12-"+dd);
            if(!dd.equals("01")){
                list.add((Integer.parseInt(yyyy)+1)+"-01-"+dd);
            }
        }else if(nowMon==11){
            list.add(yyyy+"-11-"+dd);
            list.add(yyyy+"-12-"+dd);
            list.add((Integer.parseInt(yyyy)+1)+"-01-"+dd);
            if(!dd.equals("01")){
                list.add((Integer.parseInt(yyyy)+1)+"-02-"+dd);
            }
        }else if(nowMon==12){
            list.add(yyyy+"-12-"+dd);
            list.add((Integer.parseInt(yyyy)+1)+"-01-"+dd);
            list.add((Integer.parseInt(yyyy)+1)+"-02-"+dd);
            if(!dd.equals("01")){
                list.add((Integer.parseInt(yyyy)+1)+"-03-"+dd);
            }
        }else{
            list.add(yyyy+"-"+getMon(nowMon)+"-"+dd);
            list.add(yyyy+"-"+getMon((nowMon+1))+"-"+dd);
            list.add(yyyy+"-"+getMon((nowMon+2))+"-"+dd);
            if(!dd.equals("01")){
                list.add(yyyy+"-"+getMon((nowMon+3))+"-"+dd);
            }
        }
        return list;
    }

    public String getMon(int mon){
        String month="";
        if(mon<10){
            month="0"+mon;
        }else{
            month=""+mon;
        }
        return month;
    }
}

最后贴上实现的效果

最后需要代码的请到下面的地址下载:http://download.csdn.net/detail/xiangzhihong8/9435606,有问题的可以留言



目录
相关文章
|
3月前
|
Java 关系型数据库 MySQL
基于servlet+jsp实现的电影院订票系统分前后台
基于servlet+jsp实现的电影院订票系统分前后台
|
5月前
|
存储
SwiftUI动画进阶,仿购票平台App行程目的地互换动效
SwiftUI动画进阶,仿购票平台App行程目的地互换动效
45 0
上下轮流滚动公告代码
上下轮流滚动公告代码
|
8月前
7-2 银行排队问题之单窗口“夹塞”版 (30分)
7-2 银行排队问题之单窗口“夹塞”版 (30分)
|
开发框架 小程序 前端开发
来接私活吧?玩转小程序开发之丝滑拆红包【附完整代码】
来接私活吧?玩转小程序开发之丝滑拆红包【附完整代码】
99 0
来接私活吧?玩转小程序开发之丝滑拆红包【附完整代码】
7-46 银行排队问题之单队列多窗口服务 (10 分)
7-46 银行排队问题之单队列多窗口服务 (10 分)
232 0
NewPagedFlowView电影票卡片式无限自动轮播图方法改进
新增网络图片数据源和本地图片数据源属性 直接传入url链接数组或uiimage对象数组
199 0
NewPagedFlowView电影票卡片式无限自动轮播图方法改进
|
Java Maven Android开发
手撸了个很容易实现京东购物车吸顶功能的Android库
手撸了个很容易实现京东购物车吸顶功能的Android库
手撸了个很容易实现京东购物车吸顶功能的Android库
|
小程序
我写小程序像菜虚鲲——3、你能17张牌把我秒杀,我当场把电脑屏幕吃掉(中)
本节来肝下「微信小程序中布局」相关姿势点。希望你学完本章后,可以:根据设计师给的设计稿,堆砌控件。
122 0
|
编解码 小程序 前端开发
我写小程序像菜虚鲲——3、你能17张牌把我秒杀,我当场把电脑屏幕吃掉(上)
本节来肝下「微信小程序中布局」相关姿势点。希望你学完本章后,可以:根据设计师给的设计稿,堆砌控件。
118 0