android菜鸟练手小项目之自定义日历,涵盖LitePal数据库,极光推送(一)
2017-05-07 09:44
573 查看
心血来潮想开发个小玩意练练手,于是就有了上面标题的创意,自己一直想用下郭霖大神的开源数据库项目LitePal,再加之想要每天进行推送,于是跟日历结合起来有了下面的构想,项目简单点,对于我这个菜鸟而言就不会半途而废
,希望能够顺利写完。打算用三个篇幅来写,分别是
1。自定义日历控件部分(一),
2。极光推送集成以及富媒体消息推送部分(二),
3。LitePal数据库集成部分(三)。
初步的构想大概类似这样的功能
下面就想从自定义日历开始。自定义日历的教程参考慕课网《自定义实现日历件》http://www.imooc.com/learn/775
先看下我做出来的效果
好了,开始撸代码,日历的实现不是纯自定义的View , 而是借助系统的控件组合而成的,贴出XML文件大家就一目了然了,这是日历组合布局文件canlendar_view.xml
还是比较简单的,一个头部LinearLayout和一个GridView组合就好了,主要看下实现类的写法,业务逻辑都在实现类中完成的。对应的业务实现类MyCalendarView.java
多的我就不再啰嗦了,代码中的注释还是比较多的,如果有什么不清楚的,完全可以拷贝然后试着运行下,相信你能更加理解我说的意思了,上述代码中有一个自定义的
TodayTextView.java
这个自定义的View主要用来显示区分当天,这里做的主要工作就是把当前天用红色圆圈圈出来,当然你也可以做更多的事情,比如把某个选中的View换个颜色显示。
还有多一个布局文件,就是上面Adapter中渲染的一个Layout布局文件calendar_day_text.xml
简单的引用了自定义的布局文件。MianActivity 和对应的activity_main.xml任然灰常简单
注意:MainActivity实现了自定义View中的那个接口,所以才能弹出效果图中的Toast提示,当然,你也可以直接使用GridView.setOnclickListener来实现。
第一部分的效果:完成了自定义日历控件,能够响应日历的点击事件,为后面的数据查询做准备,第一部分就到此为止。
,希望能够顺利写完。打算用三个篇幅来写,分别是
1。自定义日历控件部分(一),
2。极光推送集成以及富媒体消息推送部分(二),
3。LitePal数据库集成部分(三)。
初步的构想大概类似这样的功能
下面就想从自定义日历开始。自定义日历的教程参考慕课网《自定义实现日历件》http://www.imooc.com/learn/775
先看下我做出来的效果
好了,开始撸代码,日历的实现不是纯自定义的View , 而是借助系统的控件组合而成的,贴出XML文件大家就一目了然了,这是日历组合布局文件canlendar_view.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!--头部布局--> <LinearLayout android:layout_width="match_parent" android:layout_height="32dp" android:gravity="center_vertical" android:orientation="horizontal" android:paddingLeft="5dp" android:paddingRight="5dp"> <ImageView android:id="@+id/pre_month_btn" android:layout_width="32dp" android:layout_height="32dp" android:src="@android:drawable/ic_media_previous" /> <TextView android:id="@+id/cal_title_tv" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="May 2017" android:textSize="20sp" /> <ImageView android:id="@+id/next_month_btn" android:layout_width="32dp" android:layout_height="32dp" android:src="@android:drawable/ic_media_next" /> </LinearLayout> <LinearLayout android:id="@+id/week_title_layout" android:layout_width="match_parent" android:layout_height="30dp" android:orientation="horizontal"> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="星期日" android:textSize="16sp" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="星期一" android:textSize="16sp" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="星期二" android:textSize="16sp" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="星期三" android:textSize="16sp" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="星期四" android:textSize="16sp" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="星期五" android:textSize="16sp" /> <TextView android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="星期六" android:textSize="16sp" /> </LinearLayout> <!--日历布局--> <GridView android:id="@+id/days_grid_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:numColumns="7" /> </LinearLayout>
还是比较简单的,一个头部LinearLayout和一个GridView组合就好了,主要看下实现类的写法,业务逻辑都在实现类中完成的。对应的业务实现类MyCalendarView.java
public class MyCalendarView extends LinearLayout{ private ImageView mPreBtn , mNextBtn ; private TextView mCalendarTitle ; private GridView mDaysGridView ; public OnCalendarItemClickListener listener ; public void setOnCalendarItemClickListener(OnCalendarItemClickListener listener) { this.listener = listener; } private Calendar cruDate = Calendar.getInstance() ; // 全局日历 public MyCalendarView(Context context) { this(context,null); } public MyCalendarView(Context context, AttributeSet attrs) { this(context, attrs,0); bindView(context); } public MyCalendarView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); bindView(context); } private void bindView(Context context){ View v = LayoutInflater.from(context).inflate(R.layout.canlendar_view , this , true); mPreBtn = (ImageView) v.findViewById(R.id.pre_month_btn); mNextBtn = (ImageView) v.findViewById(R.id.next_month_btn); mCalendarTitle = (TextView) v.findViewById(R.id.cal_title_tv); mDaysGridView = (GridView) v.findViewById(R.id.days_grid_view); renderCalendar(); // 前一月 mPreBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { cruDate.add(Calendar.MONTH , -1); renderCalendar(); } }); // 后一月 mNextBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { cruDate.add(Calendar.MONTH , 1); renderCalendar(); } }); } /** * 核心的逻辑业务处理部分 */ private void renderCalendar(){ // 设置标题栏 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月"); mCalendarTitle.setText(sdf.format(cruDate.getTime())); // 准备要显示的数据 ArrayList<Date> cells = new ArrayList<>(); Calendar calendar = (Calendar) cruDate.clone(); calendar.set(Calendar.DAY_OF_MONTH,1); int preDays = calendar.get(Calendar.DAY_OF_WEEK ) - 1 ; calendar.add(Calendar.DAY_OF_MONTH,-preDays); int maxDays = 6 * 7 ; // 一个月最多需要6行显示完全,每行7天 while (cells.size() < maxDays){ // 填充数据 cells.add(calendar.getTime()); calendar.add(Calendar.DAY_OF_MONTH,1); } // 为GridView设置适配器 mDaysGridView.setAdapter(new CalArrayAdapter(getContext(),cells)); // 设置单个日期点击的接口 mDaysGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(listener == null){ return; }else{ listener.onCalendarItemClickListener((Date) parent.getItemAtPosition(position)); } } }); } /** * 日历显示数据的GridView的适配器 */ private class CalArrayAdapter extends ArrayAdapter<Date>{ LayoutInflater inflater ; public CalArrayAdapter(Context context, ArrayList<Date> days) { super(context, R.layout.calendar_day_text , days); inflater = LayoutInflater.from(context); } @Override public View getView(int position, View convertView, ViewGroup parent) { Date date = getItem(position); if(convertView == null){ convertView = inflater.inflate(R.layout.calendar_day_text, parent, false); } int day = date.getDate(); ((TodayTextView)convertView).setText(String.valueOf(day)); Date now = new Date(); // 当月 if(date.getMonth() == now.getMonth()){ ((TodayTextView)convertView).setTextColor(Color.BLACK); }else{ ((TodayTextView)convertView).setTextColor(Color.GRAY); } // 当天 if(date.getYear() == now.getYear() && date.getMonth() == now.getMonth() && date.getDate() == now.getDate()){ ((TodayTextView)convertView).setTextColor(Color.RED); // 当天标红 ((TodayTextView)convertView).isToday = true; } return convertView; } } /** * 自定义日历单个日期点击的接口 */ public interface OnCalendarItemClickListener{ // 传入选中的日期 void onCalendarItemClickListener(Date day); } }
多的我就不再啰嗦了,代码中的注释还是比较多的,如果有什么不清楚的,完全可以拷贝然后试着运行下,相信你能更加理解我说的意思了,上述代码中有一个自定义的
TodayTextView.java
public class TodayTextView extends TextView { private Paint mPaint = new Paint(); public boolean isToday = false ; // 确认是否是当天 public TodayTextView(Context context) { super(context); } public TodayTextView(Context context, AttributeSet attrs) { this(context, attrs , 0); } public TodayTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // 设置画笔 mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(3); mPaint.setAntiAlias(true); mPaint.setColor(Color.RED); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.translate(getWidth()/2 , getHeight()/2); // 移动到中心位置 if(isToday){ canvas.drawCircle(0 , 0 , getWidth()/2 - 3 ,mPaint); // 画圈 } } }
这个自定义的View主要用来显示区分当天,这里做的主要工作就是把当前天用红色圆圈圈出来,当然你也可以做更多的事情,比如把某个选中的View换个颜色显示。
还有多一个布局文件,就是上面Adapter中渲染的一个Layout布局文件calendar_day_text.xml
<?xml version="1.0" encoding="utf-8"?> <com.cjt.customcalendar.view.TodayTextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/cal_day_txt_tv" android:layout_width="36dp" android:layout_height="36dp" android:gravity="center" android:textSize="20sp"> </com.cjt.customcalendar.view.TodayTextView>
简单的引用了自定义的布局文件。MianActivity 和对应的activity_main.xml任然灰常简单
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.cjt.customcalendar.MainActivity"> <com.cjt.customcalendar.view.MyCalendarView android:id="@+id/MyCalendarView" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>
public class MainActivity extends AppCompatActivity implements MyCalendarView.OnCalendarItemClickListener { private MyCalendarView mCalendarView ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mCalendarView = (MyCalendarView) this.findViewById(R.id.MyCalendarView); mCalendarView.setOnCalendarItemClickListener(this); } @Override public void onCalendarItemClickListener(Date day) { Toast.makeText(this,"Date---"+day.toString(),Toast.LENGTH_SHORT).show(); } }
注意:MainActivity实现了自定义View中的那个接口,所以才能弹出效果图中的Toast提示,当然,你也可以直接使用GridView.setOnclickListener来实现。
第一部分的效果:完成了自定义日历控件,能够响应日历的点击事件,为后面的数据查询做准备,第一部分就到此为止。
相关文章推荐
- android菜鸟练手小项目之自定义日历,涵盖LitePal数据库,极光推送(二)
- android菜鸟练手小项目之自定义日历,涵盖LitePal数据库,极光推送(三)
- android菜鸟练手小项目之自定义日历,涵盖LitePal数据库,极光推送,聊天机器人(四)
- Android项目使用Dcloud架构处理极光推送跳转以及加载JS回调方法
- Android极光推送自定义通知问题
- 原生Android项目中集成react-native以及jpush-react-native(极光推送)
- Android之极光推送发送自定义消息
- Android之极光推送发送自定义消息
- Android极光推送自定义消息
- Android 极光推送获取自定义消息
- Android 使用极光推送消息详细介绍之自定义消息
- Android菜鸟练习第三十四课 第三方数据库LitePal的基本使用
- Android项目使用极光推送时步骤及注意的细节
- Android添加手机黑名单,手机来电拦截实现详解与Demo,一个不错的练手项目,涵盖Android四大组件。
- Android小菜鸟向大神进攻的奋斗记(一)之关于Android studio 使用极光推送,集成成功,但是推送不成
- Android极光推送手工整合到项目中的方法
- Ionic项目中使用极光推送-android
- Android 使用极光推送自定义消息打造个性的消息推送效果
- Android 使用极光推送自定义消息推送效果
- android项目中使用开源数据库litepal