android菜鸟练手小项目之自定义日历,涵盖LitePal数据库,极光推送(一)

来源:互联网 发布:西门子plc数据用于联网 编辑:程序博客网 时间:2024/05/19 17:05

心血来潮想开发个小玩意练练手,于是就有了上面标题的创意,自己一直想用下郭霖大神的开源数据库项目LitePal,再加之想要每天进行推送,于是跟日历结合起来有了下面的构想,项目简单点,对于我这个菜鸟而言就不会半途而废尴尬,希望能够顺利写完。打算用三个篇幅来写,分别是

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来实现。

第一部分的效果:完成了自定义日历控件,能够响应日历的点击事件,为后面的数据查询做准备,第一部分就到此为止。

0 0
原创粉丝点击