转载

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

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

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

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

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

在这个案列中,一开始只是开发了添加文字内容的记事功能,添加图片功能时在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,"第一个引号后的空格不能省略 否则名称会变为contentTEXT 24     @Override 25     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     @Override 35     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     @Override 29     public int getCount() { 30         return mCursor.getCount(); 31     } 32  33     @Override 34     public Object getItem(int position) { 35         return mCursor.getPosition(); 36     } 37  38     @Override 39     public long getItemId(int position) { 40         return position; 41     } 42  43     @Override 44     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):

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

分别是主界面 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     @Override 23     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             @Override 35             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     @Override 63     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     @Override 78     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     @Override 107     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     @Override 24     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     @Override 53     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记下来吧.

正文到此结束
Loading...