精华内容
下载资源
问答
  • 源码安卓备忘录开发为了明天方便我自己下载,这个东西网上有,你们别花分在这个上面
  • 安卓备忘录

    2015-06-20 12:37:33
    这是一款基于安卓平台的,利用elipse开发与实现的,用于实现闹钟与备忘录功能的源代码。
  • 安卓开发备忘录源码

    2016-03-22 21:47:11
    这是一个简单的安卓备忘录应用的源码实例,适合新手借鉴学习。
  • 毕业设计论文-安卓系统下的备忘录开发与研究论文.rar
  • 备忘录基于安卓移动开发,手机端的备忘录,让您记录身边的事情。不要忘记,手机移动完美。
  • 基于安卓开发备忘录学年设计文档,且已经通过老师的审核
  • 开发一个安卓app-备忘录

    千次阅读 多人点赞 2019-08-27 17:22:57
    效果图 工程目录: AddActivity代码: package cn.fanting.notpadnew; import android.annotation.SuppressLint; import android.content.Context; import android.content...import android.support.v7.ap...

    效果图

         

    工程目录:

    AddActivity代码:

    package cn.fanting.notpadnew;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.content.Intent;
    import android.support.v7.app.ActionBar;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.io.BufferedWriter;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class AddActivity extends AppCompatActivity {
    
        private EditText editText;//正文
    
        @SuppressLint("SetTextI18n")
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.add_layout);
    
            //将系统自带的标题栏隐藏掉
            ActionBar actionbar = getSupportActionBar();
            if (actionbar != null){
                actionbar.hide();
            }
    
            //关联布局控件
            editText = findViewById(R.id.add_text);
            TextView textView = findViewById(R.id.add_time);
    
            textView.setText(timeStamp1()+" "+timeStamp2()+" ");//将时间填充到
    
            //自动弹出软键盘
                editText.setFocusable(true);
                editText.setFocusableInTouchMode(true);
    
                java.util.Timer timer = new java.util.Timer();
                timer.schedule(new java.util.TimerTask(){
                public void run(){
                android.view.inputmethod.InputMethodManager inputManager =(android.view.inputmethod.InputMethodManager)editText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                    assert inputManager != null;
                    inputManager.showSoftInput(editText, 0);
                }
    
            },300);
    
    
            //注册"分享"按钮的监听事件
            Button button_share = findViewById(R.id.add_share);
            button_share.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    switch (v.getId()) {
                        case R.id.add_share:
                            shareMsg();//分享
                            break;
                    }
                }
            });
        }
    
    
        @Override//销毁页面前保存文本
        protected void onDestroy() {
            super.onDestroy();
            String inputText = editText.getText().toString();//将获取到的EditText内的文本转化为字符串
            if (!TextUtils.isEmpty(inputText)) {
                if (!TextUtils.isEmpty(inputText)) {//文本不为空
                    save(inputText);//存储到文件指定文件中
                } else {
                    save(inputText);//存储到文件指定文件中
                }
            }
        }
    
    
    
        //常用方法封装
        //时间戳
        public static  String timeStamp1(){
            Date time = new Date();
            //SimpleDateFormat format1 = new SimpleDateFormat( "yy年MM月dd日  HH:mm:ss" );//定义时间格式
            SimpleDateFormat format1 = new SimpleDateFormat( "yy-MM-dd" );//定义时间格式
            return format1.format(time);
        }
    
        public static String timeStamp2(){
            Date time = new Date();
            SimpleDateFormat format2 = new SimpleDateFormat( "HH:mm:ss" );//定义时间格式
            return format2.format(time);
        }
    
    
        //存储标题、文本
        private void save(String text) {
            BufferedWriter writertext = null;
            String saveFileName;
            if (text.length() >= 9) {
                saveFileName = timeStamp1()+" "+timeStamp2()+"   "+text.substring(0, 9);
            }else {
                saveFileName = timeStamp1()+" "+timeStamp2()+"   "+ text;
            }
    
            try {
                FileOutputStream outtext = openFileOutput(saveFileName, Context.MODE_PRIVATE);
                writertext = new BufferedWriter(new OutputStreamWriter(outtext));
                writertext.write(text);
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                try {
                    if (writertext != null){
                        writertext.close();
                    }
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    
        //分享方法
        public void shareMsg() {
            editText.getText(); //获取文本
            String text = editText.getText().toString();//转化为字符串
    
            if(!text.equals("")) {
                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.setType("text/plain"); // 纯文本
    
                intent.putExtra(Intent.EXTRA_TEXT, text);//分享内容
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(Intent.createChooser(intent, "分享文本"));//弹框标题
            }else if (text.equals("")){
                Toast.makeText(getApplicationContext(), "没有内容", Toast.LENGTH_LONG).show();
            }
            else {
                Toast.makeText(getApplicationContext(), "分享失败", Toast.LENGTH_LONG).show();
            }
        }
    
    
    }
    
    Book代码:
    package cn.fanting.notpadnew;
    
    public class Book {
        private String name;
        private int imageId;
    
        Book(String name, int imageId){
            this.name = name;
            this.imageId = imageId;
        }
    
        public String getName(){
            return name;
        }
    
        public int getImageId(){
            return imageId;
        }
    }
    
    BookAdapter代码:
    package cn.fanting.notpadnew;
    
    import android.annotation.SuppressLint;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.support.annotation.NonNull;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.io.File;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class BookAdapter extends RecyclerView.Adapter<BookAdapter.ViewHolder> {
        private List<Book> mBookList;
        private MainActivity mainActivity;//引用
    
        static class ViewHolder extends RecyclerView.ViewHolder{//定义内部类:ViewHolder,继承自RecyclerView.ViewHolder
            ImageView bookImage;
            TextView bookName;
            View bookView;//点击
    
            ViewHolder(View view){//ViewHolder的构造函数中传入参数view
                super(view);
                bookImage = view.findViewById(R.id.book_image);//通过findViewById方法获取布局中的ImageView和TextView
                bookName = view.findViewById(R.id.book_name);
                bookView = view;//点击
    
            }
        }
    
        BookAdapter(MainActivity mainActivity, List<Book> bookList){//将展示的数据源传给bookList
            this.mainActivity = mainActivity;
            mBookList = bookList;//赋值给一个全局变量mBookList,后续操作都在mBookList数据源进行
        }
    
        //因为BookAdapter是继承自RecyclerView.Adapter的,所以必须重写onCreateViewHolder、onBindViewHolder、getItemCount三个方法
        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);//加载自定义布局
            final ViewHolder holder = new ViewHolder(view);//创建一个ViewHolder实例,把加载的布局传到构造函数中
            //点击事件监听
            holder.bookView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = holder.getAdapterPosition();//获取用户点击的position
                    Book book = mBookList.get(position);//通过position拿到Book实例
                    Intent Edit = new Intent(mainActivity,EditActivity.class);
                    Edit.putExtra("title",book.getName());//获取文件名字,传递参数
    
                    mainActivity.startActivity(Edit);
    
                }
            });
            //长按事件监听
            holder.bookView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    int position = holder.getAdapterPosition();
                    final Book book = mBookList.get(position);
    
                    //String inputTitle = book.getName().substring(0,book.getName().indexOf(".txt"));//截取标题
    
                    //提示框
                    AlertDialog.Builder dialog = new AlertDialog.Builder(mainActivity);
    
                    //去掉换行
                    String getName1 = null;
                    if (book.getName()!=null) {
                        Pattern p = Pattern.compile("[*\t\r\n]");
                        Matcher m = p.matcher(book.getName());
                        getName1 = m.replaceAll("");
                    }
    
                    dialog.setMessage("删除: "+getName1+" ?");
                    //dialog.setCancelable(false);//屏蔽返回键
                    dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                        @SuppressLint("SdCardPath")
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            deleteFileName("/data/data/cn.fanting.notpadnew/files/"+book.getName());//删除文件
                            mainActivity.notifyData();//刷新列表
                        }
                    });
                    dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            mainActivity.notifyData();//刷新列表
                        }
                    });
                    dialog.show();
    
                    return false;
                }
            });
            return holder;//将holder实例返回
        }
    
        @Override//对RecyclerView子项数据赋值,会在每个子项被滚动到屏幕内的时候执行
        public void onBindViewHolder(@NonNull ViewHolder holder, int position){
            Book book = mBookList.get(position);//通过position参数得到当前项的Book实例
            holder.bookImage.setImageResource(book.getImageId());//将数据设置到ViewHolder的bookImage中
            holder.bookName.setText(book.getName());//将数据设置到ViewHolder的bookName中
        }
    
        @Override//告诉RecyclerView一共有多少个子项
        public int getItemCount(){
            return mBookList.size();//返回数据源长度
        }
    
        //删除单个文件
        private void deleteFileName(String fileName) {
            File file = new File(fileName);
            // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
            if (file.exists() && file.isFile()) {
                if (!file.delete()) {
                    Toast.makeText(mainActivity, "删除失败", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(mainActivity, "文件" + fileName + "不存在", Toast.LENGTH_SHORT).show();
            }
        }
    }
    
    EditActivity代码:
    package cn.fanting.notpadnew;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.content.Intent;
    import android.net.Uri;
    import android.support.v7.app.ActionBar;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    
    import static cn.fanting.notpadnew.AddActivity.timeStamp1;
    import static cn.fanting.notpadnew.AddActivity.timeStamp2;
    
    public class EditActivity extends AppCompatActivity {
    
        private EditText editText;//正文
        private String mNoteTitle;//文件名(标题)
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.edit_layout);
    
            //将系统自带的标题栏隐藏掉
            ActionBar actionbar = getSupportActionBar();
            if (actionbar != null){
                actionbar.hide();
            }
    
            //关联布局控件
            editText = findViewById(R.id.edit_text);
            TextView textView = findViewById(R.id.edit_time);
    
            mNoteTitle = getIntent().getStringExtra("title");//接收参数
            load();//读取
    
            textView.setText(mNoteTitle.substring(0, 18));//将时间填充到
    
    
            //注册"分享"按钮的监听事件
            Button button_share = findViewById(R.id.edit_share);
            button_share.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    switch (v.getId()) {
                        case R.id.edit_share:
                            shareMsg();//分享
                            break;
                    }
                }
            });
        }
    
        @SuppressLint("SdCardPath")
        @Override//销毁页面前保存文本
        protected void onDestroy() {
            super.onDestroy();
            //读取之前的内容
            FileInputStream in;
            BufferedReader reader = null;
            StringBuilder content = new StringBuilder();
            try {
                in = openFileInput(mNoteTitle);//从默认目录加载data文件,返回一个FileInputStream对象
                reader = new BufferedReader(new InputStreamReader(in));//读取对象
                String line;
                while ((line = reader.readLine()) != null) {//读取一行文本
                    content.append(line).append("\n");//每次都在末尾插入文本
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            String loadText1 = content.toString();//将content转化成字符串inputText
            String loadText = null;
            if (loadText1.length() != 0) {
                loadText = loadText1.substring(0, loadText1.length() - 1);//去掉最末尾的\n
            }
    
    
            //获取当前输入的内容
            String inputText = editText.getText().toString();//将获取到的EditText内的文本转化为字符串
            if (!TextUtils.isEmpty(inputText)) {
                assert loadText != null;
                if (!loadText.equals(inputText)) {//文本和之前不一样
                    save(inputText);//存储到文件指定文件中
                    deleteFileName("/data/data/cn.fanting.notpadnew/files/" + mNoteTitle);
                }
            }
    
    
        }
    
    
    
    
    
    
        //常用方法封装
        //读取
        public void load(){
            FileInputStream in;
            BufferedReader reader = null;
            StringBuilder content = new StringBuilder();
            try{
                in = openFileInput(mNoteTitle);//从默认目录加载data文件,返回一个FileInputStream对象
                reader = new BufferedReader(new InputStreamReader(in));//读取对象
                String line;
                while ((line = reader.readLine()) !=null){//读取一行文本
                    content.append(line).append("\n");//每次都在末尾插入文本,插入换行
                }
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                if (reader !=null){
                    try{
                        reader.close();
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }
            }
            String loadText1 = content.toString();//将content转化成字符串inputText
            String loadText = null;
            if (loadText1.length() != 0) {
                loadText = loadText1.substring(0, loadText1.length() - 1);
            }
    
                editText.setText(loadText);//将inputText内容填充到editText
                editText.requestFocus();//获取焦点
            assert loadText != null;
            editText.setSelection(loadText.length());//将光标移动到文本末尾
    
                //自动弹出软键盘
                editText.setFocusable(true);
                editText.setFocusableInTouchMode(true);
    
                java.util.Timer timer = new java.util.Timer();
                timer.schedule(new java.util.TimerTask(){
                public void run(){
                android.view.inputmethod.InputMethodManager inputManager =(android.view.inputmethod.InputMethodManager)editText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                    assert inputManager != null;
                    inputManager.showSoftInput(editText, 0);
                }
    
            },300);
        }
    
    
        //存储标题、文本
        private void save(String text) {
            BufferedWriter writertext = null;
            String saveFileName;
    
            if (text.length() >= 9) {
                saveFileName = timeStamp1()+" "+timeStamp2()+"   "+text.substring(0, 9);
            }else {
                saveFileName = timeStamp1()+" "+timeStamp2()+"   "+ text;
            }
    
            try {
                FileOutputStream outtext = openFileOutput(saveFileName, Context.MODE_PRIVATE);
                writertext = new BufferedWriter(new OutputStreamWriter(outtext));
                writertext.write(text);
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                try {
                    if (writertext != null){
                        writertext.close();
                    }
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    
        //删除单个文件
        public void deleteFileName(String fileName) {
            File file = new File(fileName);
            // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
            if (file.exists() && file.isFile()) {
                if (!file.delete()) {
                    Toast.makeText(getApplicationContext(), "删除失败", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(getApplicationContext(), "文件" + fileName + "不存在", Toast.LENGTH_SHORT).show();
            }
        }
    
        //分享方法
        public void shareMsg() {
            editText.getText(); //获取文本
            String text = editText.getText().toString();//转化为字符串
    
            Intent intent = new Intent(Intent.ACTION_SEND);
            intent.setType("text/plain"); // 纯文本
    
            intent.putExtra(Intent.EXTRA_TEXT, text);//分享内容
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(Intent.createChooser(intent,"分享文本"));//弹框标题
        }
    }
    
    MainActivity代码:
    package cn.fanting.notpadnew;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.os.Handler;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;
    
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.util.ArrayList;
    import java.util.List;
    
    import static cn.fanting.notpadnew.AddActivity.timeStamp1;
    import static cn.fanting.notpadnew.AddActivity.timeStamp2;
    
    public class MainActivity extends AppCompatActivity {
    
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.main_menu, menu);
            return true;
        }
    
        @SuppressLint("SdCardPath")
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.deletename_item://全部删除button
                    AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
                    dialog.setTitle("提示");
                    dialog.setMessage("删除全部记录?");
                    //dialog.setCancelable(false);//屏蔽返回键
                    dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                        @SuppressLint("SdCardPath")
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            deleteDir("/data/data/cn.fanting.notpadnew/files/");//全部删除
                            notifyData();//刷新列表
                        }
                    });
                    dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            notifyData();
                        }
                    });
                    dialog.show();
                    break;
            }
            return true;
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            new Handler().postDelayed(new Runnable() {
                @Override//延时
                public void run() {
    
                    notifyData();
                }
            }, 800);
        }
    
        public void notifyData() {
            initBook();//重新初xcc始化数据。
            RecyclerView recyclerView = findViewById(R.id.recycler_view);//获取到RecyclerView实例
            recyclerView.getAdapter().notifyDataSetChanged();//刷新列表
        }
    
    
        private List<Book> bookList = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_layout);
    
    
            //声明Sharedpreferenced对象
            SharedPreferences sp = getSharedPreferences("filename", Context.MODE_PRIVATE);
    
            boolean value = sp.getBoolean("user", false);
            if (!value) {//首次使用app
                save("首次使用 介绍说明\n\n1、卸载软件后数据将会清空,卸载前请备份。\n2、长按可以删除单条记录,全部删除在菜单栏。\n3、为了避免误操作,返回后也会保存。\n4、不输入任何内容将不会保存。");
            }
            //获取到edit对象
            SharedPreferences.Editor edit = sp.edit();
            //通过editor对象写入数据
            edit.putBoolean("user", true);
            //提交数据存入到xml文件中
            edit.apply();
    
    
    
            initBook();//初始化Book数据
            RecyclerView recyclerView = findViewById(R.id.recycler_view);//获取到RecyclerView实例
            LinearLayoutManager layoutManager = new LinearLayoutManager(this);//指定布局方式,LinearLayoutManager:线性布局,可以实现和listview类似的效果
            recyclerView.setLayoutManager(layoutManager);//设置布局管理器
            BookAdapter adapter = new BookAdapter(this, bookList);//将bookList数据传入到BookAdapter的构造函数中
            recyclerView.setAdapter(adapter);//设置adapter
    
            //设置item间距,30dp
            recyclerView.addItemDecoration(new SpacesItemDecoration(40));
            recyclerView.setAdapter(adapter);
    
            //注册add按钮的监听事件
            Button button_add = findViewById(R.id.button_add);
            button_add.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    switch (v.getId()) {
                        case R.id.button_add:
                            Intent Add = new Intent(MainActivity.this, AddActivity.class);
                            startActivity(Add);
                            break;
                    }
                }
            });
        }
    
    
        private void initBook() {
            bookList.clear();//清空数据
            String[] str = fileList();//遍历文件,组成数组
            for (String s : str) {
                Book a = new Book(s, R.mipmap.notpad_icon);
                bookList.add(a);
            }
        }
    
    
        //删除目录下所有文件
        public static void deleteDir(final String pPath) {
            File dir = new File(pPath);
            deleteDirWihtFile(dir);
        }
    
        public static void deleteDirWihtFile(File dir) {
            if (dir == null || !dir.exists() || !dir.isDirectory())
                return;
            for (File file : dir.listFiles()) {
                if (file.isFile())
                    file.delete(); // 删除所有文件
                else if (file.isDirectory())
                    deleteDirWihtFile(file); // 递规的方式删除文件夹
            }
            //dir.delete();// 删除目录本身
        }
    
    
    
        //存储标题、文本
        private void save(String text) {
            BufferedWriter writertext = null;
            String saveFileName;
            if (text.length() >= 9) {
                saveFileName = timeStamp1()+" "+timeStamp2()+"   "+text.substring(0, 9);
            }else {
                saveFileName = timeStamp1()+" "+timeStamp2()+"   "+ text;
            }
    
            try {
                FileOutputStream outtext = openFileOutput(saveFileName, Context.MODE_PRIVATE);
                writertext = new BufferedWriter(new OutputStreamWriter(outtext));
                writertext.write(text);
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                try {
                    if (writertext != null){
                        writertext.close();
                    }
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    SpacesItemDecoration代码:
    package cn.fanting.notpadnew;
    
    import android.graphics.Rect;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    
    public class SpacesItemDecoration extends RecyclerView.ItemDecoration{
        private int space;
    
        SpacesItemDecoration(int space) {
            this.space = space;
        }
    
        @Override
        public void getItemOffsets(Rect outRect, View view,
                                   RecyclerView parent, RecyclerView.State state) {
            outRect.left = 20;
            outRect.right = 20;
            outRect.bottom = space;
    
            //仅为第一个项目添加上边距,以避免项目之间的双倍空间
            if (parent.getChildPosition(view) == 0)
                outRect.top = space;
        }
    
    }
    
    TitleLayout代码:
    package cn.fanting.notpadnew;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.net.Uri;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.Button;
    import android.widget.LinearLayout;
    
    import java.io.File;
    
    public class TitleLayout extends LinearLayout {
    
        public TitleLayout(Context context , AttributeSet attrs){
            super(context , attrs);
            LayoutInflater.from(context).inflate(R.layout.title, this);
            Button titleBack = findViewById(R.id.title_back);
            titleBack.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    ((Activity) getContext()).finish();
                }
            });
        }
    }

    add_layout.xml布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context=".AddActivity"
        android:orientation="vertical"
        android:background="#CDAA7D">
        <include layout="@layout/title"/>
    
        <cn.fanting.notpadnew.TitleLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
        <TextView
            android:id="@+id/add_time"
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:layout_above="@+id/add_text"
            android:layout_alignParentStart="true"
            android:layout_marginBottom="-84dp"
            android:gravity="right"
            android:text="TextView"
            android:textColor="#FFFFFF"
            tools:ignore="UnknownIdInLayout" />
    
        <EditText
            android:id="@+id/add_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentBottom="true"
            android:layout_alignParentStart="true"
            android:layout_marginTop="84dp"
            android:background="@null"
            android:gravity="top"
            android:hint="请输入文本"
            android:textColorHint="@color/colorAddEditText" />
    
        <Button
            android:id="@+id/add_share"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentTop="true"
            android:text="分享"
            android:textColor="#fff"
            android:background="#8B4513"/>
    
    </RelativeLayout>

    edit_layout.xml布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context=".EditActivity"
        android:orientation="vertical"
        android:background="#CDAA7D">
        <include layout="@layout/title"/>
    
        <cn.fanting.notpadnew.TitleLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
    
        <TextView
            android:id="@+id/edit_time"
            android:layout_width="match_parent"
            android:layout_height="20dp"
            android:layout_above="@+id/edit_text"
            android:layout_alignParentStart="true"
            android:layout_marginBottom="-84dp"
            android:gravity="right"
            android:text="TextView"
            android:textColor="#FFFFFF"
            tools:ignore="UnknownIdInLayout" />
    
        <EditText
            android:id="@+id/edit_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentBottom="true"
            android:layout_alignParentStart="true"
            android:layout_marginTop="84dp"
            android:background="@null"
            android:gravity="top"
            android:hint="请输入文本"
            android:textColorHint="@color/colorAddEditText" />
    
        <Button
            android:id="@+id/edit_share"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentTop="true"
            android:text="分享"
            android:textColor="#fff"
            android:background="#8B4513"/>
    </RelativeLayout>
    

    item_layout.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:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="#CDAA7D"
        android:orientation="horizontal">
    
        <ImageView
            android:id="@+id/book_image"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />
    
        <TextView
            android:id="@+id/book_name"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginStart="10dp"
            android:ellipsize="end"
            android:gravity="center_vertical"
            android:maxEms="19"
            android:singleLine="true"
    
            android:text="23242342353453454353"
            android:textColor="#000000"
            android:textSize="16sp" />
    
    </LinearLayout>
    

    main_layout.xml布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:background="#8B4513">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <Button
            android:id="@+id/button_add"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentEnd="true"
            android:layout_marginBottom="23dp"
            android:layout_marginEnd="34dp"
            android:background="@drawable/addbutton" />
    </RelativeLayout>

    title.xml布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#8B4513">
    
        <Button
            android:id="@+id/title_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="5dp"
            android:text="保存"
            android:textColor="#fff"
            android:background="#8B4513"
            tools:ignore="HardcodedText" />
    
        <!--<TextView-->
            <!--android:id="@+id/title_text"-->
            <!--android:layout_width="0dp"-->
            <!--android:layout_height="wrap_content"-->
            <!--android:layout_gravity="center"-->
            <!--android:layout_weight="1"-->
            <!--android:gravity="center"-->
            <!--android:text="备忘录"-->
            <!--android:textColor="#fff"-->
            <!--android:textSize="24sp" />-->
    
    
    </LinearLayout>
    

    main_menu.xml布局:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:id="@+id/deletename_item"
            android:title="全部删除"/>
    
    </menu>

    colors.xml配置:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="colorPrimaryDark">#8B4513</color>
        <color name="colorPrimary">#8B4513</color>
        <color name="colorAccent">#000000</color>
        <color name="colorAddEditText">#808080</color>
    
    </resources>
    

    strings.xml配置:

    <resources>
        <string name="app_name">备忘录</string>
    </resources>
    

    styles.xml配置:

    <resources>
    
        <!-- Base application theme. -->
        <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>
    
        <style name="AppAdd" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>
    
        <style name="AppEdit" parent="Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
        </style>
    
    </resources>
    

     

    展开全文
  • 这是Android程序设计与开发(Android Studio版)课程的课程设计——“备忘录“软件源代码。没有bug,保证符合课设要求,老师已验收过,成绩优秀。
  • 基于安卓Android的备忘录系统APP的设计(Eclipse)(任务书,开题报告,论文13000字,程序代码)摘要随着移动互联网的高速发展,智能手机的使用已经普及。为了能让智能手机发挥更大的应用功能,一种高效的办法就是将各种...

    基于安卓Android的备忘录系统APP的设计(Eclipse)(任务书,开题报告,论文13000字,程序代码)

    摘要

    随着移动互联网的高速发展,智能手机的使用已经普及。为了能让智能手机发挥更大的应用功能,一种高效的办法就是将各种应用系统的功能拓展到手机终端上。如今人们的学习、工作任务繁重,大量日常事务信息需要记住,有时候难免忘记其中一部分。为了帮助移动用户记住日常事务信息,开发一个简单便捷的备忘录系统是很有必要的。

    本次毕业设计旨在设计一个基于Android的个人备忘录系统,数据存储方面使用Android自带的Sqlite数据库,系统要求界面友好,使用方便,需要实现的基本功能如下:显示所有的备忘录信息,添加修改删除备忘录和设置闹钟提醒功能。本文在实现五个基本功能的基础上,还添加了一些其他的小功能,如:APP启动动画、用户反馈等,使Android备忘录系统更加完美。

    本论文是Android开发基础之作,对学习Android开发的入门者有很大的参考价值。

    关键词:安卓;智能手机;记录;移动互联网;

    Abstract

    With the high-speed development of mobile Internet, smartphones have popularity. In order to make smart phones play a more important application functions, a highly efficient way is to apply various system functions to mobile terminal. Now people's study, the workloads, a large number of daily transaction information to keep in mind, sometimes hard to avoid forget one part. In order to help mobile users to remember daily transaction information, develop a simple and convenient memo system is necessary.

    This graduation project aims to design a personal memo system based on Android, Android used to own Sqlite database data storage, system requirements, friendly interface, easy to use, you need to implement the basic functions are as follows: display all of the information memorandum. In this paper, on the basis of the five basic functions of the implementation, also added some other small features, such as: APP to start the animation, user feedback, etc., make the Android memo system more perfect.

    This paper is the Android development foundation, to grasp learning Android development has great reference value.

    Key Words:Android; Smart phones; Record; The mobile Internet

    功能需求分析

    在对本次的项目进行分析之后,开发的备忘录软件需要以下几个功能:

    1.    能够查看所有的备忘录。

    2.    能够添加备忘录。

    3.    能够修改某一条备忘录。

    4.    能够删除备忘录。

    5.    能够设置闹钟提醒功能。

    6.    菜单可以查看软件介绍及使用说明、退出等。

    开发环境需求

    此次开发的系统是一个简单的android客户端,需要的IDE是Eclipse。需要安装Android sdk并配置好android开发环境,开发环境搭建详细步骤可参考《Android移动应用开发案例教程》的 “搭建Android开发环境”。数据库方面不用考虑,Android带有专用sqlite数据库[2]。

    79f04567969537418b33ea0b64643574.png

    49bfe9edc500eb8a2e942c5288fc2435.png

    6b01df892baab9bedb6979137fb3e3f0.png

    目录

    1绪论    1

    1.1研究背景    1

    1.2研究目的及意义    1

    1.3国内外研究现状    1

    2需求分析    2

    2.1可行性分析    2

    2.2功能需求分析    2

    2.3性能需求分析    2

    2.4环境需求分析    3

    2.4.1开发环境需求    3

    2.4.2运行环境需求    3

    2.5 用例图    3

    3概要设计    5

    4详细设计    7

    4.1功能模块划分    7

    4.2各个类的用途说明    7

    4.3数据库设计    8

    5编码实现    9

    5.1 数据库连接类实现    9

    5.2 App启动界面的实现    9

    5.3 备忘录显示界面的实现    11

    5.4添加备忘录的实现    11

    5.5修改备忘录的实现    12

    5.6菜单的实现    12

    5.7设置闹钟的实现    12

    5.8关于界面的实现    13

    5.9备忘录详细界面的实现    14

    5.10播放闹铃的实现    15

    5.11广播接收类的实现    15

    6测试    16

    6.1 App启动模块    16

    6.1.1 UI测试    16

    6.1.2单项测试    16

    6.1.3 矩阵测试    17

    6.1.4 极限测试    17

    6.2备忘录显示模块    17

    6.2.1 UI测试    17

    6.2.2单项测试    18

    6.2.3矩阵测试    19

    6.2.4极限测试    20

    6.3添加删除修改模块    20

    6.3.1 UI测试    20

    6.3.2 单项测试    22

    6.3.3矩阵测试    23

    6.3.4极限测试    24

    6.4 菜单模块    25

    6.4.1 UI测试    25

    6.4.2 单项测试    25

    6.4.3 矩阵测试    26

    6.4.4极限测试    26

    6.5问题及处理    27

    6.5.1问题报告清单    27

    6.5.2 问题处理    27

    7总结与体会    29

    7.1项目开发与管理    29

    7.2开发技术    29

    7.3后期完善过程    30

    参考文献    32

    致谢    34

    展开全文
  • 本期小编给大家推荐一款受到广大用户喜爱的APP,名字叫《日期备忘录》。用户界面不仅专为 iPhone 设计,同时针对 iPad 的大尺寸屏幕进行专门的设计和优化。功能强大,操作简单,感兴趣的伙伴快来微侠下载使用吧!...

    本期小编给大家推荐一款受到广大用户喜爱的APP,名字叫《日期备忘录》。用户界面不仅专为 iPhone 设计,同时针对 iPad 的大尺寸屏幕进行专门的设计和优化。功能强大,操作简单,感兴趣的伙伴快来微侠下载使用吧!

    c6f30273fa863d950b2d8d32aa832ed9.png

    日期备忘录软件

    “日期备忘录”可以帮助您记录重要的事件并提醒您。

    软件特色

    - 使用原生框架设计和开发,为您带来流畅的使用体验。

    - 用户界面不仅专为 iPhone 设计,同时针对 iPad 的大尺寸屏幕进行专门的设计和优化。

    - 支持深色模式。

    - 包含分组、重复、纪念日、收藏等强大易用的功能。

    - 支持自定义事件的提醒日期及时间。

    - 支持小组件,并可以将重要的事件在小组件中置顶。

    - 使用 iCloud 在多设备之间自动同步数据。

    - 支持 iMessage 信息 App,可以将记录的事件作为贴纸分享给其他人。

    更新内容

    - 支持将事件以图像的形式进行分享

    - 支持通过长按主屏幕图标快速新建事件或分组

    - 多种用户界面改进

    相关说明

    基于日期的备忘提醒工具,非常适合那些经常忘记一些特殊日期的朋友,通过周期提醒以及倒计时的方式,直接通过小组件放到屏幕上,每每解锁手机就能从屏幕上看到日期,让人不记住都不行。

    展开全文
  • 备忘录Android开发

    2019-03-03 20:30:56
    安卓开发,智能移动终端,可以直接放入eclipse或者androidstudio运行!
  • Android:实现安卓小程序-记事本(备忘录)的开发

    万次阅读 多人点赞 2019-05-28 00:27:55
    本文目录1. 前言2. 记事本功能需求3. 部分关键代码解析及程序截图3.1...在学习安卓开发这门课程中期,学会了安卓开发的基本知识,比如,UI组件的应用,Intent的应用等等,同时期中作业为编写一个记事本程序,基于goo...

    1. 前言

    在学习安卓开发这门课程中期,学会了安卓开发的基本知识,比如,UI组件的应用,Intent的应用等等,同时期中作业为编写一个记事本程序,基于google的记事本demo, 但对于我本人来说,我更喜欢对代码从头到位都有自己的参与,于是我决定自己从头编写一个基本记事本的开发和记事本的相关扩展功能。

    开发环境: Android Studio (API25以上)

    2. 记事本功能需求

    功能名称 功能概述 优先级
    记事本基本功能 对记事本的增删改 最高
    时间戳显示 记事本的最近编辑时间的显示
    高级搜索 对记事本的查找
    UI美化 对用户界面的美化
    记事本背景色的设置 记事本背景色的设置
    记事本闹钟设置 记事本的闹钟功能设置

    3. 部分关键代码解析及程序截图

    3.1 记事本类的基本设计

    Note.java

    //序列化便于本地存储
    public class Note  implements Serializable,Comparable{
    
        private String title;
        private String create_date;
        private String update_date;
        private String text;
        private String background;
        private String date_alarm;
        public Note(String title,String text) {
            //标题
            this.title = title;
            //创建日期
            this.create_date = new SimpleDateFormat("yyyy-MM-dd HH-mm").format(new Date());
            //更新日期
            this.update_date = this.create_date;
            //内容
            this.text = text;
            //背景色
            this.background = null;
            //闹钟日期
            this.date_alarm = "";
        }
    }
    

    3.2 记事本的数据存储设计

    这里由于我当时暂未学习到SQLite的数据存储方式,采用了文件读写的方式来存储记事本的条目。]
    首先,在AndroidManifest.xml中设置允许程序读写文件的权限。

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.VIBRATE" />
    

    将Note存储在哈希表内,再将哈希表的内容写入文件中,同时文件存储在内置的SD卡的路径下。
    NoteManager.java

    public class NoteManager {
    
        private Context mContext;
        private List<Note> list;
        private String root_file;
        public NoteManager(Context context){
            root_file = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"NoteList";
            this.mContext = context;
            list = getNoteList();
        }
        
        //更新当前notes列表
        public void updateNoteList(List<Note> now_data){
            try {
                File file = new File(root_file);
                if (!file.exists()){
                    file.createNewFile();
                }
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(root_file));
                oos.writeObject(now_data);
                oos.close();
            }
            catch (Exception e1){
                e1.printStackTrace();
            }
        }
    }
    

    3.3 主界面的设计

    为了更好的用户体验,决定将用户设计设计成两种情况,一种为用户程序中暂无存储记事文件的情况下,一种为程序中已存有记事文件下。附上部分关键代码以及程序截图。

    主界面-1 主界面-2
    在这里插入图片描述 在这里插入图片描述
    //检查数据列表是否为空,如果为空,那么渲染blank_View
        public void emptyListCheck(){
            int number = 0;
            if(data!=null){
                number=data.size();
            }
            if(number == 0) {
                smlvMain.setVisibility(View.GONE);
                RelativeLayout empty = (RelativeLayout) findViewById(R.id.blank_view);
                empty.setVisibility(View.VISIBLE);
                fabMenu.setVisibility(View.VISIBLE);
            }else{
                smlvMain.setVisibility(View.VISIBLE);
                RelativeLayout empty = (RelativeLayout) findViewById(R.id.blank_view);
                empty.setVisibility(View.GONE);
            }
        }
    

    这里设置了Note条目的菜单模块和空白模块,若数据列表为空,则隐藏条目菜单模块,显示空白模块,若不为空,则隐藏空白模块,显示菜单模块。

    3.4 记事本的编辑

    可以看到在主界面的右下角存在一个浮动窗口菜单,这里涉及到第三方依赖的添加:
    com.getbase.floatingactionbutton.FloatingActionButton
    res/layout/activity_main.xml

    <com.getbase.floatingactionbutton.FloatingActionsMenu
                adroid:id="@+id/fab_menu"
                adroid:layout_width="wrap_content"
                adroid:layout_height="wrap_content"
                adroid:layout_alignParentRight="true"
                adroid:layout_alignParentBottom="true"
                fab:fab_labelStyle="@style/fab_label_style"
                app:fab_addButtonSize="mini"
                fab:fab_addButtonColorNormal="#5e96b9"
                fab:fab_addButtonColorPressed="@null"
                fab:fab_addButtonPlusIconColor="@color/black"
                adroid:layout_marginBottom="16dp"
                adroid:layout_marginRight="16dp">
    
                <com.getbase.floatingactionbutton.FloatingActionButton
                    adroid:id="@+id/fab_add"
                    adroid:layout_width="wrap_content"
                    adroid:layout_height="wrap_content"
                    fab:fab_colorNormal="@color/white"
                    fab:fab_colorPressed="@color/green"
                    fab:fab_title="新备忘录"
                    fab:fab_size="mini"
                    fab:fab_icon="@drawable/fab_add" />
                <com.getbase.floatingactionbutton.FloatingActionButton
                    adroid:id="@+id/fab_exit"
                    adroid:layout_width="wrap_content"
                    adroid:layout_height="wrap_content"
                    fab:fab_colorNormal="@color/white"
                    fab:fab_colorPressed="@color/green"
                    fab:fab_title="退出应用"
                    fab:fab_size="mini"
                    app:fab_icon="@drawable/fab_exit" />
    </com.getbase.floatingactionbutton.FloatingActionsMenu>
    

    这里可以看到对浮动菜单栏的xml设计,包含两种功能,新建Note和应用的退出,涉及到功能的逻辑代码这里就不赘述了。
    新建Note后,可在主界面-2下的点击Note条目或左滑条目进入编辑模式。

    编辑模式-1 编辑模式-2
    在这里插入图片描述 在这里插入图片描述

    同时可以注意到两者编辑模式略有不同,在编辑模式-1下,可以做到修改,删除,背景色的设置,闹铃的添加,在编辑模式-2下仅仅能做到修改和删除。
    左滑Note条目左滑部分关键代码:
    首先需要新建一个滑动view类

    public class MyScrollView extends ScrollView {
       private ScrollViewListener scrollViewListener = null;
    
        public MyScrollView(Context context) {
            super(context);
        }
    
        public MyScrollView(Context context, AttributeSet attrs,
                            int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public MyScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public void setOnScrollListener(ScrollViewListener scrollViewListener) {
            this.scrollViewListener = scrollViewListener;
        }
    
        @Override
        protected void onScrollChanged(int x, int y, int oldx, int oldy) {
            super.onScrollChanged(x, y, oldx, oldy);
            if (scrollViewListener != null) {
                if (oldy < y && ((y - oldy) > 15)) {
                    scrollViewListener.onScroll(y - oldy);
                } else if (oldy > y && (oldy - y) > 15) {
                    scrollViewListener.onScroll(y - oldy);
                }
            }
        }
    //这一部分参考了github某个开源项目
        public  interface ScrollViewListener{//dy Y轴滑动距离
            void onScroll(int dy);
        }
    }
    

    设置完毕后在xml文件中即可设置应用:

    <com.zc.memo.view.MyScrollView
                adroid:id="@+id/sv_main"
                adroid:layout_width="match_parent"
                adroid:layout_height="wrap_content"
                adroid:background="@drawable/border_bottom_null">
                <LinearLayout
                    adroid:layout_width="match_parent"
                    adroid:layout_height="wrap_content"
                    adroid:orientation="vertical">
                    <com.baoyz.swipemenulistview.SwipeMenuListView
                        adroid:id="@+id/smlv_main"
                        adroid:layout_width="match_parent"
                        adroid:layout_height="match_parent"
                        adroid:descendantFocusability="blocksDescendants"
                        adroid:divider="@color/little_gray"
                        adroid:dividerHeight="1dp"
                        adroid:background="@null"
                        />
                </LinearLayout>
    </com.zc.memo.view.MyScrollView>
    

    接着在activity中,初始化滑动窗口及滑动窗口菜单。

     private void initView() {
    
            data = new NoteManager(context).getNoteList();
            smlvMain.setAdapter(new NoteAdapter(context,data));
            smlvMain.setMenuCreator(new MySwipeMenuCreator(context));
            smlvMain.setSwipeDirection(SwipeMenuListView.DIRECTION_LEFT);
            new ListViewUtil().setListViewHeightBasedOnChildren(smlvMain);
            svMain.setOnScrollListener(new MyScrollView.ScrollViewListener() {
                @Override
                public void onScroll(int dy) {
                    if (dy > 0) {
                        //下滑
                        showOrHideFab(false);
                    } else if (dy <= 0 ) {
                        //上滑
                        showOrHideFab(true);
                    }
                }
            });
            viewListener();
            emptyListCheck();
        }
    

    这里仅放上如何初始化滑动窗口的view,关于监听这个滑动窗口的逻辑代码在这里就不赘述了。
    接下来讲一讲自定义NoteAdapter适配器来展示即使条目,首先继承BaseAdapter实现一个抽象类MyBaseAdapter该类可读取List列表的数据。

    public abstract class MyBaseAdapter<T> extends BaseAdapter {
        Context context;
        List<T> data;
    
        public MyBaseAdapter(Context context, List<T> data) {
            this.context = context;
            this.data = data;
        }
    
        @Override
        public Object getItem(int i) {
            return null;
        }
    
        @Override
        public long getItemId(int i) {
            return 0;
        }
        @Override
        public int getCount() {
            if(data==null) return 0;
            return data.size();
        }
    }
    

    接着在编写NoteAdapter类继承上类,初始化view, 将Note条目的各项信息展示出来,其中还自定义了一个viewHolder类,方便对xml文件中的各项组件进行绑定编辑。

    public class NoteAdapter extends MyBaseAdapter<Note> {
    
        public NoteAdapter(Context context, List<Note> data) {
            super(context, data);
        }
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            ViewHolder viewHolder;
            if(view==null){
                viewHolder=new ViewHolder();
                LayoutInflater inflater = LayoutInflater.from(context);
                view = inflater.inflate(R.layout.item_main_list, viewGroup, false);
                viewHolder.tv_lv_month = (TextView) view.findViewById(R.id.tv_lv_month);
                viewHolder.tv_lv_day= (TextView) view.findViewById(R.id.tv_lv_day);
                viewHolder.tv_lv_title = (TextView) view.findViewById(R.id.tv_lv_title);
                viewHolder.tv_lv_content = (TextView) view.findViewById(R.id.tv_lv_content);
                viewHolder.layout = (LinearLayout) view.findViewById(R.id.Linelayout);
                view.setTag(viewHolder);
            }
            else{
                viewHolder = (ViewHolder) view.getTag();
            }
            viewHolder.tv_lv_month.setText(data.get(i).getUpdate_date().split("-")[1]);
            viewHolder.tv_lv_day.setText(data.get(i).getUpdate_date().split("-")[2]);
            viewHolder.tv_lv_title.setText(data.get(i).getTitle());
            viewHolder.tv_lv_content.setText(data.get(i).getText());
    
            if(data.get(i).getBackground()!=null){
                viewHolder.layout.setBackgroundColor(Color.parseColor(data.get(i).getBackground()));
            }
            return view;
        }
    
        class ViewHolder{
            TextView tv_lv_month;
            TextView tv_lv_day;
            TextView tv_lv_title;
            TextView tv_lv_content;
            LinearLayout layout;
        }
    }
    
    
    

    3.5 记事本的背景色设置

    进入到上述提到的编辑模式2中,也就是ContentActivity中,在其底部设置更改背景色功能。这里运用到了会话框的弹出AlertDialog。设置三种颜色。点击确认后,更改数据文件中相应记事条目Note的Background属性。接着进行调用onResume();使其重新载入数据文件中的记事条目得到背景色的更改。功能截图如下:

    背景选项 设置成功
    在这里插入图片描述 在这里插入图片描述

    部分关键代码如下:

    ivSettings.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(ContentActivity.this);
                    builder.setIcon(R.drawable.fab_settings);
                    builder.setTitle("选择一个背景色");
                    //    指定下拉列表的显示数据
                    final String[] colors = {"护眼色", "薰衣淡紫", "粉粉粉"};
                    builder.setItems(colors, new DialogInterface.OnClickListener()
                    {
                        @Override
                        public void onClick(DialogInterface dialog, int which)
                        {
                            Toast.makeText(ContentActivity.this, "选择的背景色为:" + colors[which], Toast.LENGTH_SHORT).show();
                            switch (which){
                                case 0:
                                    new NoteManager(mContext).updateBackground(title,"#C7EDCC");
                                    onResume();
                                    break;
                                case 1:
                                    new NoteManager(mContext).updateBackground(title,"#E6E6FA");
                                    onResume();
                                    break;
                                case 2:
                                    new NoteManager(mContext).updateBackground(title,"#FC9D9A");
                                    onResume();
                                    break;
                                default:
                                    break;
                            }
    
                        }
                    });
                    builder.show();
                }
            });
    

    3.6 记事本的闹铃功能

    该功能的实现思路为,为闹钟设置闹铃后,在该记事条目对应得ContentActvity的右上角会显示闹铃的时间,长按该闹铃时间戳则可删除该闹铃,同时闹铃到达指定时间后,会在程序中弹出提示框并且在手机通知栏也会有消息提醒。功能截图如下:

    设置闹钟 闹钟设置完成 通知栏响应
    在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

    首先是闹铃时间的设定,这里要对ContentActivity实现相应的设置日期时间的接口。

    public class ContentActivity extends AppCompatActivity
            implements DatePickerDialog.OnDateSetListener, TimePickerDialog.OnTimeSetListener{
    
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            alarm_year=year;
            alarm_month=monthOfYear+1;
            alarm_day=dayOfMonth;
        }
    
        @Override
        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
            alarm_hour=hourOfDay;
            alarm_minute=minute;
    
            alarm=alarm_year+"/"+alarm_month+"/"+alarm_day+" "+alarm_hour+":"+alarm_minute;
            av.setText("Alert at "+alarm+"!");
            av.setVisibility(View.VISIBLE);
    
            Log.d("ContentActivity","alarm"+alarm);
            new NoteManager(mContext).updateAlarm(title,alarm);
            loadAlarm(alarm, title, 0);
            Toast.makeText(this,"Alarm will be on at "+alarm+" !",Toast.LENGTH_LONG).show();
        }
    }
    

    接着就是开始设置闹铃:

    public void setAlarm(View v) {
            if(alarm.length()<=1) {
                //if no alarm clock has been set up before
                //show the current time
                Calendar c=Calendar.getInstance();
                alarm_hour=c.get(Calendar.HOUR_OF_DAY);
                alarm_minute=c.get(Calendar.MINUTE);
    
                alarm_year=c.get(Calendar.YEAR);
                alarm_month=c.get(Calendar.MONTH)+1;
                alarm_day=c.get(Calendar.DAY_OF_MONTH);
            }
            else {
                //show the alarm clock time which has been set up before
                int i=0, k=0;
                while(i<alarm.length()&&alarm.charAt(i)!='/') i++;
                alarm_year=Integer.parseInt(alarm.substring(k,i));
                k=i+1;i++;
                while(i<alarm.length()&&alarm.charAt(i)!='/') i++;
                alarm_month=Integer.parseInt(alarm.substring(k,i));
                k=i+1;i++;
                while(i<alarm.length()&&alarm.charAt(i)!=' ') i++;
                alarm_day=Integer.parseInt(alarm.substring(k,i));
                k=i+1;i++;
                while(i<alarm.length()&&alarm.charAt(i)!=':') i++;
                alarm_hour=Integer.parseInt(alarm.substring(k,i));
                k=i+1;i++;
                alarm_minute=Integer.parseInt(alarm.substring(k));
            }
    
            new TimePickerDialog(this,this,alarm_hour,alarm_minute,true).show();
            new DatePickerDialog(this,this,alarm_year,alarm_month-1,alarm_day).show();
        }
    

    同样的,监听该view,若被响应则调用onResume();
    长按删除闹铃功能这里就不再赘述了,接下来来详细讲解如何调用通知栏的通知功能。部分关键代码:

    private void loadAlarm(String alarm, String title, int days) {
            int alarm_hour=0;
            int alarm_minute=0;
            int alarm_year=0;
            int alarm_month=0;
            int alarm_day=0;
    
            int i=0, k=0;
            while(i<alarm.length()&&alarm.charAt(i)!='/') i++;
            alarm_year=Integer.parseInt(alarm.substring(k,i));
            k=i+1;i++;
            while(i<alarm.length()&&alarm.charAt(i)!='/') i++;
            alarm_month=Integer.parseInt(alarm.substring(k,i));
            k=i+1;i++;
            while(i<alarm.length()&&alarm.charAt(i)!=' ') i++;
            alarm_day=Integer.parseInt(alarm.substring(k,i));
            k=i+1;i++;
            while(i<alarm.length()&&alarm.charAt(i)!=':') i++;
            alarm_hour=Integer.parseInt(alarm.substring(k,i));
            k=i+1;i++;
            alarm_minute=Integer.parseInt(alarm.substring(k));
    
            Intent intent = new Intent(ContentActivity.this, OneShotAlarm.class);
            intent.putExtra("alarm_title",title);
            PendingIntent sender = PendingIntent.getBroadcast(
                    ContentActivity.this, 0, intent, 0);
    
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
    
            Calendar alarm_time = Calendar.getInstance();
            alarm_time.set(alarm_year,alarm_month-1,alarm_day,alarm_hour,alarm_minute);
    
            AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
            am.set(AlarmManager.RTC_WAKEUP, alarm_time.getTimeInMillis(), sender);
        }
    

    在上述关键代码中,可以看到在loadAlarm函数中使用了Intent来传递闹铃时间的消息给OneShotAlarm类,且是再闹铃设置完成后,构建一个PendingIntent广播,通过AlarmManager在时间到达指定的闹铃事件后,发出广播,接收到广播的OneShotAlarm类做出回应,在通知栏显示通知。
    这里要先在AndroidManifest.xml设置广播接收器:

    <receiver
                android:name=".utils.OneShotAlarm"
                android:process=":remote" />
    

    接下来让我们看看OneShortAlarm类,当OneShotAlarm收到广播后,则构建通知消息并在通知栏显示。同时该类中设置了通知消息显示的内容,有该记事本程序名,记事条目的标题,该记事创建时间戳以及记事内容。通过构造Notification类实现该消息。部分关键代码如下:

    public class OneShotAlarm extends BroadcastReceiver {
        private String alarm_title;
        @Override
        public void onReceive(Context context, Intent intent) {
            alarm_title=intent.getStringExtra("alarm_title");
            Toast.makeText(context,"Time UP!",Toast.LENGTH_LONG).show();
            Vibrator vb =(Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
            vb.vibrate(300);
    
            showNotice(context);
        }
        private void showNotice(Context context) {
    
            Intent intent=new Intent(context,ContentActivity.class);
            Note record = new NoteManager(context).get(alarm_title);
            new NoteManager(context).deleteAlarm(alarm_title);
            PendingIntent pi=PendingIntent.getActivity(context,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
            NotificationManager manager=(NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
            Notification notification=new NotificationCompat.Builder(context)
                    .setContentTitle(record.getCreate_date())
                    .setContentText(record.getText())
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.drawable.icon))
                    .setContentIntent(pi)
                    .setAutoCancel(true)
                    //.setStyle(new NotificationCompat.BigTextStyle().bigText(record.getMainText()))
                    .setLights(Color.GREEN,1000,1000)
                    .build();
            manager.notify(0,notification);
        }
    }
    

    3.7 高级搜索

    在早先就有了解到一些动态搜索框现成的源码,这里则使用了一些网上开源的搜索框控件的使用。
    首先需要添加第三方依赖,'com.quinny898.library.persistentsearch:library:1.1.0-SNAPSHOT’就可以使用了。该搜索框还支持语音输入识别,但这里因为在设计时并没有考虑语音识别功能,所以这里就弃用了该功能。
    附上功能截图:
    在这里插入图片描述

    <com.quinny898.library.persistentsearch.SearchBox
            android:layout_width="wrap_content"
            android:id="@+id/searchbox"
            android:layout_height="wrap_content"/>
    

    设置完成后,需要对显示搜索到的记事条目,内容,及搜索到的记事条目总和进行显示,这里布局设计如下:

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <ListView
                android:id="@+id/history_lis_search"
                android:layout_marginLeft="20dp"
                android:layout_marginRight="20dp"
                android:layout_marginBottom="5dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/border_bottom_null">
            </ListView>
        </LinearLayout>
    
        <ListView
            android:id="@+id/content_lis_search"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/border_bottom_null">
        </ListView>
    
        <TextView
            android:id="@+id/bottom_search"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center_horizontal" />
    
    

    接着则是代码的实现,实现该功能代码网上有很多现成的实例,这里实现起来并没有看起来的那么复杂,稍微学习后则可写出自己想要的代码:

    public class SearchActivity extends AppCompatActivity {
        private Context mContext;
        private SearchBox sbSearch;
        private TextView tvBottom;
        //数据列表
        private List<Note> listSearch;
        //结果列表
        private List<Note> listResult;
        private ListView mSearchResult ;
        private SearchAdapter mResultAdapter ;
    
        private ListView mHistory ;
        private HistoryAdapter mHistoryAdapter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_search);
            mContext = this;
            bindViews();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            initData();
            init();
            initSearchView();
            initHistory();
            updateBottom();
        }
    
        private void initData() {
            //本地可供检索数据获取,每次resume就要重新渲染
            listSearch = new NoteManager(mContext).getNoteList();
        }
    
        private void bindViews() {
            mSearchResult = (ListView) findViewById(R.id.content_lis_search);
            sbSearch = (SearchBox) findViewById(R.id.searchbox);
            tvBottom = (TextView) findViewById(R.id.bottom_search);
            mHistory = (ListView) findViewById(R.id.history_lis_search);
        }
    
        public void init(){
            listResult = new ArrayList<>();
            mResultAdapter = new SearchAdapter(SearchActivity.this, listResult);
            mSearchResult.setAdapter(mResultAdapter);
            mSearchResult.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    manageKeyBoard();
                    NoteManager noteManager=new NoteManager(mContext);
                    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                    boolean isOpen = imm.isActive();
                    if (isOpen) imm.hideSoftInputFromWindow(view.getWindowToken(), 0); //强制隐藏键盘
                    noteManager.ItemClick(listResult.get(position));
                }
            });
        }
    
        private void initSearchView(){
            sbSearch.enableVoiceRecognition(this);
            sbSearch.setMenuListener(new SearchBox.MenuListener(){
                @Override
                public void onMenuClick() {
                    reBack();
                }
            });
            sbSearch.setSearchListener(new SearchBox.SearchListener(){
    
                @Override
                public void onSearchOpened() {
                    //Use this to tint the screen
                }
                @Override
                public void onSearchClosed() {
                    //Use this to un-tint the screen
                }
                @Override
                public void onSearchTermChanged(String term) {
                    search(term);
                    updateBottom();
    
                    if(listResult.size()==0){
                        mHistory.setVisibility(View.VISIBLE);
                    }else {
                        mHistory.setVisibility(View.GONE);
                    }
                }
                @Override
                public void onSearch(String searchTerm) {
                    search(searchTerm);
                    saveHistory(searchTerm);
                    initHistory();
                    updateBottom();
                }
                @Override
                public void onResultClick(SearchResult result) {
                    //React to a result being clicked
                }
                @Override
                public void onSearchCleared() {
                    //Called when the clear button is clicked
                }
    
            });
        }
    
        private void initHistory(){
    
            final List<String> history = getHistory();
            mHistoryAdapter = new HistoryAdapter(SearchActivity.this,history);
            mHistory.setAdapter(mHistoryAdapter);
            mHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    sbSearch.populateEditText(history.get(position));
                    sbSearch.setSearchString(history.get(position));
                }
            });
    
        }
    
        private void search(String newText){
    
            //若搜索内容为空
            if(newText.isEmpty()){
                listResult.clear();
            }
            else{
    
                for (Note note : listSearch) {//开始搜索
                    //搜索内容搜索到相关
                    if (note.getTitle().contains(newText) || note.getText().contains(newText)) {
    
                        if(listResult.indexOf(note)==-1) {//且 结果集内不含有此内容
                            listResult.add(note);
                        }
                    }else{
                        //搜索内容搜索不到相关 检测是否之前有加入结果集 有则删除
                        if(listResult.indexOf(note)!=-1) {
                            listResult.remove(note);
                        }
                    }
                }
            }
            mResultAdapter.notifyDataSetChanged();
        }
    
        private ArrayList<String> getHistory() {
            SharedPreferences reader = getSharedPreferences("history", MODE_PRIVATE);
            String data = reader.getString("data_history", "");
            ArrayList<String> history = new ArrayList<>();
            String [] get=  data.split("\\|");
            for( String str:get){
                if(! history.contains(str) && !StringUtil.isEmpty(str)){
                    history.add(str);
                }
            }
            return history;
        }
    
        private void saveHistory(String s){
            StringBuilder sb = new StringBuilder();
            SharedPreferences.Editor editor = getSharedPreferences("history",MODE_PRIVATE).edit();
            for (String str: getHistory()){
                sb.append(str);
                sb.append("|");
            }
            sb.append(s);
            editor.putString("data_history",sb.toString());
            editor.apply();
        }
    
        private void updateBottom(){
            if(sbSearch.getSearchText().trim().isEmpty()){
                gone_Bottom();
                return;
            }
            tvBottom.setVisibility(View.VISIBLE);
            tvBottom.setText("找到了 "+ listResult.size() +" 条记录");
    
        }
        private void gone_Bottom(){
            TextView bottom = (TextView) findViewById(R.id.bottom_search);
            bottom.setVisibility(View.GONE);
        }
    
        private void reBack(){
            finish();
            overridePendingTransition(R.anim.in_from_left, R.anim.out_from_right);
        }
    
        @Override
        public boolean onKeyUp(int keyCode, KeyEvent event) {
            switch(keyCode){
                case KeyEvent.KEYCODE_BACK:
                    finish();
                    overridePendingTransition(R.anim.in_from_left, R.anim.out_from_right);
                    break;
            }
            return super.onKeyUp(keyCode, event);
        }
        private void manageKeyBoard() {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }
    
    

    4. 总结

    这次完成该记事本的完成算是对先前学到知识的应用以及进阶,如Intent意图的使用,adapter适配器的使用,等等,对其掌握有了更进一步的提高,同时对程序UI美化和程序数据存储有了全新的了解与把握。也了解到市面上有很多开源的控件可供使用,还需要学习的东西还有很多很多。谢谢。

    参考资料:
    https://blog.csdn.net/zhouchen1998/article/details/83628218
    https://blog.csdn.net/sf_zhang26/article/details/54803691
    https://blog.csdn.net/zhouchen1998/article/details/82995526
    本文作者:林嘉伟
    原文链接

    展开全文
  • iOS是美国苹果公司所开发的手机操作系统,现在已经更新到了iOS14.1版本,新版本更新之后,如果在使用备忘录的时候,不小心误删了内容,怎样做可以恢复呢?iPhone手机上可以恢复误删内容的iOS系统便签软件是什么?在...
  • 有没有一款功能强大的带有日历提醒的手机便签备忘录软件?1、下载个手机版敬业签APP,你可以从手机应用市场搜索“敬业签”手机版下载;下载完打开注册登录账号,点击底部“+”符号;2、输入斋日提醒便签内容,点击...
  • 安卓小项目实战之--定时提醒备忘录

    千次阅读 2015-05-18 23:30:06
    写在前面: 安卓的学习也有半年多了,期间也曾写过博客,但大多都是一些琐碎的笔记,... 本次项目选择了可定时提示的备忘录。原理是利用系统每分钟发送一条时间改变的广播,通过接受这条广播来判断是否为用户设置的时
  • 1.XML文件中 需要一个文本框和输入框(输入你要存放的数据) 而且需要在对应JAVA文件中获取控件,这里只提出一下不写了,主要因为都是基础代码,贴出来浪费时间。 主要是只贴出关键代码,设置了3个按钮分别是实现写入,...
  • 备忘录

    2014-10-13 13:42:07
    一直都想把自己写过的安卓开发小程序整理一下,做成文档,但是一直没有机会,刚好,最近都不是很忙,于是今天就将之前花了好几天才完成的备忘录整理下,跟大家分享分享。要完成这个程序,主要从以下几步入手: 1、...

空空如也

空空如也

1 2 3 4
收藏数 70
精华内容 28
关键字:

安卓备忘录开发