自定义日历,随心所欲的打造自己的日历选择器
来源:互联网 发布:固结快剪试验数据 编辑:程序博客网 时间:2024/05/29 06:44
不多说,先上图,第一次录屏,剪切的有点烂,将就看
正文开始
1.先看布局图
我们可以清晰的看到视图的结构 1.头部两个TextView,左边是日期,右边是星期 2.下方三个ListView ,每个ListView中间有个选择指示的圆下面是xml的布局代码 , 不想看代码的可以略过
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:background="@color/black" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_margin="30dp" android:background="@drawable/shape_all_round" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_marginTop="15dp" android:layout_gravity="center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/show_title_year_month_day" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/show_title_week" android:layout_marginLeft="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="200dp"> <RelativeLayout android:layout_margin="10dp" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent"> <ListView android:id="@+id/list_view_year" android:divider="@null" android:scrollbars="none" android:listSelector="@color/color_null" android:layout_width="match_parent" android:layout_height="match_parent"/> <TextView android:background="@drawable/shap_calendar_list_btm_plastic" android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageView app:srcCompat="@drawable/ic_round" android:layout_centerInParent="true" android:layout_width="80dp" android:layout_height="80dp" /> </RelativeLayout> <RelativeLayout android:layout_margin="10dp" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent"> <ListView android:id="@+id/list_view_month" android:divider="@null" android:scrollbars="none" android:listSelector="@color/color_null" android:layout_width="match_parent" android:layout_height="match_parent"/> <TextView android:background="@drawable/shap_calendar_list_btm_plastic" android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageView app:srcCompat="@drawable/ic_round" android:layout_centerInParent="true" android:layout_width="80dp" android:layout_height="80dp" /> </RelativeLayout> <RelativeLayout android:layout_margin="10dp" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent"> <ListView android:id="@+id/list_view_day" android:divider="@null" android:scrollbars="none" android:listSelector="@color/color_null" android:layout_width="match_parent" android:layout_height="match_parent"/> <TextView android:background="@drawable/shap_calendar_list_btm_plastic" android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageView app:srcCompat="@drawable/ic_round" android:layout_centerInParent="true" android:layout_width="80dp" android:layout_height="80dp" /> </RelativeLayout> </LinearLayout> </LinearLayout></LinearLayout>
上面的圆形图片用的是svg格式的矢量图,不会用svg的小伙伴,可以将图片替换为png的图片,把app:srcCompat 改成 android:src就行了
shap_calendar_list_btm_plastic.xml 这就是做一个毛玻璃的效果,从上下开始到中间,透明度逐渐变高,就能显示出类似滚轮的效果来,下面贴出代码,顺便把color的代码一起贴出来
布局文件的背景
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/white"/> <corners android:radius="15dp"/></shape>
这是shap_calendar_list_btm_plastic.xml的
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <gradient android:angle="90" android:startColor="@color/white_btm_f" android:centerColor="@color/white_btm_0" android:endColor="@color/white_btm_f"/></shape>
这是color的
<color name="white_btm_0">#00ffffff</color> <color name="white_btm_1">#11ffffff</color> <color name="white_btm_2">#22ffffff</color> <color name="white_btm_3">#33ffffff</color> <color name="white_btm_4">#44ffffff</color> <color name="white_btm_5">#55ffffff</color> <color name="white_btm_6">#66ffffff</color> <color name="white_btm_7">#77ffffff</color> <color name="white_btm_8">#88ffffff</color> <color name="white_btm_9">#99ffffff</color> <color name="white_btm_a">#aaffffff</color> <color name="white_btm_b">#bbffffff</color> <color name="white_btm_c">#ccffffff</color> <color name="white_btm_d">#ddffffff</color> <color name="white_btm_e">#eeffffff</color> <color name="white_btm_f">#ffffffff</color>
2.java代码部分
适配器
/** * 适配器 * Created by zcy on 2017/8/2. */public class CalendarListAdapter extends BaseAdapter { private Context mContext; private List<Integer> list; //listView中显示的item个数 private int count; //最小个数,如果count比这个值小,将会默认使用MIN_COUNT private static final int MIN_COUNT = 3; public static final int TYPE_YEAR = 10;//年 public static final int TYPE_MONTH = 11;//月 public static final int TYPE_DAY = 12;//日 private int type; public CalendarListAdapter(Context mContext, List<Integer> list , int count , int type) { this.mContext = mContext; this.list = list; this.count = count; this.type = type; } public CalendarListAdapter(Context mContext) { this.mContext = mContext; } @Override public int getCount() { return null == list ? 0 : list.size(); } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { int height = viewGroup.getHeight(); TextView textView = new TextView(mContext); textView.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); textView.setHeight(count < MIN_COUNT ? height/MIN_COUNT : height/count); textView.setGravity(Gravity.CENTER); textView.setText(list.get(i) < 0 ? "" :new StringBuilder().append(list.get(i)).append(getTypeName())); return textView; } private String getTypeName(){ String name = null; switch (type){ case TYPE_YEAR: name = "年"; break; case TYPE_MONTH: name = "月"; break; case TYPE_DAY: name = "日"; break; default: name = ""; break; } return name; }}
实现代码
/** * 日历fragment * Created by zcy on 2017/8/2. */public class CalendarFragment extends BaseFragment { public static CalendarFragment getInstance(){ return new CalendarFragment(); } // 年月日 , 星期几 @BindView(R.id.show_title_year_month_day) TextView titleYMD; @BindView(R.id.show_title_week) TextView titleNeek; //年份选择 , 月份选择 ,天数选择 @BindView(R.id.list_view_year) ListView listViewYear; @BindView(R.id.list_view_month) ListView listViewMonth; @BindView(R.id.list_view_day) ListView listViewDay; //年份listView中显示的第一个item编号 private int firstVisibleYearItem; //月份listView中显示的第一个item编号 private int firstVisibleMonthItem; //天数listView中显示的第一个item编号 private int firstVisibleDayItem; private List<Integer> listYear; private List<Integer> listMonth; private List<Integer> listDay; //初始年份和结束年份 private int firstYear; private int lastYear; //年月日的适配器 private CalendarListAdapter yearAdapter; private CalendarListAdapter monthAdapter; private CalendarListAdapter daydApter; //日历对象 private Calendar calendar; //当前时间,年,月,日,周 private int currentTimeYear; private int currentTimeMonth; private int currentTimeDay; @Override protected int getLayoutId() { return R.layout.fragment_calendar; } @Override protected void initViews() { initYearListView(); initMonthListView(); initDayListView(); listViewYear.setSelection(listYear.indexOf(currentTimeYear)-1); listViewMonth.setSelection(listMonth.indexOf(currentTimeMonth)-1); listViewDay.setSelection(listDay.indexOf(currentTimeDay)-1); upData(false); } @Override protected void init() { initYear(); initMonth(); calendar = Calendar.getInstance(); currentTimeYear = calendar.get(Calendar.YEAR); currentTimeMonth = calendar.get(Calendar.MONTH)+1; currentTimeDay = calendar.get(Calendar.DAY_OF_MONTH); upData(false); } //初始化天数的listView private void initDayListView() { daydApter = new CalendarListAdapter(getContext() , listDay , 0 , CalendarListAdapter.TYPE_DAY); listViewDay.setAdapter(daydApter); listViewDay.setSelected(true); listViewDay.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView absListView, int i) { if (i == SCROLL_STATE_IDLE){ listViewDay.setSelection(firstVisibleDayItem); calendar.set(Calendar.DAY_OF_MONTH ,listDay.get(firstVisibleDayItem+1)); upData(false); } } @Override public void onScroll(AbsListView absListView, int i, int i1, int i2) { firstVisibleDayItem = i; } }); } //初始化月份的listView private void initMonthListView() { monthAdapter = new CalendarListAdapter(getContext() , listMonth , 0 , CalendarListAdapter.TYPE_MONTH); listViewMonth.setAdapter(monthAdapter); listViewMonth.setSelected(true); listViewMonth.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView absListView, int i) { if (i == SCROLL_STATE_IDLE){ listViewMonth.setSelection(firstVisibleMonthItem);// upDayList(); calendar.set(Calendar.DAY_OF_MONTH , 1); calendar.set(Calendar.MONTH , listMonth.get(firstVisibleMonthItem+1)-1); upData(true); } } @Override public void onScroll(AbsListView absListView, int i, int i1, int i2) { firstVisibleMonthItem = i; } }); } //初始化年份的listView private void initYearListView() { yearAdapter = new CalendarListAdapter(getContext() , listYear , 0 , CalendarListAdapter.TYPE_YEAR); listViewYear.setAdapter(yearAdapter); listViewYear.setSelected(true); listViewYear.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView absListView, int i) { if (i == SCROLL_STATE_IDLE){ listViewYear.setSelection(firstVisibleYearItem);// upDayList(); calendar.set(Calendar.DAY_OF_MONTH , 1); calendar.set(Calendar.YEAR , listYear.get(firstVisibleYearItem + 1)); upData(true); } } @Override public void onScroll(AbsListView absListView, int i, int i1, int i2) { //此处i代表屏幕中显示的第一个item firstVisibleYearItem = i; } }); } /** * 有任何动作之后刷新数据和界面 * @param isNotify 是否对天数的适配器进行刷新 */ private void upData(boolean isNotify){ initDay(); if (isNotify && null != daydApter){ daydApter.notifyDataSetChanged(); //这里须要在刷新之后将selection设置为0,否则在31号的时候调整月份,会出现显示异常的情况 listViewDay.setSelection(0); } if (null != calendar){ if (null != titleYMD)titleYMD.setText(getYMD()); if (null != titleNeek)titleNeek.setText(getNeek()); } } //从Calendar中取出年月日并拼接成想要的格式 private String getYMD(){ int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int day = calendar.get(Calendar.DAY_OF_MONTH); StringBuilder sb = new StringBuilder(); if (year >= 1900){ sb.append(year).append("年"); if (month >= 0 && month <12){ sb.append(month+1).append("月") .append(day); } } return sb.toString(); } //从Calendar中取出星期数,并返回对应的名称 private String getNeek(){ int dayOfNeek = calendar.get(Calendar.DAY_OF_WEEK); String neek = null; switch (dayOfNeek){ case 1: neek = "星期日"; break; case 2: neek = "星期一"; break; case 3: neek = "星期二"; break; case 4: neek = "星期三"; break; case 5: neek = "星期四"; break; case 6: neek = "星期五"; break; case 7: neek = "星期六"; break; default: neek = ""; break; } return neek; } //初始化天数list数据 private void initDay(){ //指定年份指定月份有多少天 int actualMaximum = calendar.getActualMaximum(Calendar.DATE); if (null == listDay)listDay = new ArrayList<>(); else listDay.clear(); listDay.add(-1); for (int i = 1 ; i <= actualMaximum ; i++){ listDay.add(i); } listDay.add(-1); } //初始化年份相关 private void initYear() { firstYear = 2000; lastYear = 2017; if (null == listYear) listYear = new ArrayList<>(); else listYear.clear(); listYear.add(-1); for (int i = firstYear ; i <= lastYear ; i++){ listYear.add(i); } listYear.add(-1); } //初始化月份 private void initMonth(){ if (null == listMonth) listMonth = new ArrayList<>(); else listMonth.clear(); listMonth.add(-1); for (int i = 0 ; i < 12 ; i++){ listMonth.add(i+1); } listMonth.add(-1); }}
这里我将逻辑全写在Fragment里面了,哪里需要用的时候,直接加载这个fragment就行了,还有个BaseFragment,也贴个代码吧
/** * baseFragment * Created by zcy on 2017/8/2. */public abstract class BaseFragment extends Fragment{ /** * 这个方法提供初始化的布局id * @return 布局id */ protected abstract int getLayoutId(); @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(getLayoutId(),container,false); ButterKnife.bind(this,view); initViews(); return view; } /** * 初始化视图控件,代替了onCreateView,不需要再重写onCreateView在该方法里面写具体实现就可以了 */ protected abstract void initViews(); /** * 初始化成员属性,不需要手动调用,只需要重写内容即可 */ protected abstract void init(); @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); init(); }}
有点乱,也不是很复杂,需要用到的可以自己整理一下;基本全局就对一个Calendar对象操作,然后在合适的地方刷新页面就行了;还有疑问的小伙伴可以私信我
阅读全文
0 0
- 自定义日历,随心所欲的打造自己的日历选择器
- 自定义的日历选择器CalendarView
- Calendar日历选择器的使用方法
- 不错的JS日历选择器
- 简单的日历选择器 LDCalendarView
- 25.VRGCalendar一款支持标记自定义日期的日历选择器
- 自定义日历控件,可以根据需求定制属于自己的日历
- 自己用的日历控件
- 安卓自定义日历选择器
- 安卓自定义日历选择器
- flex日历控件的自定义
- android自定义日历的使用方法
- 自定义的一个日历Calender
- android 好看的自定义日历
- iOS 自定义日历的实现
- 纯javascript的一个日历选择器
- jquery - 日历插件(自定义模板的日历插件)
- 安卓自定义日历滑动的日历控件
- 定时器 Timer
- MYSQL mysql_real_escape_string和addslashe区别
- ViewPager上加载Fragment
- JVM调优:选择合适的GC collector (二)
- memcahced介绍
- 自定义日历,随心所欲的打造自己的日历选择器
- 001-20161115-1光明解答读者无限关于“邪恶的生命生存与提升”的问题
- HTTP协议实现文件下载
- easyui select 动态添加 option
- W3C盒模型与IE盒模型
- Java邮件开发(一):使用JMail发送一封简单邮件
- 使用GET,POST请求获取结果
- appium工作原理
- easyui和zTree分别实现树型下拉框