自己写的一个简单的android记事本app

 

自己写的一个简单的记事本app,效果如下:

 

一、首先是第一个界面的编写,最上面是一个TextView,中间是一个Linearlayout中嵌套一个listview布局,最下面是一个button。下面附上第一个页面的简单布局xml文件。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/darker_gray"
    android:orientation="vertical" >
    <TextView 
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:text="记事本列表"
        android:textSize="20sp"
        android:paddingTop="10dp"
        android:paddingBottom="5dp"
        android:background="#039DCF"
        android:gravity="center"/>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1" >

        <ListView
            android:id="@+id/listview"
            android:layout_margin="5dp"
            android:background="#81966F"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>
    </LinearLayout>

    <Button
        android:id="@+id/btn_editnote"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/btn_selctor"
        android:layout_gravity="center"
        android:layout_marginBottom="10dp"
        android:text="添加备忘录"
        android:textSize="20sp" />

</LinearLayout>

至于button的样式btn_selector就是自己定义的button样式。

二、其次就是设置ListView中数据显示的xml文件,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:singleLine="true"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/tv_date"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="TextView" />
    
</LinearLayout>

 

三、编写第二个界面样式,第二个界面是最上面一个linearlayout,里面包含两个button和一个TextView。代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFAE99"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/btn_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/btn_selctor"
            android:text="取消" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:orientation="vertical" >

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="编辑备忘录"
                android:textSize="20sp" />

            <TextView
                android:id="@+id/tv_date"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="" />
        </LinearLayout>

        <Button
            android:id="@+id/btn_ok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/btn_selctor"
            android:text="保存" />
    </LinearLayout>

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scrollbars="vertical" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_marginLeft="2dp"
            android:orientation="vertical" >

            <EditText
                android:id="@+id/et_content"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="#FFAE99"
                android:textSize="20sp" />
        </LinearLayout>
    </ScrollView>

</LinearLayout>

四、将日志的数据保存在数据库中,使用sqlite来创建数据库,数据库中有三个属性,"_id"、"content"、"date"这三个属性,创建一个NoteDB来创建数据库。

package com.example.datenote;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class NotesDB extends SQLiteOpenHelper {

	public static final String TABLE_NAME_NOTES = "note";
	public static final String COLUMN_NAME_ID = "_id";
	public static final String COLUMN_NAME_NOTE_CONTENT = "content";
	public static final String COLUMN_NAME_NOTE_DATE = "date";

	public NotesDB(Context context) {
		super(context, "note", null, 1);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		String sql = "CREATE TABLE " + TABLE_NAME_NOTES + "(" + COLUMN_NAME_ID
				+ " INTEGER PRIMARY KEY AUTOINCREMENT,"
				+ COLUMN_NAME_NOTE_CONTENT + " TEXT NOT NULL DEFAULT\"\","
				+ COLUMN_NAME_NOTE_DATE + " TEXT NOT NULL DEFAULT\"\"" + ")";
		Log.d("SQL", sql);
		db.execSQL(sql);
//		String sql1="insert into "+TABLE_NAME_NOTES+"values("+"1,"+"'写作业',"+"'晚上要写作业的干活'"+")";
//		Log.d("SQL1", sql1);
//		db.execSQL(sql1);
//		ContentValues values=new ContentValues();
//		values.put("id",1);
//		values.put("content","写作业");
//		values.put("date", "2013-1-2");
//		db.insert("note", null, values);

	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub

	}

}



五、、实现点击添加事件的跳转,在第一个页面中点击添加备忘录后会跳转到第二个界面,设置点击事件,由一个activity跳转到另外一个activity,我使用的是intent方式。另外,在ListView中点击每个已记录下来的日志也会跳转到第二个界面,只是显示的不是空白的EditText,而是包含日志的EditText。MainActivity如下:

package com.example.datenote;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnScrollListener,
		OnItemClickListener, OnItemLongClickListener {

	private Context mContext;
	private ListView listview;
	private SimpleAdapter simp_adapter;
	private List<Map<String, Object>> dataList;
	private Button addNote;
	private TextView tv_content;
	private NotesDB DB;
	private SQLiteDatabase dbread;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		tv_content = (TextView) findViewById(R.id.tv_content);
		listview = (ListView) findViewById(R.id.listview);
		dataList = new ArrayList<Map<String, Object>>();

		addNote = (Button) findViewById(R.id.btn_editnote);
		mContext = this;
		addNote.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				noteEdit.ENTER_STATE = 0;
				Intent intent = new Intent(mContext, noteEdit.class);
				Bundle bundle = new Bundle();
				bundle.putString("info", "");
				intent.putExtras(bundle);
				startActivityForResult(intent, 1);
			}
		});
		DB = new NotesDB(this);
		dbread = DB.getReadableDatabase();
		// 清空数据库中表的内容
		//dbread.execSQL("delete from note");
		RefreshNotesList();

		listview.setOnItemClickListener(this);
		listview.setOnItemLongClickListener(this);
		listview.setOnScrollListener(this);
	}

	public void RefreshNotesList() {

		int size = dataList.size();
		if (size > 0) {
			dataList.removeAll(dataList);
			simp_adapter.notifyDataSetChanged();
			listview.setAdapter(simp_adapter);
		}
		simp_adapter = new SimpleAdapter(this, getData(), R.layout.item,
				new String[] { "tv_content", "tv_date" }, new int[] {
						R.id.tv_content, R.id.tv_date });
		listview.setAdapter(simp_adapter);
	}

	private List<Map<String, Object>> getData() {

		Cursor cursor = dbread.query("note", null, "content!=\"\"", null, null,
				null, null);

		while (cursor.moveToNext()) {
			String name = cursor.getString(cursor.getColumnIndex("content"));
			String date = cursor.getString(cursor.getColumnIndex("date"));
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("tv_content", name);
			map.put("tv_date", date);
			dataList.add(map);
		}
		cursor.close();
		return dataList;

	}

	@Override
	public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
		// TODO Auto-generated method stub

	}

	// 滑动listview监听事件
	@Override
	public void onScrollStateChanged(AbsListView arg0, int arg1) {
		// TODO Auto-generated method stub
		switch (arg1) {
		case SCROLL_STATE_FLING:
			Log.i("main", "用户在手指离开屏幕之前,由于用力的滑了一下,视图能依靠惯性继续滑动");
		case SCROLL_STATE_IDLE:
			Log.i("main", "视图已经停止滑动");
		case SCROLL_STATE_TOUCH_SCROLL:
			Log.i("main", "手指没有离开屏幕,试图正在滑动");
		}
	}

	// 点击listview中某一项的监听事件
	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
		noteEdit.ENTER_STATE = 1;
		// Log.d("arg2", arg2 + "");
		// TextView
		// content=(TextView)listview.getChildAt(arg2).findViewById(R.id.tv_content);
		// String content1=content.toString();
		String content = listview.getItemAtPosition(arg2) + "";
		String content1 = content.substring(content.indexOf("=") + 1,
				content.indexOf(","));
		Log.d("CONTENT", content1);
		Cursor c = dbread.query("note", null,
				"content=" + "'" + content1 + "'", null, null, null, null);
		while (c.moveToNext()) {
			String No = c.getString(c.getColumnIndex("_id"));
			Log.d("TEXT", No);
			// Intent intent = new Intent(mContext, noteEdit.class);
			// intent.putExtra("data", text);
			// setResult(4, intent);
			// // intent.putExtra("data",text);
			// startActivityForResult(intent, 3);
			Intent myIntent = new Intent();
			Bundle bundle = new Bundle();
			bundle.putString("info", content1);
			noteEdit.id = Integer.parseInt(No);
			myIntent.putExtras(bundle);
			myIntent.setClass(MainActivity.this, noteEdit.class);
			startActivityForResult(myIntent, 1);
		}

	}

	@Override
	// 接受上一个页面返回的数据,并刷新页面
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == 1 && resultCode == 2) {
			RefreshNotesList();
		}
	}

	// 点击listview中某一项长时间的点击事件
	@Override
	public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
			long arg3) {
		final int n=arg2;
		Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("删除该日志");
		builder.setMessage("确认删除吗?");
		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				String content = listview.getItemAtPosition(n) + "";
				String content1 = content.substring(content.indexOf("=") + 1,
						content.indexOf(","));
				Cursor c = dbread.query("note", null, "content=" + "'"
						+ content1 + "'", null, null, null, null);
				while (c.moveToNext()) {
					String id = c.getString(c.getColumnIndex("_id"));
					String sql_del = "update note set content='' where _id="
							+ id;
					dbread.execSQL(sql_del);
					RefreshNotesList();
				}
			}
		});
		builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
			}
		});
		builder.create();
		builder.show();
		return true;
	}

}


六、编写第二个跳转后界面的Activity,如下:

package com.example.datenote;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class noteEdit extends Activity {
	private TextView tv_date;
	private EditText et_content;
	private Button btn_ok;
	private Button btn_cancel;
	private NotesDB DB;
	private SQLiteDatabase dbread;
	public static int ENTER_STATE = 0;
	public static String last_content;
	public static int id;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		// 设置无标题
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.edit);

		tv_date = (TextView) findViewById(R.id.tv_date);
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		String dateString = sdf.format(date);
		tv_date.setText(dateString);

		et_content = (EditText) findViewById(R.id.et_content);
		// 设置软键盘自动弹出
		getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);

		DB = new NotesDB(this);
		dbread = DB.getReadableDatabase();

		Bundle myBundle = this.getIntent().getExtras();
		last_content = myBundle.getString("info");
		Log.d("LAST_CONTENT", last_content);
		et_content.setText(last_content);
		// 确认按钮的点击事件
		btn_ok = (Button) findViewById(R.id.btn_ok);
		btn_ok.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
				// 获取日志内容
				String content = et_content.getText().toString();
				Log.d("LOG1", content);
				// 获取写日志时间
				Date date = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				String dateNum = sdf.format(date);
				String sql;
				String sql_count = "SELECT COUNT(*) FROM note";
				SQLiteStatement statement = dbread.compileStatement(sql_count);
				long count = statement.simpleQueryForLong();
				Log.d("COUNT", count + "");
				Log.d("ENTER_STATE", ENTER_STATE + "");
				// 添加一个新的日志
				if (ENTER_STATE == 0) {
					if (!content.equals("")) {
						sql = "insert into " + NotesDB.TABLE_NAME_NOTES
								+ " values(" + count + "," + "'" + content
								+ "'" + "," + "'" + dateNum + "')";
						Log.d("LOG", sql);
						dbread.execSQL(sql);
					}
				}
				// 查看并修改一个已有的日志
				else {
						Log.d("执行命令", "执行了该函数");
						String updatesql = "update note set content='"
								+ content + "' where _id=" + id;
						dbread.execSQL(updatesql);
						// et_content.setText(last_content);
				}
				Intent data = new Intent();
				setResult(2, data);
				finish();
			}
		});
		btn_cancel = (Button) findViewById(R.id.btn_cancel);
		btn_cancel.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
				finish();
			}
		});
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		// if (requestCode == 3 && resultCode == 4) {
		// last_content=data.getStringExtra("data");
		// Log.d("LAST_STRAING", last_content+"gvg");
		// }
	}
}


七、其中,对ListView添加OnItemLongclicklistener,长点击之后会弹出一个dialog对话框提醒要不要删除该日志文件。

public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
			long arg3) {
		final int n=arg2;
		Builder builder = new AlertDialog.Builder(this);
		builder.setTitle("删除该日志");
		builder.setMessage("确认删除吗?");
		builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				String content = listview.getItemAtPosition(n) + "";
				String content1 = content.substring(content.indexOf("=") + 1,
						content.indexOf(","));
				Cursor c = dbread.query("note", null, "content=" + "'"
						+ content1 + "'", null, null, null, null);
				while (c.moveToNext()) {
					String id = c.getString(c.getColumnIndex("_id"));
					String sql_del = "update note set content='' where _id="
							+ id;
					dbread.execSQL(sql_del);
					RefreshNotesList();
				}
			}
		});
		builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
			}
		});
		builder.create();
		builder.show();
		return true;
	}

注意最后将返回值设为true,否则会和OnItemClickListener产生冲突。
附上长点击删除的效果。

 

由于Android6.0以上读写权限需要手动申请,可能会导致保存之后显示不出来,需要手动加上权限申请:

//android6.0之后要动态获取权限
    private void checkPermission() {
        // Storage Permissions
        final int REQUEST_EXTERNAL_STORAGE = 1;
        String[] PERMISSIONS_STORAGE = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE};

        try {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(MainActivity.this,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限,去申请写的权限,会弹出对话框
                ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

已更新到github上,自行下载。

由于很多人去csdn下载资源分不够,现将代码上传到github,大家自行下载。
 

  • 81
    点赞
  • 457
    收藏
    觉得还不错? 一键收藏
  • 87
    评论
评论 87
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值