有关Android-times-square的日期控件之前写过一篇文章,请参考我的博文Android日期控件,需求和详细设计都在这篇博文里。
今天主要说说自定义样式的问题。我虽然不是美工或者前端设计师,自认为审美还是没问题的,但是这个日期控件就被诸多吐槽,首先它的样式跟设计图就不一样,这可能也是每个小伙伴都会遇到的问题。所以读了一下它的源码,之所以是“一下”,还是因为那句话:时间紧任务重。不过今天要说的应该能撼动整体的样式,满足我们一般水平的需求。
本来上周就已经成型了,无奈要参加BEC考试耽搁了,还让一个留言的小伙伴的问题没有及时被解答,实在是抱歉了。
主要目的是达到设计图中的几点要求:
1.今天的日期右上角显示今字,用户选择的机票或者酒店的时间段中的开始和结束时间下面要显示文字:去程和返程或者入住和离店;
2.控件本身自带的每一天日期的网格样式去掉换成现在的横线;
3.去掉每月上面的星期,只在最上方显示“日、一、二”等;
4.控件中的每个月会有下一个月的日期占位,这些要去掉;
5.每个月可选的日期数字要黑色加粗显示;(字体的改变也会进行)
这五点满足后,样式能够大大改观,也确实是能够比控件本身的样式好看,至少在这一点上我和前端设计美工达成了共识;
OK,下一步就是修改了,网上这样的有关Android-times-square自定义样式如何修改,还是缺少系统的文章指导,因此在这里我按照我的实践去建设一篇这样的文章供大家参考。
首先如果要修改样式我们应该了解一下Android-times-square的底层实现结构,Android-times-square是基于ListView实现的,然后每一个日期是一个CalendarCellView,我们可以在这里做文章,控件本身提供了一个CalendarCellDecorator,让开发者可以实现这个接口,我们主要的工作也是基于这个实现来做。
下面上代码:
第一,需要升级我们的插件,否则Decorator有些方法写法已经不同了,我们用最新的;
compile 'com.squareup:android-times-square:1.6.5@aar'
第二,写Decorator:
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import com.squareup.timessquare.CalendarCellDecorator;
import com.squareup.timessquare.CalendarCellView;
import java.util.Date;
/**
* 修改日期控件背景效果
* Created by shikeyue on 17/5/25.
*/
public class DatePickerDecorator implements CalendarCellDecorator{
private Context context;
//加入这个typeMark,是因为我的需求是如果涉及到酒店的预订就需要在日期范围选择的时候开始和结束时间显示
//“入住和离店“,而对于预订机票的时候又需要显示“去程和返程“的个性化需求。
private String typeMark;
public DatePickerDecorator(Context context, String typeMark) {
this.context = context;
this.typeMark = typeMark;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void decorate(CalendarCellView cellView, Date date) {
//我用了一个讨巧的方法,可能略显笨拙。
//利用更换背景的方式免于具体操作单个日期块的样式,因为每天的日期块修改的话会同时修改,利用更换背景加上
//判断返回的tag字符串标识可以暂时绕过这个不好处理的每个日期块都会影响的问题。
Drawable beginDraw = context.getResources().getDrawable(R.mipmap.icon_go_img,null);
Drawable endDraw = context.getResources().getDrawable(R.mipmap.icon_back_img,null);
Drawable middleDraw = context.getResources().getDrawable(R.mipmap.icon_middle,null);
Drawable combineDraw = context.getResources().getDrawable(R.mipmap.icon_air_combine,null);
Drawable todayDraw = context.getResources().getDrawable(R.mipmap.icon_today_img,null);
Drawable blankDraw = context.getResources().getDrawable(R.mipmap.icon_blank_hb,null);
if ("hotel".equals(typeMark)) {
//酒店
beginDraw = context.getResources().getDrawable(R.mipmap.icon_hotel_go,null);
endDraw = context.getResources().getDrawable(R.mipmap.icon_hotel_back,null);
combineDraw = context.getResources().getDrawable(R.mipmap.icon_hotel_combine,null);
}
/**
* 可以设置字体,参见官方的例子Decorator的代码
*/
// String dateString = Integer.toString(date.getDate());
// SpannableString string = new SpannableString(dateString + "\ntitle");
// string.setSpan(new RelativeSizeSpan(0.5f), 0, dateString.length(),
// Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
// cellView.getDayOfMonthTextView().setText(string);
if (cellView.isSelectable()) { //先通过是否可选方法来区分时间,如果可选则再判断是否已选
if (cellView.isSelected()) {//再通过是否已选来设置日期的背景图片
String json = String.valueOf(cellView.getTag());
//这里就是单纯的截取tag字符串进行判断了,暂时没找到能够转换成属性对象或者直接设置的方式,
//它是内部的不可访问的类的属性
String tagLocation = json.substring(json.indexOf("rangeState") + 11, json.length() - 1);
//处理选中日期的样式
if ("FIRST".equals(tagLocation)) {
cellView.setBackground(beginDraw);
} else if ("LAST".equals(tagLocation)){
cellView.setBackground(endDraw);
} else if ("NONE".equals(tagLocation)){
cellView.setBackground(beginDraw);
} else if ("MIDDLE".equals(tagLocation)) {
cellView.setBackground(middleDraw);
}
if (cellView.isToday()) {
Log.d("DateDecorator5", String.valueOf(cellView.getTag()));
cellView.setBackground(combineDraw);
}
} else {
if (cellView.isToday()) {
cellView.setBackground(todayDraw);
} else {
cellView.setBackground(blankDraw);
}
}
}else {//如果为不可选时间则直接设置日期背景
String json = String.valueOf(cellView.getTag());
String currentMonthBoolean = json.substring(json.indexOf("isCurrentMonth") + 15, json.indexOf("isCurrentMonth") + 20);
if ("false".equals(currentMonthBoolean)) {
cellView.getDayOfMonthTextView().setText("");
cellView.setBackground(blankDraw);
}
}
}
}
第三,调用:
DatePickerDecorator decorator = new DatePickerDecorator(getActivity(), getTypeMark());
List<CalendarCellDecorator> d = new ArrayList<>();
d.add(decorator);
calendarPickerView.setDecorators(d);
调用是很简单的代码。
OK,就到这里,如果有问题大家可以给我留言,我会继续跟进这个插件的个性化处理。