安卓Andriod使用入门(十八)【仿淘宝预订日历】

不妄求,则心安,不妄做,则身安。


MainActivity.java代码:

package siso.calendarselector;

import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

import siso.calendarselector.lib.CalendarSelectorActivity;

public class MainActivity extends Activity {
    private EditText orderEt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void jump(View v) {
        EditText et = (EditText) findViewById(R.id.et_input);
        orderEt = (EditText) findViewById(R.id.et_order);
        int days = Integer.valueOf(et.getText().toString());
        String order = orderEt.getText().toString();
        Intent i = new Intent(MainActivity.this, CalendarSelectorActivity.class);
        i.putExtra(CalendarSelectorActivity.DAYS_OF_SELECT, days);
        i.putExtra(CalendarSelectorActivity.ORDER_DAY, order);
        startActivityForResult(i, 1);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && resultCode == RESULT_OK) {
            String orderInfo = data.getStringExtra(CalendarSelectorActivity.ORDER_DAY);
            orderEt.setText(orderInfo);
            /* *****注意*****
            // 如需转换为Calendar
            // 正确转换方法(因为2月没有30天):
            String[] info = orderInfo.split("#");
            Calendar c = Calendar.getInstance();
            c.set(Integer.valueOf(info[0]), Integer.valueOf(info[1]) - 1, Integer.valueOf(info[2]));
            // 错误转换方法:
            c.set(Integer.valueOf(info[0]), Integer.valueOf(info[1]), Integer.valueOf(info[2]));
            c.add(Calendar.MONTH, -1);
            **/
        }
    }

}

CalendarAdapter.java代码:

package siso.calendarselector.lib;

import java.util.ArrayList;
import java.util.Calendar;

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import siso.calendarselector.R;


/**
 * @Description 日历表格适配器
 */
public class CalendarAdapter extends BaseAdapter {

    private ArrayList<Day> days;
    private LayoutInflater mInflater;
    private Calendar c;
    private Context context;
    private String orderDay;

    public CalendarAdapter(Context context, Calendar c, int passDays, String orderDay) {
        this.c = c;
        this.context = context;
        this.orderDay = orderDay;
        days = CalendarUtils.getDaysOfMonth(this.c, passDays, orderDay);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return days.size();
    }

    @Override
    public Day getItem(int arg0) {
        return days.get(arg0);
    }

    @Override
    public long getItemId(int arg0) {
        return 0;
    }

    @Override
    public View getView(int arg0, View arg1, ViewGroup arg2) {
        View v = arg1;
        ViewHolder holder = null;
        if (v == null) {
            v = mInflater.inflate(R.layout.calendar_item, arg2, false);
            holder = new ViewHolder();
            holder.tv = (TextView) v.findViewById(R.id.tv_calendar_item);
            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }
        Day d = getItem(arg0);
        switch (d.getType()) {
        case TODAY:
            setOrderThreeDayStyle(holder.tv, d.isOrdered(), context.getString(R.string.today));
            break;
        case TOMORROW:
            setOrderThreeDayStyle(holder.tv, d.isOrdered(), context.getString(R.string.tomorrow));
            break;
        case T_D_A_T:
            setOrderThreeDayStyle(holder.tv, d.isOrdered(), context.getString(R.string.t_d_a_t));
            break;
        case ENABLE:
            holder.tv.setText(d.isOrdered() ? d.getName() + context.getString(R.string.order_day) : d.getName());
            holder.tv.setEnabled(true);
            holder.tv.setTextColor(d.isOrdered() ? Color.WHITE : context.getResources().getColor(
                    R.color.calendar_enable_color));
            holder.tv.setBackgroundResource(d.isOrdered() ? R.drawable.calendar_order_item_bg
                    : R.drawable.normal_calendar_order_item_bg);
            holder.tv.setTextSize(d.isOrdered() ? context.getResources().getDimension(
                    R.dimen.calendar_item_order_day_size) : context.getResources().getDimension(
                    R.dimen.calendar_item_nonorder_day_size));
            break;
        case NOT_ENABLE:
            holder.tv.setText(d.getName());
            holder.tv.setEnabled(false);
            holder.tv.setTextColor(context.getResources().getColor(R.color.calendar_disable_color));
            holder.tv.setBackgroundColor(Color.WHITE);
            holder.tv.setTextSize(context.getResources().getDimension(R.dimen.calendar_item_nonorder_day_size));
            break;
        }

        return v;
    }

    private void setOrderThreeDayStyle(TextView tv, boolean ordered, String dayStr) {
        tv.setText(ordered ? dayStr + context.getString(R.string.order_day) : dayStr);
        tv.setEnabled(true);
        tv.setTextColor(ordered ? Color.WHITE : context.getResources().getColor(R.color.calendar_threeday_color));
        tv.setBackgroundResource(ordered ? R.drawable.calendar_order_item_bg : R.drawable.normal_calendar_order_item_bg);
        tv.setTextSize(ordered ? context.getResources().getDimension(R.dimen.calendar_item_order_day_size) : context
                .getResources().getDimension(R.dimen.calendar_item_nonorder_day_size));
    }

    static class ViewHolder {
        TextView tv;
    }

    public void previous() {
        if (c.get(Calendar.MONTH) == c.getActualMinimum(Calendar.MONTH)) {
            c.set((c.get(Calendar.YEAR) - 1), c.getActualMaximum(Calendar.MONTH), 1);
        } else {
            c.set(Calendar.MONTH, c.get(Calendar.MONTH) - 1);
        }
        days = CalendarUtils.getDaysOfMonth(c, 0, orderDay);
        notifyDataSetChanged();
    }

    public void next() {
        if (c.get(Calendar.MONTH) == c.getActualMaximum(Calendar.MONTH)) {
            c.set((c.get(Calendar.YEAR) + 1), c.getActualMinimum(Calendar.MONTH), 1);
        } else {
            c.set(Calendar.MONTH, c.get(Calendar.MONTH) + 1);
        }
        days = CalendarUtils.getDaysOfMonth(c, 0, orderDay);
        notifyDataSetChanged();
    }

}

CalendarListAdapter.java代码:

package siso.calendarselector.lib;

import java.util.Calendar;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.TextView;

import siso.calendarselector.R;


/**
 * @Description 日历列表适配器
 */
public class CalendarListAdapter extends BaseAdapter {

    private Context context;
    private LayoutInflater mInflater;
    private int daysOfSelect;
    private String orderDay;
    private OnCalendarOrderListener listener;

    public CalendarListAdapter(Context context, int daysOfSelect, String orderDay) {
        this.context = context;
        this.daysOfSelect = daysOfSelect;
        this.orderDay = orderDay;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return CalendarUtils.throughMonth(Calendar.getInstance(), daysOfSelect) + 1;
    }

    @Override
    public Object getItem(int arg0) {
        return null;
    }

    @Override
    public long getItemId(int arg0) {
        return 0;
    }

    @Override
    public View getView(int arg0, View arg1, ViewGroup arg2) {
        View v = arg1;
        ViewHolder holder = null;
        if (v == null) {
            v = mInflater.inflate(R.layout.calendar, arg2, false);
            holder = new ViewHolder();
            holder.yearAndMonth = (TextView) v.findViewById(R.id.tv_year_month);
            holder.calendarGrid = (NoScrollGridView) v.findViewById(R.id.gv_calendar_layout);
            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }
        final Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, arg0);
        holder.yearAndMonth.setText(c.get(Calendar.YEAR) + context.getString(R.string.year)
                + (c.get(Calendar.MONTH) + 1) + context.getString(R.string.month));

        CalendarAdapter cAdapter = null;
        if (arg0 == 0) {
            cAdapter = new CalendarAdapter(context, c, daysOfSelect, orderDay);
        } else {
            int d = daysOfSelect - CalendarUtils.currentMonthRemainDays() - CalendarUtils.getFlowMonthDays(arg0 - 1);
            cAdapter = new CalendarAdapter(context, c, d, orderDay);
        }
        holder.calendarGrid.setAdapter(cAdapter);

        holder.calendarGrid.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Calendar cl = (Calendar) c.clone();
                cl.set(Calendar.DAY_OF_MONTH, 1);
                int day = position + 2 - cl.get(Calendar.DAY_OF_WEEK);
                TextView dayTv = (TextView) view.findViewById(R.id.tv_calendar_item);
                if (day <= 0 || !dayTv.isEnabled())
                    return;
                String orderInfo = c.get(Calendar.YEAR) + "#" + (c.get(Calendar.MONTH) + 1) + "#" + day;
                cl.clear();
                cl = null;
                if (listener != null)
                    listener.onOrder(orderInfo);
            }
        });

        return v;
    }

    static class ViewHolder {
        TextView yearAndMonth;
        NoScrollGridView calendarGrid;
    }

    public void setOnCalendarOrderListener(OnCalendarOrderListener listener) {
        this.listener = listener;
    }

    public interface OnCalendarOrderListener {
        void onOrder(String orderInfo);
    }

}

CalendarSelectorActivity.java代码:

package siso.calendarselector.lib;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;

import siso.calendarselector.R;


/**
 * @Description 预订日选择
 */
public class CalendarSelectorActivity extends Activity {

    /**
     * 可选天数
     */
    public static final String DAYS_OF_SELECT = "days_of_select";
    /**
     * 上次预订日
     */
    public static final String ORDER_DAY = "order_day";

    private int daysOfSelect;
    private String orderDay;

    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.calendar_selector);
        daysOfSelect = getIntent().getIntExtra(DAYS_OF_SELECT, 30);
        orderDay = getIntent().getStringExtra(ORDER_DAY);
        listView = (ListView) findViewById(R.id.lv_calendar);

        CalendarListAdapter adapter = new CalendarListAdapter(this, daysOfSelect, orderDay);
        listView.setAdapter(adapter);

        adapter.setOnCalendarOrderListener(new CalendarListAdapter.OnCalendarOrderListener() {

            @Override
            public void onOrder(String orderInfo) {
                Intent result = new Intent();
                result.putExtra(ORDER_DAY, orderInfo);
                setResult(RESULT_OK, result);
                finish();
            }
        });
    }
}

CalendarUtils.java代码:

package siso.calendarselector.lib;

import java.util.ArrayList;
import java.util.Calendar;



public class CalendarUtils {

    private static int dayOfMonth, monthOfYear, curYear;

    static {
        dayOfMonth = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
        monthOfYear = Calendar.getInstance().get(Calendar.MONTH);
        curYear = Calendar.getInstance().get(Calendar.YEAR);
    }

    /**
     * Gets the days in month.
     *
     * @param month the month
     * @param year the year
     * @return the days in month
     */
    public static int getDaysInMonth(int month, int year) {
        switch (month) {
        case Calendar.JANUARY:
        case Calendar.MARCH:
        case Calendar.MAY:
        case Calendar.JULY:
        case Calendar.AUGUST:
        case Calendar.OCTOBER:
        case Calendar.DECEMBER:
            return 31;
        case Calendar.APRIL:
        case Calendar.JUNE:
        case Calendar.SEPTEMBER:
        case Calendar.NOVEMBER:
            return 30;
        case Calendar.FEBRUARY:
            return (year % 4 == 0) ? 29 : 28;
        default:
            throw new IllegalArgumentException("Invalid Month");
        }
    }

    /**
     * Gets the flow month days.
     *
     * @param flowMonth the flow month
     * @return the flow month days
     */
    public static int getFlowMonthDays(int flowMonth) {
        int totalDays = 0;
        for (int i = 0; i < flowMonth; i++) {
            Calendar c = Calendar.getInstance();
            c.add(Calendar.MONTH, i + 1);
            int days = getDaysInMonth(c.get(Calendar.MONTH), c.get(Calendar.YEAR));
            totalDays += days;
        }
        return totalDays;
    }

    /**
     * Current month remain days.
     *
     * @return the int
     */
    public static int currentMonthRemainDays() {
        Calendar c = Calendar.getInstance();
        return getDaysInMonth(c.get(Calendar.MONTH), c.get(Calendar.YEAR)) - c.get(Calendar.DAY_OF_MONTH) + 1;
    }

    /**
     * Through month.
     *
     * @param calendar the calendar
     * @param passDays the pass days
     * @return the int
     */
    public static int throughMonth(Calendar calendar, int passDays) {
        Calendar c = (Calendar) calendar.clone();
        int curMonth = c.get(Calendar.MONTH);
        int curYear = c.get(Calendar.YEAR);
        c.add(Calendar.DAY_OF_MONTH, passDays - 1);
        int monthCount = (c.get(Calendar.YEAR) - curYear) * 12 + (c.get(Calendar.MONTH) - curMonth);
        return monthCount;
    }

    /**
     * Gets the days of month.
     *
     * @param calendar the calendar
     * @return the days of month
     */
    public static String[] getDaysOfMonth(Calendar calendar) {
        Calendar month = (Calendar) calendar.clone();
        String[] days;
        final int FIRST_DAY_OF_WEEK = 0; // Sunday = 0, Monday = 1
        month.set(Calendar.DAY_OF_MONTH, 1);
        int lastDay = month.getActualMaximum(Calendar.DAY_OF_MONTH);
        int firstDay = (int) month.get(Calendar.DAY_OF_WEEK);

        if (firstDay == 1) {
            days = new String[lastDay + (FIRST_DAY_OF_WEEK * 6)];
        } else {
            days = new String[lastDay + firstDay - (FIRST_DAY_OF_WEEK + 1)];
        }

        int j = FIRST_DAY_OF_WEEK;

        if (firstDay > 1) {
            for (j = 0; j < firstDay - FIRST_DAY_OF_WEEK; j++) {
                days[j] = "";
            }
        } else {
            for (j = 0; j < FIRST_DAY_OF_WEEK * 6; j++) {
                days[j] = "";
            }
            j = FIRST_DAY_OF_WEEK * 6 + 1; // sunday => 1, monday => 7
        }

        int dayNumber = 1;
        for (int i = j - 1; i < days.length; i++) {
            days[i] = "" + dayNumber;
            dayNumber++;
        }
        return days;
    }

    /**
     * Gets the days of month.
     *
     * @param calendar the calendar
     * @param passDays the pass days
     * @param orderDay the order day
     * @return the days of month
     */
    public static ArrayList<Day> getDaysOfMonth(Calendar calendar, int passDays, String orderDay) {
        String[] orderInfo = null;
        boolean isOrdered = false;
        if (orderDay != null)
            orderInfo = orderDay.split("#");
        Calendar month = (Calendar) calendar.clone();
        final int FIRST_DAY_OF_WEEK = 0; // Sunday = 0, Monday = 1
        month.set(Calendar.DAY_OF_MONTH, 1);
        int lastDay = month.getActualMaximum(Calendar.DAY_OF_MONTH);
        int firstDay = (int) month.get(Calendar.DAY_OF_WEEK);

        ArrayList<Day> days = new ArrayList<Day>();
        int size;
        if (firstDay == 1) {
            size = lastDay + (FIRST_DAY_OF_WEEK * 6);
        } else {
            size = lastDay + firstDay - (FIRST_DAY_OF_WEEK + 1);
        }

        for (int i = 0; i < size; i++) {
            days.add(new Day("", Day.DayType.NOT_ENABLE, isOrdered));
        }

        int j = FIRST_DAY_OF_WEEK;

        if (firstDay > 1) {
            for (j = 0; j < firstDay - FIRST_DAY_OF_WEEK; j++) {
                days.set(j, new Day("", Day.DayType.NOT_ENABLE, isOrdered));
            }
        } else {
            for (j = 0; j < FIRST_DAY_OF_WEEK * 6; j++) {
                days.set(j, new Day("", Day.DayType.NOT_ENABLE, isOrdered));
            }
            j = FIRST_DAY_OF_WEEK * 6 + 1; // sunday => 1, monday => 7
        }

        int dayNumber = 1;

        for (int i = j - 1; i < days.size(); i++) {
            Day.DayType type;
            if (month.get(Calendar.YEAR) == curYear && month.get(Calendar.MONTH) == monthOfYear) {
                if (dayNumber >= dayOfMonth && dayNumber < dayOfMonth + passDays) {
                    type = Day.DayType.ENABLE;
                    if (dayNumber == dayOfMonth) {
                        type = Day.DayType.TODAY;
                        if (orderDay == null) {
                            isOrdered = true;
                        } else {
                            isOrdered = false;
                        }
                    } else if (dayNumber == dayOfMonth + 1) {
                        type = Day.DayType.TOMORROW;
                    } else if (dayNumber == dayOfMonth + 2) {
                        type = Day.DayType.T_D_A_T;
                    }
                } else {
                    type = Day.DayType.NOT_ENABLE;
                }
            } else {
                if (dayNumber <= passDays) {
                    type = Day.DayType.ENABLE;
                    // 明天/后天在下个月
                    int remainDays = getDaysInMonth(monthOfYear, curYear) - dayOfMonth;
                    if (remainDays < 2 && dayNumber <= 2 && Math.abs(month.get(Calendar.MONTH) - monthOfYear) == 1
                            && month.get(Calendar.YEAR) == curYear) {
                        if (remainDays == 1) {
                            if (dayNumber == 1) {
                                type = Day.DayType.T_D_A_T;
                            }
                        } else if (remainDays == 0) {
                            if (dayNumber == 1) {
                                type = Day.DayType.TOMORROW;
                            } else if (dayNumber == 2) {
                                type = Day.DayType.T_D_A_T;
                            }
                        }
                    }
                } else {
                    type = Day.DayType.NOT_ENABLE;
                }
            }
            if (orderInfo != null && orderInfo.length == 3 && Integer.valueOf(orderInfo[0]) == month.get(Calendar.YEAR)
                    && Integer.valueOf(orderInfo[1]) == (month.get(Calendar.MONTH) + 1)
                    && Integer.valueOf(orderInfo[2]) == dayNumber) {
                isOrdered = true;
            } else {
                isOrdered = false;
            }

            days.set(i, new Day("" + dayNumber, type, isOrdered));
            dayNumber++;
        }
        return days;
    }
}

Day.java代码:

package siso.calendarselector.lib;

public class Day {

public Day(String name, DayType type, boolean isOrdered) {
    setName(name);
    setType(type);
    setOrdered(isOrdered);
}

public enum DayType {
    TODAY, TOMORROW, T_D_A_T, ENABLE, NOT_ENABLE
}

private String name;
private DayType type;
private boolean isOrdered;

public boolean isOrdered() {
    return isOrdered;
}

public void setOrdered(boolean isOrdered) {
    this.isOrdered = isOrdered;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public DayType getType() {
    return type;
}

public void setType(DayType type) {
    this.type = type;
}

}

NoScrollGridView.java代码:

package siso.calendarselector.lib;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;

public class NoScrollGridView extends GridView {

    public NoScrollGridView(Context context) {
        super(context);

    }

    public NoScrollGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }

}

AndroidManifest.xml内容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ndroid="http://schemas.android.com/apk/res-auto"
    package="siso.calendarselector">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        ndroid:theme="@android:style/Theme.Black.NoTitleBar">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="siso.calendarselector.lib.CalendarSelectorActivity">

        </activity>
    </application>

</manifest>

项目结构如图:

这里写图片描述


项目运行结果如图:

这里写图片描述


这里写图片描述


这里写图片描述

保存并恢复选定的日历组 注意:仅适用于新的基于Material的Google日历用户界面! CHANGELOG:版本0.1.3-错误修复:保存预设可以再次正常工作版本0.1.2-错误修复:用于打开侧抽屉的次要修复版本0.1.1-增强功能:切换为使用日历ID代替名称(以便多个)具有相同名称的日历在保存到预设中时可以正常工作)-增强功能:如果隐藏了屏幕左侧的日历抽屉,它将自动显示以更改日历并再次隐藏 0.0.14版-错误修复:范围内CSS,以免干扰Google Calendar UI;三个点按钮和临时会议接受现在可以正确显示版本0.0.13-增强功能:保存以同步/存储时仅保留最后3个自动保存的日历视图版本0.0.12-错误修复:支持没有“其他日历日历日历列表0.0.11版-删除了对HTML英文版名称的依赖性,该依赖性不适用于国际用户 0.0.10版-添加了ctrl + alt-t快捷键来切换日历选择(如“启用”,而是切换)。尚无UI按钮 0.0.9版-修复了问题1-扫描现在即使在非整数元素尺寸的情况下也可以正常工作-修复了问题2-页面加载后“加载”和“另存为”工作无需清除或启用任何日历 0.0.8版-预设搜索现在可以从预设名称的开头开始匹配,而不仅仅是在预设名称中的任何位置。0.0.7版-在所有功能中,除其他日历外,还包括我的日历-将“用户”按钮重命名为“启用”说明:此扩展程序在Google Chrome浏览器用户界面中创建了一组按钮,可让您轻松创建,保存和显示日历预设组。如果您有很多日历,并且经常需要在显示的日历之间进行切换(例如同事和团队),那么此扩展名适合您。您的预设存储在本地浏览器存储中,并自动跨设备同步(使用Chrome的内置同步机制)。键盘快捷键:按Ctrl + Alt键,然后按一下突出显示的主要功能键(突出显示的键是e,s,r,c,i,x或p之一)。由Bluenexa团队构建。 支持语言:English (United States)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值