Android应用-备忘录实现重点

作者: 3a7e0b22a5df | 来源:发表于2017-10-14 15:35 被阅读72次

    前言

    最近在做一个题目,是关于备忘录的实现。由于时间比较紧迫,所以只花了两天半左右时间完成,实现了日历的显示、日程的记录、数据的存储与读取以及解锁控件等功能,本文文末会附上源码下载地址,欢迎下载查看。文章不对全项目分析,只解析部分重点实现方式。

    功能

    (1)显示出日历
    (2)进行行程的记录、删除、查看、分享、修改功能
    (3)保存行程数据/读取行程数据
    (4)可对App设置图案密码

    效果图


    开发工具

    Android Studio

    开发环境

    1)JDK(Java Development Kit)JDK是Java语言的软件开发工具包,主要用于移动设备、嵌入设备上的java应用程序。

    2)SDK(software development kit) SDK是软件开发工具包。 被软件开发工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合

    实现过程重点解析

    (1)日历的自定义

    Android实际上是提供了日历这个控件的,但是如果能自定义View也许会更完美。那么,第一步当然是要自定义日历控件。我们首先需要定义一个NewCalender类继承于线性布局,在类中实现对布局的引入等操作。当然,在此之前,要自定义一个日历xml布局
    代码如下:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <RelativeLayout
        android:id="@+id/calender_header"
        android:layout_width="match_parent"
        android:layout_height="30dp">
        <ImageView
            android:id="@+id/btnPrev"
            android:background="@mipmap/last"
            android:layout_width="30dp"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="100dp"
            android:layout_height="30dp" />
        <ImageView
            android:id="@+id/btnNext"
            android:layout_width="30dp"
     android:layout_alignParentRight="true"
            android:layout_marginRight="100dp"
            android:background="@mipmap/next"
            android:layout_height="30dp" />
        <TextView
            android:text="2017 10"
            android:gravity="center"
            android:layout_width="wrap_content"
            android:layout_centerVertical="true"
            android:layout_height="match_parent" 
            android:layout_toRightOf="@id/btnPrev"
            android:layout_toLeftOf="@id/btnNext"
            android:id="@+id/txtDate"/>
    </RelativeLayout>
        <LinearLayout
            android:layout_marginTop="2dp"
            android:orientation="horizontal"
            android:id="@+id/calender_week_header"
            android:layout_width="match_parent"
            android:layout_height="40dp">
            <TextView
                android:text="星期日"
                android:textSize="15dp"
                android:layout_gravity="center_horizontal"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                />
            <TextView
                android:textSize="15dp"
                android:text="星期一"
                android:layout_gravity="center_horizontal"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
            <TextView
                android:text="星期二"
                android:textSize="15dp"
                android:layout_gravity="center_horizontal"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
            <TextView
                android:text="星期三"
                android:layout_gravity="center_horizontal"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:textSize="15dp"
                android:layout_height="match_parent" />
            <TextView
                android:text="星期四"
                android:textSize="15dp"
                android:layout_gravity="center_horizontal"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
            <TextView
                android:text="星期五"
                android:textSize="15dp"
                android:layout_gravity="center_horizontal"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
            <TextView
                android:text="星期六"
                android:textSize="15dp"
                android:layout_gravity="center_horizontal"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent" />
        </LinearLayout>
        <GridView
            android:layout_width="match_parent"
            android:numColumns="7"
            android:id="@+id/calender_grid"
            android:layout_height="match_parent"/>
    </LinearLayout>
    
    public class NewCalender extends LinearLayout {
        private ImageView btnPrev;
        private ImageView btnNext;
        private TextView txtDate;
        private GridView grid;
        public  ArrayList<Date> cells=new ArrayList<>();
        public NewCalendarListener newCalendarListener;
        private Calendar curDate=Calendar.getInstance();  //minsdk api:24
        public NewCalender(Context context) {
            super(context);
        }
    
        public NewCalender(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            initControl(context);
            bindControlEvent();
            renderCalendar();
        }
    
        public NewCalender(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initControl(context);
        }
        private void initControl(Context context)
        {
            bindControl(context);
        }
        //绑定各控件
        private void bindControl(Context context)
        {
            LayoutInflater inflater=LayoutInflater.from(context);
            inflater.inflate(R.layout.calender_view,this);
            btnPrev=(ImageView)findViewById(R.id.btnPrev);
            btnNext=(ImageView)findViewById(R.id.btnNext);
            txtDate=(TextView)findViewById(R.id.txtDate);
            grid=(GridView)findViewById(R.id.calender_grid);
        }
        //设置前后按钮监听事件
        //便于日历月份的变化处理
        private void bindControlEvent()
        {
            btnPrev.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                        curDate.add(Calendar.MONTH,-1);
                      renderCalendar();
                }
            });
            btnNext.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    curDate.add(Calendar.MONTH,+1);
                    renderCalendar();
                }
            });
        }
        //渲染函数 对日历控件进行渲染
        private  void renderCalendar()
        {
            SimpleDateFormat sdf=new SimpleDateFormat("MMM YYYY");
            txtDate.setText(sdf.format(curDate.getTime()));
            Calendar calendar=(Calendar) curDate.clone();  //复制一个curDate
            calendar.set(Calendar.DAY_OF_MONTH,1);
            int preDays=calendar.get(Calendar.DAY_OF_WEEK)-1;
            calendar.add(Calendar.DAY_OF_MONTH,-preDays);
            int maxCellCount=6*7;
            cells.clear();
            while(cells.size()<maxCellCount)
            {
                cells.add(calendar.getTime());
                calendar.add(Calendar.DAY_OF_MONTH,1);
            }
            grid.setAdapter(new CalendarAdapter(getContext(),cells));
            grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                     newCalendarListener.onItemPress((Date)adapterView.getItemAtPosition(i),i);
                }
            });
    
        }
        private class CalendarAdapter extends ArrayAdapter<Date>
        {
               LayoutInflater inflater;
            public CalendarAdapter(@NonNull Context context, ArrayList<Date> days) {
                super(context,R.layout.calendar_day,days);
                inflater=LayoutInflater.from(context);
            }
            @NonNull
            @Override
            public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                Date date=getItem(position);
                if(convertView==null)
                {
                    convertView = inflater.inflate(R.layout.calendar_day, parent, false);
                }
                int day=date.getDate();
                ((TextView)convertView).setText(String.valueOf(day));
                //设置字体颜色
                Date now=new Date();
                Calendar calendar=(Calendar) curDate.clone();
                calendar.set(Calendar.DAY_OF_MONTH,1);
                boolean isTheSameMonth=false;
                if(now.getMonth()==date.getMonth())
                {
                    isTheSameMonth=true;
                }
                if(isTheSameMonth)
                {
                    ((Calendar_text_view)convertView).setTextColor(Color.parseColor("#000000"));
                }else
                {
                    ((Calendar_text_view)convertView).setTextColor(Color.parseColor("#666666"));
                }
    
                if(now.getDate()==date.getDate()&&now.getMonth()==date.getMonth()
                        &&now.getYear()==date.getYear())
                {
                    ((Calendar_text_view)convertView).setTextColor(Color.parseColor("#ff0000"));
                    ((Calendar_text_view)convertView).isToday=true;
                }
                 return convertView;
            }
        }
        //自定义接口 在主活动中可调用
        //设置了position参数 便于对所选日期位置进行记录
        //方便日程的保存
        public  interface  NewCalendarListener
        {
            void onItemPress(Date day,int position);
        }
    }
    

    其中,Calendar_text_view类是自定义的文本显示框,当日日期将会显示红色圆边框。

    public class Calendar_text_view extends android.support.v7.widget.AppCompatTextView {
        public  boolean isToday=false;
        public Paint paint;
        @Override
        public int getSystemUiVisibility() {
            return super.getSystemUiVisibility();
        }
    
        public Calendar_text_view(Context context) {
            super(context);
        }
    
        public Calendar_text_view(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            initControl();
        }
    
        public Calendar_text_view(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initControl();
        }
        private void initControl()
        {   paint=new Paint();
            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(Color.parseColor("#FF0000"));
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if(isToday)
            {  canvas.translate(getWidth()/2,getHeight()/2);
               canvas.drawCircle(0,0,getWidth()/2,paint);
            }
        }
    }
    

    (2)日程点击事件

    当我们点击日期时,下方将会有一个ListView用于显示当天的行程,那么点击行程后,我们可以进行行程的修改、删除、分享、查看等功能。这里我将选项放置在了ChooseActivity中,利startActivityForResult将选择的结果以判断值的形式返回给主活动,主活动根据判断值的不同作出不同的响应,这样的做法使得程序思路较为清晰。

    public class chooseActivity extends Activity implements View.OnClickListener{
        public Button btnLook;
        public Button btndelete;
        public Button btnmodify;
        public Button btnshare;
        public Button btnAlarm;
        /*
        *此活动时通过startActivityforresult启动的
        * 故只会根据用户的选择返回不同的判断值
        * 然后具体在逻辑处理仍旧时在MainActivity中处理
        */
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_choose);
            btnLook=(Button)findViewById(R.id.look);
            btndelete=(Button)findViewById(R.id.delete);
            btnmodify=(Button)findViewById(R.id.modify);
            btnshare=(Button)findViewById(R.id.share);
            btnAlarm=(Button)findViewById(R.id.alarm_set);
            btnAlarm.setOnClickListener(this);
            btndelete.setOnClickListener(this);
            btnmodify.setOnClickListener(this);
            btnLook.setOnClickListener(this);
            btnshare.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View view) {
            Intent intent=new Intent();
            switch (view.getId())
            {
                case R.id.look:
                    //返回判断值1
                    intent.putExtra("judge",1);
                    setResult(RESULT_OK,intent);
                    finish();
                    break;
                case R.id.delete:
                    //返回判断值2
                    intent.putExtra("judge",2);
                    setResult(RESULT_OK,intent);
                    finish();
                    break;
                case R.id.modify:
                    //返回判断值3
                    intent.putExtra("judge",3);
                    setResult(RESULT_OK,intent);
                    finish();
                    break;
                case R.id.share:
                    Intent intent1=new Intent(Intent.ACTION_SEND);
                    intent1.setType("text/plain");
                    //分享文本内容
                    intent1.putExtra(Intent.EXTRA_TEXT,getIntent().getStringExtra("content"));
                    intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(Intent.createChooser(intent1,getTitle()));
                    break;
                case R.id.alarm_set:
                    intent.putExtra("judge",4);
                    setResult(RESULT_OK,intent);
                    finish();
                    break;
    
    
            }
        }
    

    主活动处理:

     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            switch (requestCode)
            {
                case 1:if(resultCode==RESULT_OK&&data.getStringExtra("judge")!="cancel")
                {
                    Bundle bundle=data.getBundleExtra("add");
                    sch.add((schedule)bundle.getSerializable("add_data"));
                    saveData(mPosition);
                    sch_view.setVisibility(View.VISIBLE);
                    nullSch.setVisibility(View.GONE);
                    schAdapter adapter=new schAdapter(sch,this);
                    sch_view.setAdapter(adapter);
                }
                    if(resultCode==2)
                    {
                        Bundle bundle=data.getBundleExtra("add");
                        sch.remove(lvPosition);
                        sch.add((schedule)bundle.getSerializable("add_data"));
                        saveData(mPosition);
                        sch_view.setVisibility(View.VISIBLE);
                        nullSch.setVisibility(View.GONE);
                        schAdapter adapter=new schAdapter(sch,this);
                        sch_view.setAdapter(adapter);
                    }
                    break;
                case 2:if(resultCode==RESULT_OK)
                {
                    int judge=data.getIntExtra("judge",0);
                    switch (judge)
                    {
                        case 1:Intent intent=new Intent(MainActivity.this,lookActivity.class);
                            intent.putExtra("time",curDay+sch.get(lvPosition).time);
                            intent.putExtra("content",sch.get(lvPosition).content);
                            startActivity(intent);
                            break;
                        case 2: sch.remove(lvPosition);
                            saveData(mPosition);
                            schAdapter adapter=new schAdapter(sch,this);
                            sch_view.setAdapter(adapter);
                            break;
                        //修改日程
                        case 3:
                            Intent intent1=new Intent(MainActivity.this,addActivity.class);
                            String [] a=sch.get(lvPosition).time.split(":");
                            intent1.putExtra("hour",a[0]);
                            intent1.putExtra("min",a[1]);
                            intent1.putExtra("content",sch.get(lvPosition).content);
                            startActivityForResult(intent1,1);
                            break;
                        //闹钟设置
                        case 4:
                             setalarm();
                            break;
                    }
                }
                    break;
            }
        }
    

    其中,修改、查看均为Acitivity,将由主活动跳转.

    (3)解锁控件的应用

    本应用添加了锁定功能,用于保护隐私。使用的时开源控件PatternLockView,使用前,我们需要在gradle中添加以下依赖:

      compile 'com.andrognito.patternlockview:patternlockview:1.0.0'
    

    之后可以设置按钮,点击后跳转到设置密码的Activity,在活动中再对密码进行处理与保存等操作。
    patternlockview监听器提供了以下方法。

    public void onStarted();
    public void onProgress(List<PatternLockView.Dot> progressPattern);
    public void onComplete(List<PatternLockView.Dot> pattern);
    public void onCleared();
    

    在第三个函数中实现密码的处理操作即可。

    可拓展功能

    实现闹钟提醒,UI美化等

    总结

    本文重点在日定义的实现代码部分,代码也有部分注释,理解代码可能需要一定的android基础,由于本人写简书的经验不足,难以做到浅显易懂,见谅。如果能对你有所帮助,当然最好。如果你也想实现一个备忘录,有问题也可私信交流。谢谢阅读。文末附上源码。
    https://pan.baidu.com/s/1o8OIivC
    密码:x6t4
    下载前私信告知一声哦。

    相关文章

      网友评论

        本文标题:Android应用-备忘录实现重点

        本文链接:https://www.haomeiwen.com/subject/hegxuxtx.html