首页 > 学院 > 开发设计 > 正文

利用MVC编程模式-开发一个简易记事本app

2019-11-15 00:07:02
字体:
来源:转载
供稿:网友
利用MVC编程模式-开发一个简易记事本app

  学了极客学院一个开发记事本的课程,利用自己对MVC编程模式的简单理解重写了一遍该app。

  github地址:https://github.com/morningsky/MyNote

MVC即,模型(model)-视图(view)-控制器(controller),有效的实现了数据-业务逻辑-视图显示的代码分离,使得加入新功能时不需要重新编写业务逻辑,大大提高了代码的可维护性。

  

  

   在这个案列中,一开始只是开发了添加文字内容的记事功能,添加图片功能时在activity文件中写入imageview的逻辑 在数据库中加入图片路径数据 在视图中加一个imageview的。后期若再添加视频功能可参照之前添加图片的操作快速实现app的升级。整个代码编写过程脉络清晰,加上Android Studio的帅气主题,开发过程感觉极好。

  

下面是整个app的开发流程:

/*步骤: 1.model构建   1.1创建数据库 NoteDB类   1.2创建自定义的adapter MyAdapter类     1.2.1构造函数     1.2.2复写4个子类方法 注意getView方法

2.创建视图   2.1布局主界面 两个按钮 一个listview activity_main.xml   2.2 listview每一条数据的视图格式 图片imageview 内容textview 时间textview cell.xml   2.3添加内容界面 imageview editext 两个Button addcontent.xml   2.4创建详情页视图 与addcontent视图相似 将Editext转换为Textview Button的内容由返回变成删除 incontent.xml

3.逻辑实现   MainActivity:     3.1初始化主界面布局 定义initView方法 给按钮设置监听     3.7在MainActivity实例化一个SQLiteDatabase 获取读取权限 用于加载listview的内容     3.8添加查询数据方法selectDB 并在该方法中加载MyAdapter   

  AddContent:     3.2创建添加内容界面的activity 并在AndroidManifest文件中注册该activity 两个activity添加固定竖屏参数     3.3初始化AddContent界面布局 定义initView方法 给按钮设置监听 实例化SQLiteDatabase 获取写入数据权限     3.4添加addDB方法获取内容 时间并写入数据库     3.5添加getTime方法获取系统当前时间     3.6为按钮添加事件     3.9增加根据添加文字还是图文加载不同界面的initView逻辑     4.0添加Intent调用系统相机 实例化一个File存放照片路径     4.1复写onActivityResult来查看照片效果     4.2add函数添加图片路径

  MyAdapter:     4.3添加查看缩略图函数getImageThumbnail listview中显示     4.5添加用来查询的String path 储存地址

  InContent:     4.6添加详情页Activity 并注册     4.7给listview添加监听事件 跳转到详情页 并传入部分数据     4.8根据图文还是文字加载不同视图 显示文字 图片信息     4.9实例化一个SQLiteDatabase 获取写入数据权限 用来删除数据     5.0添加删除数据方法delDB 给按钮加上方法 */

  

  model层:

    NoteDB.java 创建了一个数据库 用来存放记事内容 记事时间 图片路径

    

 1 package com.bluesky.mynote; 2  3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteOpenHelper; 6  7 /** 8  * Created by 清晨 on 2015/5/6. 9  */10 public class NoteDB extends SQLiteOpenHelper {11 12     public static final String TABLE_NAME="notes";//表名13     public static final String CONTENT="content";//内容14     public static final String ID="id";         //标识每一条数据15     public static final String TIME="time";    //存放添加数据时的时间16     public static final String PATH="path";   //路径,用来存放照片路径17 18     //构造函数参数保留一个Content即可19     public NoteDB(Context context) {20         super(context, "notes", null, 1);21     }22 23     //注意属性内的空格 " TEXT NOT NULL,"第一个引号后的空格不能省略 否则名称会变为contentTEXT24     @Override25     public void onCreate(SQLiteDatabase db) {26         db.execSQL("CREATE TABLE " + TABLE_NAME + " ("27                 + ID+ " INTEGER PRIMARY KEY AUTOINCREMENT,"28                 + CONTENT+" TEXT NOT NULL,"29                 + PATH +" TEXT NOT NULL,"30                 + TIME +" TEXT NOT NULL)");31     }32 33     //不需要更新34     @Override35     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {36 37     }38 }

  MyAdapter.java 用来设定主界面listview的内容格式

 1 package com.bluesky.mynote; 2  3 import android.content.Context; 4 import android.database.Cursor; 5 import android.graphics.Bitmap; 6 import android.graphics.BitmapFactory; 7 import android.media.ThumbnailUtils; 8 import android.view.LayoutInflater; 9 import android.view.View;10 import android.view.ViewGroup;11 import android.widget.BaseAdapter;12 import android.widget.ImageView;13 import android.widget.LinearLayout;14 import android.widget.TextView;15 16 /**17  * Created by 清晨 on 2015/5/7.18  */19 public class MyAdapter extends BaseAdapter {20     private Context mContext;21     private Cursor mCursor;22     private LinearLayout layout;23 24     public MyAdapter(Context context,Cursor cursor){25         mContext=context;26         mCursor=cursor;27     }28     @Override29     public int getCount() {30         return mCursor.getCount();31     }32 33     @Override34     public Object getItem(int position) {35         return mCursor.getPosition();36     }37 38     @Override39     public long getItemId(int position) {40         return position;41     }42 43     @Override44     public View getView(int position, View convertView, ViewGroup parent) {45         LayoutInflater inflater=LayoutInflater.from(mContext);//加载视图权限46         layout= (LinearLayout) inflater.inflate(R.layout.cell,null);//加载视图47         //初始化控件48         TextView content_tv= (TextView) layout.findViewById(R.id.list_content);49         TextView time_tv= (TextView) layout.findViewById(R.id.list_time);50         ImageView img_iv= (ImageView) layout.findViewById(R.id.list_img);51         //查询mCursor 用String获取查询内容52         mCursor.moveToPosition(position);53         String content=mCursor.getString(mCursor.getColumnIndex("content"));54         String time=mCursor.getString(mCursor.getColumnIndex("time"));55         String url=mCursor.getString(mCursor.getColumnIndex("path"));56         content_tv.setText(content);57         time_tv.setText(time);58         img_iv.setImageBitmap(getImageThumbnail(url,200,200));59         return layout;60     }61 62     //获取缩略图63     public Bitmap getImageThumbnail(String uri,int width,int height){64         Bitmap bitmap=null;65         BitmapFactory.Options options=new BitmapFactory.Options();66         options.inJustDecodeBounds=true;67         bitmap=BitmapFactory.decodeFile(uri,options);68         options.inJustDecodeBounds=false;69         int beWidth=options.outWidth/width;70         int beHeight=options.outHeight/height;71         int be=1;72         //防止图片超出过大或过小不予缩小73         if(beWidth<beHeight){74             be=beWidth;75         }else {76             be=beHeight;77         }78         if(be<=0){79             be=1;80         }81         options.inSampleSize=be;82         bitmap=BitmapFactory.decodeFile(uri,options);83         bitmap=ThumbnailUtils.extractThumbnail(bitmap,width,height,ThumbnailUtils.OPTIONS_RECYCLE_INPUT);84         return bitmap;85     }86 }

  视图层(View):

分别是主界面 activity_main.xml 添加内容addcontent.xml 内容详情页incontent.xml

内容详情页与添加内容界面 基本相似 所以可实现代码的简单修改 将编辑框改为文本框 再修改相应ID即可

接下来是核心部分

  控制器(Controler):

    主activity:

 1 package com.bluesky.mynote; 2 import android.content.Intent; 3 import android.database.Cursor; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.support.v7.app.ActionBarActivity; 6 import android.os.Bundle; 7 import android.view.View; 8 import android.widget.AdapterView; 9 import android.widget.Button;10 import android.widget.ListView;11 12 13 public class MainActivity extends ActionBarActivity implements View.OnClickListener {14     private Button text_btn, img_btn;15     private ListView lv;16     private Intent i;17     private MyAdapter adapter;18     private NoteDB noteDB;19     private SQLiteDatabase dbReader;20     private Cursor cursor;21 22     @Override23     protected void onCreate(Bundle savedInstanceState) {24         super.onCreate(savedInstanceState);25         setContentView(R.layout.activity_main);26         initView();27         //给按钮加入监听事件28         text_btn.setOnClickListener(this);29         img_btn.setOnClickListener(this);30         noteDB = new NoteDB(this);31         //获取读取权限 用于加载listview的内容32         dbReader = noteDB.getReadableDatabase();33         lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {34             @Override35             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {36                 cursor.moveToPosition(position);//游标挪到了position的位置上37                 Intent i=new Intent(MainActivity.this,InContent.class);38                 i.putExtra(NoteDB.ID,cursor.getInt(cursor.getColumnIndex(NoteDB.ID)));//以便根据ID删除数据39                 i.putExtra(NoteDB.CONTENT,cursor.getString(cursor.getColumnIndex(NoteDB.CONTENT)));40                 i.putExtra(NoteDB.TIME,cursor.getString(cursor.getColumnIndex(NoteDB.TIME)));41                 i.putExtra(NoteDB.PATH,cursor.getString(cursor.getColumnIndex(NoteDB.PATH)));42                 startActivity(i);43             }44         });45 46     }47 48     //初始化控件49     public void initView() {50         lv = (ListView) findViewById(R.id.list);51         text_btn = (Button) findViewById(R.id.text);52         img_btn = (Button) findViewById(R.id.image);53     }54 55     //查询数据56     public void selectDB() {57         cursor = dbReader.query(NoteDB.TABLE_NAME,null,null,null,null,null,null,null);58         adapter = new MyAdapter(this,cursor);59         lv.setAdapter(adapter);60     }61 62     @Override63     public void onClick(View v) {64         i = new Intent(this, AddContent.class);65         switch (v.getId()) {66             case R.id.text:67                 i.putExtra("flag", "1");68                 startActivity(i);69                 break;70             case R.id.image:71                 i.putExtra("flag", "2");72                 startActivity(i);73                 break;74         }75     }76 77     @Override78     protected void onResume() {79         super.onResume();80         selectDB();81     }82 }

添加内容 activity

  

  1 package com.bluesky.mynote;  2   3 import android.app.Activity;  4 import android.content.ContentValues;  5 import android.content.DialogInterface;  6 import android.content.Intent;  7 import android.database.sqlite.SQLiteDatabase;  8 import android.graphics.Bitmap;  9 import android.graphics.BitmapFactory; 10 import android.net.Uri; 11 import android.os.Bundle; 12 import android.os.Environment; 13 import android.os.PersistableBundle; 14 import android.provider.MediaStore; 15 import android.util.Log; 16 import android.view.Menu; 17 import android.view.View; 18 import android.widget.Button; 19 import android.widget.EditText; 20 import android.widget.ImageView; 21 import android.widget.VideoView; 22  23 import java.io.File; 24 import java.text.SimpleDateFormat; 25 import java.util.Date; 26  27 /** 28  * Created by 清晨 on 2015/5/6. 29  */ 30 public class AddContent extends Activity implements View.OnClickListener { 31     private NoteDB noteDB; 32     private SQLiteDatabase dbWriter; 33     private String flag; //接受从mainactivity传来的标识 用于判定加载不同的添加内容界面(图文或者纯文字) 34     private EditText editText; 35     private Button save_btn,cancel_btn; 36     private ImageView c_img; 37     private File imgfile; 38     @Override 39     public void onCreate(Bundle savedInstanceState) { 40         super.onCreate(savedInstanceState); 41         setContentView(R.layout.addcontent); 42         flag=getIntent().getStringExtra("flag"); 43         initView(); 44         save_btn.setOnClickListener(this); 45         cancel_btn.setOnClickListener(this); 46         noteDB=new NoteDB(this); 47         dbWriter=noteDB.getWritableDatabase();//获取写入数据库权限 48     } 49  50     //初始化控件 51     public void initView(){ 52         editText= (EditText) findViewById(R.id.ettext); 53         save_btn= (Button) findViewById(R.id.save); 54         cancel_btn= (Button) findViewById(R.id.cancel); 55         c_img= (ImageView) findViewById(R.id.c_img); 56         if(flag.equals("1")){ 57             c_img.setVisibility(View.GONE);//隐藏imageview 58         } 59         if(flag.equals("2")){ 60             c_img.setVisibility(View.VISIBLE);//显示imageview 61             //启动系统相机拍照 62             Intent getImg=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 63             //图片是放在存储卡中 路径存在数据库中 以时间命名图片 避免重名 64             imgfile=new File(Environment.getExternalStorageDirectory() 65                     .getAbsolutePath()+"/"+getTime()+".jpg"); 66             getImg.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imgfile)); 67             startActivityForResult(getImg,1);//便于立即查看效果 68  69  70         } 71     } 72  73     //获取内容并写入数据库 74     public void addDB(){ 75         ContentValues cv=new ContentValues(); 76         cv.put(NoteDB.CONTENT,editText.getText().toString()); 77         cv.put(NoteDB.TIME,getTime()); 78         cv.put(NoteDB.PATH,imgfile + ""); 79         dbWriter.insert(NoteDB.TABLE_NAME,null,cv); 80     } 81  82     //获取系统当前时间 83     public String getTime(){ 84         SimpleDateFormat format=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); 85         Date curDate=new Date(); 86         String str=format.format(curDate); 87         return str; 88     } 89  90     @Override 91     public void onClick(View v) { 92         switch (v.getId()){ 93             case R.id.save: 94                 addDB(); 95                 finish(); 96                 break; 97             case R.id.cancel: 98                 finish(); 99                 break;100 101         }102 103     }104 105     //预览显示拍摄内容106     @Override107     protected void onActivityResult(int requestCode, int resultCode, Intent data) {108         super.onActivityResult(requestCode, resultCode, data);109         if(resultCode==1){110             Bitmap bitmap= BitmapFactory.decodeFile(imgfile.getAbsolutePath());111             c_img.setImageBitmap(bitmap);112         }113     }114 }

内容详情页Activity

 1 package com.bluesky.mynote; 2  3 import android.app.Activity; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.graphics.Bitmap; 6 import android.graphics.BitmapFactory; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.widget.Button;10 import android.widget.ImageView;11 import android.widget.TextView;12 13 /**14  * Created by 清晨 on 2015/5/8.15  */16 public class InContent extends Activity implements View.OnClickListener {17     private Button del_btn;18     private Button back_btn;19     private ImageView in_img;20     private TextView in_tv;21     private NoteDB noteDB;22     private SQLiteDatabase dbWriter;23     @Override24     protected void onCreate(Bundle savedInstanceState) {25         super.onCreate(savedInstanceState);26         setContentView(R.layout.incontent);27         initView();28         noteDB= new NoteDB(this);29         dbWriter=noteDB.getWritableDatabase();30         del_btn.setOnClickListener(this);31         back_btn.setOnClickListener(this);32         //根据记事方式加载不同视图33         if(getIntent().getStringExtra(NoteDB.PATH).equals("null")){34             in_img.setVisibility(View.GONE);35         }else {36             in_img.setVisibility(View.VISIBLE);37         }38         //显示文字39         in_tv.setText(getIntent().getStringExtra(NoteDB.CONTENT));40         //显示图片41         Bitmap bitmap= BitmapFactory.decodeFile(getIntent().getStringExtra(NoteDB.PATH));42         in_img.setImageBitmap(bitmap);43     }44 45     public void initView(){46         del_btn= (Button) findViewById(R.id.delete);47         back_btn= (Button) findViewById(R.id.back);48         in_img= (ImageView) findViewById(R.id.in_img);49         in_tv= (TextView) findViewById(R.id.in_tv);50     }51 52     @Override53     public void onClick(View v) {54         switch (v.getId()){55             case R.id.delete:56                 delDB();57                 finish();58                 break;59             case R.id.back:60                 finish();61                 break;62         }63     }64     //删除数据65     public void delDB(){66         dbWriter.delete(NoteDB.TABLE_NAME,"id="+getIntent()67                 .getIntExtra(NoteDB.ID,0),null);68     }69 }

  新人一枚,初学安卓,也初次尝试着写博客,暂且把这一路的code time记下来吧.


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表