安卓項目——實時記錄APP:03功能實現

上一篇文章我們講的是實時記錄APP界面的搭建:帶你做項目——實時記錄APP:02搭建佈局,本篇文章就來實現APP中的邏輯功能。

一、點擊按鈕彈出可輸入的對話框

/**
* 加號按鈕的點擊事件
* @param v
*/
public void btn_click(View v){

EditText editText = new EditText(this);
//new出一個對話框
new AlertDialog.Builder(this)
.setTitle("請輸入內容")
.setView(editText)//對話框加一個edittext用於輸入內容
.setPositiveButton("確定", new OnClickListener() {
//確定按鈕的點擊事件
@Override
public void onClick(DialogInterface dialog, int which) {
//在這裡保存數據並刷新listview

}
})
.setNegativeButton("取消",null)
.show();
}

運行看一下效果:

安卓項目——實時記錄APP:03功能實現


效果和預期一樣,還是不錯的,我們要的是快速,所以可以在彈出對話框的同時把輸入法也彈出來就更快了。那麼,讓輸入法也彈出來吧。代碼就變成了這樣:

/**
* 加號按鈕的點擊事件
* @param v
*/
public void btn_click(View v){

final EditText editText = new EditText(this);
//new出一個對話框
new AlertDialog.Builder(this)
.setTitle("請輸入內容")
.setView(editText)//對話框加一個edittext用於輸入內容
.setPositiveButton("確定", new OnClickListener() {
//確定按鈕的點擊事件
@Override
public void onClick(DialogInterface dialog, int which) {
//在這裡保存數據並刷新listview

}
})
.setNegativeButton("取消",null)
.show();
//調出鍵盤
editText.post(new Runnable() {
@Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editText, 0);
}
});
}

看下效果:

安卓項目——實時記錄APP:03功能實現


果然點擊加號按鈕直接就能彈出輸入法了,很方便。

二、點擊對話框中的確定按鈕,保存數據並顯示在listview上

分析一下,點擊“確定”按鈕之後,應該先將數據保存到文件中,然後再刷新listview的數據適配器即可。

1.將數據保存到文件

我們一次要保存兩個數據,一個是內容,一個是時間。兩者都可以很方便的獲取到。唯一要考慮的是數據保存的格式,既然我們要把所有數據一行行保存在一個文本文件中,那麼這兩個數據就要能夠分離,這樣讀取的時候就能區分哪一部分是內容,哪一部分是時間。因此我自己定義一個分隔符即可。

首先定義兩個路徑常量:一個是文件路徑,一個是文件目錄路徑,要分清楚

private static final String FILEPATH = Environment.getExternalStorageDirectory().getPath()+"/IntimeRecord/record.db";

private static final String DIRPATH = Environment.getExternalStorageDirectory().getPath()+"/IntimeRecord";

然後:

//1.獲得內容和當前時間


String content = editText.getText().toString();//得到內容
String time = getNowTime();//得到當前時間
String save = content+ "^"+time;//以^分割兩者,讀取的時候再分開即可
saveToFile(save);//將內容保存到文件中

/**
* 獲得當前時間
* @return 格式為 年-月-日-時h-分m-秒s 的字符串 比如2019-11-20-21h24m19s
*/
protected String getNowTime() {
//從calendar對象中拿到時間
Calendar c = Calendar.getInstance();//得到calendar對象
String mYear = String.valueOf(c.get(Calendar.YEAR)); // 獲取當前年份
String mMonth = String.valueOf(c.get(Calendar.MONTH) + 1);// 獲取當前月份
String mDay = String.valueOf(c.get(Calendar.DAY_OF_MONTH));// 獲取當日期
String mHour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));//時
String mMinute =String.valueOf(c.get(Calendar.MINUTE));//分
String mSecond =String.valueOf(c.get(Calendar.SECOND));//秒
return mYear+"-"+mMonth+"-"+mDay+"-"+mHour+"h"+mMinute+"m"+mSecond+"s";
}

/**
* 向文件中添加一行數據
* @param save
*/
protected void saveToFile(String content) {
//首先創建文件夾
File file = new File(DIRPATH);
if(!file.exists()){
file.mkdir();
}
//然後創建文件 注意路徑必須指定到文件名才行
file = new File(FILEPATH);
FileWriter writer = null;
try {
writer = new FileWriter(file, true);//第二個參數為true是追加內容,false是覆蓋


writer.write(content);
writer.write("\r\n");//換行
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(writer != null){
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

代碼部分就完成了,不過不要忘記最重要的東西:SD卡讀寫數據、刪除和創建文件的權限



最後一個是在SD卡中創建、刪除文件的權限,開始沒想到還要這個權限,浪費了好長時間才發現是這個問題!

然後看一下效果,在外置存儲目錄中有一個IntimeRecord文件夾,下面有個record.db文件,以文本的方式打開就能看到數據了

安卓項目——實時記錄APP:03功能實現

安卓項目——實時記錄APP:03功能實現


然後是在listview中顯示數據了。保存好數據後,從文件中讀取即可。這個時候,我們不能從文件中直接讀取一行

行的數據顯示在listview中,效率低,需要將數據從文件中一下子讀出來,然後放進一個容器中,最好的容器就是

集合了,因為後面我們還要用到刪除操作,集合可以很方便的刪除某一個元素。

我們首先要先修改listview的數據適配器。

定義一個list:private List list = new ArrayList();

然後修改listview的適配器:

class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView == null){//這樣寫可以提高listview加載速度
convertView = View.inflate(MainActivity.this, R.layout.listview_view, null);
}
TextView tv_content = (TextView)convertView.findViewById(R.id.content);
TextView tv_date = (TextView)convertView.findViewById(R.id.date);
String text = list.get(list.size() - position - 1);//從最後記錄的數據開始顯示
String[] msg = text.split("\\^");
tv_content.setText(msg[0]);
tv_date.setText(msg[1]);
return convertView;
}
}

接著寫一個方法:

/**
* 將文件中的數據放入list中


*/
private void fileToList() {
//從文件中讀取數據放到list中
list.clear();//首先要把list清空,避免數據堆積
FileReader fr;
try {
fr = new FileReader(new File(FILEPATH));
BufferedReader br = new BufferedReader(fr);
String content = br.readLine();
while(content != null){
list.add(content);
content = br.readLine();
}
br.close();
fr.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

然後再寫一個刷新listview數據適配器的方法:

/**
* 刷新listview的數據
*/
protected void freshListView() {
//1.將文件中的數據放入list中
fileToList();
//2.刷新listview適配器
myAdapter.notifyDataSetChanged();
}

接著在輸入框的確定事件中調用即可:

public void onClick(DialogInterface dialog, int which) {
//在這裡保存數據並刷新listview
//1.獲得內容和當前時間
String content = editText.getText().toString();//得到內容


String time = getNowTime();//得到當前時間
String save = content+ "^"+time;//以^分割兩者,讀取的時候再分開即可
saveToFile(save);//將內容保存到文件中
freshListView();
}

這樣就可以實現listview數據的刷新,但是打開APP的時候也要加載數據,所以在APP的加載事件中添加fileToList方法即可。

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
fullScreen(this);//沉浸式狀態欄
lv = (ListView)findViewById(R.id.lv);//獲得listview
fileToList();//填充list
myAdapter = new MyAdapter();
lv.setAdapter(myAdapter);//設置數據適配器 通過內部類繼承baseAdapter

}

到這一步,實際上就大功告成了,已經實現了最初設計的功能。效果圖:

安卓項目——實時記錄APP:03功能實現


下面是擴充功能

三、圖標的製作與添加

APP圖標怎麼修改?我在PS中做了一張圖片:

安卓項目——實時記錄APP:03功能實現


把它的名稱重命名為ic_launcher.png然後複製到res目錄下的drawable開頭的文件夾中,覆蓋掉裡面的同名文件即可。

圖片是個正方形的就行了,寬高一樣,大小無所謂。我做的這個是174X174的。

效果:

安卓項目——實時記錄APP:03功能實現


變成了這個樣子,模擬器上太醜了,安裝在真的手機上還是不錯的。

安卓項目——實時記錄APP:03功能實現


四、數據的刪除:長按listview的某一行,彈出是否刪除此行,點擊確認後刪除

//listview的每一行的長按事件
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView> parent, View view,
final int position, long id) {
//長按後彈出提示框,提示是否刪除
new AlertDialog.Builder(MainActivity.this)
.setTitle("確定要刪除嗎")
.setPositiveButton("確定", new OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
//點擊確定後進行刪除
//要知道刪除的是第幾行數據,在list中刪除後重新寫入文件即可
//1.list中刪除該記錄
list.remove(list.size() - position -1);
//2.文件中刪除
//先刪除文件
File file = new File(FILEPATH);
file.delete();
//再重新寫入文件
try {
FileWriter fw = new FileWriter(file,true);
for (int i = 0; i < list.size(); i++) {
fw.write(list.get(i)+"\r\n");
}
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();


}
//3.刷新listview數據適配器
freshListView();
}
})
.setNegativeButton("取消", null)
.show();
return true;
}
});

OK,到現在,擴展功能也做完了。

最後源碼下載地址請點擊更多,滑到文章最下方有下載鏈接。

本文系小博客網站原創,轉載請註明文章鏈接地址


分享到:


相關文章: