亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

利用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記下來吧.


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久精品国产一区二区| 2019中文字幕在线免费观看| 亚洲欧美中文日韩在线v日本| 欧美日韩国产精品一区二区不卡中文| 亚洲国产精品久久| 久久精品色欧美aⅴ一区二区| 久久99久久亚洲国产| 久久久久久12| 欧美日韩中文字幕日韩欧美| 色偷偷噜噜噜亚洲男人的天堂| 亚洲成人精品av| 草民午夜欧美限制a级福利片| 精品国产区一区二区三区在线观看| 亚洲香蕉av在线一区二区三区| 国产91精品久久久久久| 欧美日韩福利在线观看| 欧美午夜片欧美片在线观看| 亚洲高清av在线| 中文字幕精品久久久久| 国模精品一区二区三区色天香| 精品亚洲永久免费精品| 欧美日韩高清区| 国产精品ⅴa在线观看h| 国产精品av电影| 这里只有精品久久| 欧美丰满片xxx777| 91啪国产在线| 亚洲变态欧美另类捆绑| 国内精品视频一区| 91精品91久久久久久| 97精品欧美一区二区三区| 国产一区二区三区欧美| 中文字幕日韩有码| 欧美视频一区二区三区…| 日本一区二区三区四区视频| 中文字幕综合一区| 成人h视频在线观看播放| 91热精品视频| 久久综合五月天| 久久免费视频在线观看| 亚洲乱码国产乱码精品精| 久久精品视频亚洲| 色综合天天综合网国产成人网| 国产亚洲欧洲黄色| 久久久天堂国产精品女人| 久久久久久久久久久91| 社区色欧美激情 | 91夜夜未满十八勿入爽爽影院| 成人国产精品日本在线| 成人免费视频97| 国产精品高潮呻吟视频| 日本免费久久高清视频| 最近2019年手机中文字幕| 国外色69视频在线观看| 成人综合网网址| 日韩欧美成人免费视频| 日韩大片在线观看视频| 久久久久久国产精品| 欧美特黄级在线| 日韩av影视在线| 欧美大成色www永久网站婷| 欧美怡春院一区二区三区| 欧美性xxxx极品hd满灌| 夜夜躁日日躁狠狠久久88av| 亚洲天堂第二页| 成人网中文字幕| 国产成人精品日本亚洲专区61| 91性高湖久久久久久久久_久久99| 欧美激情精品久久久久| 日韩成人在线网站| 97在线看福利| 亚洲男人第一网站| 亚洲欧美在线免费观看| 国内偷自视频区视频综合| 亚洲精品第一页| www国产亚洲精品久久网站| 国产欧洲精品视频| 亚洲在线第一页| 日韩在线免费视频观看| 亚洲一区二区三区四区视频| 色偷偷av亚洲男人的天堂| 成人春色激情网| 亚洲一级片在线看| 亚洲天堂2020| 久久久久久久久国产| 4438全国成人免费| 欧美极品少妇xxxxⅹ免费视频| 国产成人亚洲综合91精品| 尤物99国产成人精品视频| 欧美巨乳在线观看| 日韩在线观看免费| 精品久久久91| 日本成人免费在线| 欧美另类极品videosbestfree| 国产精自产拍久久久久久| 日韩av免费在线播放| 国产精品aaaa| 国产精品一区二区三区成人| 国产精品第七十二页| 性欧美暴力猛交69hd| 国内精品久久久久久久| 亚洲视频axxx| 中文字幕亚洲色图| 国产精品一区二区三区毛片淫片| 亚洲精品一区二区在线| 在线观看日韩av| 日韩欧美aⅴ综合网站发布| 亚洲国产成人精品一区二区| 91高清免费在线观看| 午夜精品久久久久久99热软件| 亚洲一区二区福利| 成人网在线免费观看| 97视频在线播放| 国产69精品99久久久久久宅男| 亚洲理论电影网| 日韩欧美在线看| 亚洲开心激情网| 理论片在线不卡免费观看| 97精品国产97久久久久久春色| 性色av一区二区三区| 欧美激情va永久在线播放| 久久精品国产视频| 亚洲自拍偷拍在线| 久久精品夜夜夜夜夜久久| 亚洲精品福利视频| 欧美日韩福利在线观看| 国产精品成人久久久久| 欧美精品九九久久| 亚洲iv一区二区三区| 国产精品美女久久久久久免费| 久久久久久有精品国产| 92看片淫黄大片欧美看国产片| 国产精品久久久av久久久| 久久久久久国产免费| 亚洲精品久久在线| 88xx成人精品| 国产精品亚洲综合天堂夜夜| 国产精品嫩草影院一区二区| 欧美大尺度在线观看| 亚洲www在线| 91九色视频导航| 国产成人免费av| 精品久久久久国产| 欧美性猛交xxxx黑人| 成人精品视频99在线观看免费| 国产精品久久久| 国产精品www网站| 91欧美精品午夜性色福利在线| 欧美做受高潮电影o| 欧美国产亚洲视频| 国产欧美在线观看| 在线观看中文字幕亚洲| 国内成人精品一区| 久久久久久久久久久国产| 亚洲最新视频在线| 日韩资源在线观看| 日韩毛片在线观看| 欧美视频免费在线观看| 欧美一级高清免费播放| 欧美极品欧美精品欧美视频| 国语自产偷拍精品视频偷| 亚洲第一网中文字幕| 国产精品v日韩精品| 国产精品jizz在线观看麻豆|