`
kevincollins
  • 浏览: 57243 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android笔记之二:改进的NotePad Demo

阅读更多

 下面是对SDK中的NotePad smaple做的一些改进,效果图在最后。

刚开始看Android,这是继hello之后的第二个例子。

不对的地方,请批评指正。

 

java文件有:

1.NotesList.java

2.NoteEditor.java

3.NotePadProvider.java

4.NotePad.java

5.DateUtil.java

 

layout有:

1.note_editor.xml

2.noteslist_item.xml

 

 

贴出来修改之后的代码:

NotesList.java:

package com.cticc.notepad;

import android.app.ListActivity;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

import com.cticc.notepad.NotePad.Notes;

/**
 * Displays a list of notes. Will display notes from the {@link Uri} provided in the intent if there
 * is one, otherwise defaults to displaying the contents of the {@link NotePadProvider}
 */
public class NotesList extends ListActivity
{
	private static final String TAG = "NotesList";

	public static final int MENU_ITEM_DELETE = Menu.FIRST;
	public static final int MENU_ITEM_INSERT = Menu.FIRST + 1;

	/**
	 * The columns we are interested in from the database
	 */
	private static final String[] PROJECTION = new String[] { Notes._ID, // 0
			Notes.KEY_TITLE, // 1
			Notes.KEY_CREATEAT // 2
	};

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);

		// If no data was given in the intent (because we were started as a MAIN activity), then use our default content provider.
		Intent intent = getIntent();
		if (intent.getData() == null)
		{
			intent.setData(Notes.CONTENT_URI);
		}

		// Inform the list we provide context menus for items
		getListView().setOnCreateContextMenuListener(this);

		// Perform a managed query. The Activity will handle closing and requerying the cursor when needed.
		Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null, Notes.DEFAULT_SORT_ORDER);

		// Used to map notes entries from the database to views
		SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor, new String[] { Notes.KEY_CREATEAT, Notes.KEY_TITLE }, new int[] { android.R.id.text1,
				android.R.id.text2 });
		setListAdapter(adapter);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		super.onCreateOptionsMenu(menu);

		Log.i(TAG, "enter in onCreateOptionsMenu");

		// This is our one standard application action -- inserting a new note into the list.
		menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert).setShortcut('3', 'a').setIcon(android.R.drawable.ic_menu_add);

		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu)
	{
		super.onPrepareOptionsMenu(menu);

		Log.i(TAG, "enter in onPrepareOptionsMenu");
		final boolean haveItems = getListAdapter().getCount() > 0;

		// If there are any notes in the list (which implies that one of them is selected), then we need to generate the actions that
		// can be performed on the current selection. This will be a combination of our own specific 
		// actions along with any extensions that can be found.
		if (haveItems)
		{
			// This is the selected item.
			Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId());
			
			// Build menu... always starts with the EDIT action...
			Intent[] specifics = new Intent[1];
			specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
			MenuItem[] items = new MenuItem[1];

			// ... is followed by whatever other actions are available...
			Intent intent = new Intent(null, uri);
			intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
			menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0, items);
			
			// Give a shortcut to the edit action.
			if (items[0] != null)
			{
				items[0].setShortcut('1', 'e').setIcon(android.R.drawable.ic_menu_edit);
			}
		}
		else
		{
			menu.removeGroup(Menu.CATEGORY_ALTERNATIVE);
		}

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId())
		{
		case MENU_ITEM_INSERT:
			// Launch activity to insert a new item
			startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
	
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id)
	{
		Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);

		String action = getIntent().getAction();
		if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action))
		{
			// The caller is waiting for us to return a note selected by
			// the user. The have clicked on one, so return it now.
			setResult(RESULT_OK, new Intent().setData(uri));
		}
		else
		{
			// Launch activity to view/edit the currently selected item
			startActivity(new Intent(Intent.ACTION_EDIT, uri));
		}
	}
}

 

 NoteEditor.java:

package com.cticc.notepad;

import com.cticc.notepad.NotePad.Notes;
import com.cticc.notepad.util.DateUtil;

import android.app.Activity;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;

/**
 * A generic activity for editing a note in a database. This can be used either to simply view a
 * note {@link Intent#ACTION_VIEW}, view and edit a note {@link Intent#ACTION_EDIT}, or create a new
 * note {@link Intent#ACTION_INSERT}.
 */
public class NoteEditor extends Activity
{
	private static final String TAG = "Notes";

	// Standard projection for the interesting columns of a normal note.
	private static final String[] PROJECTION = new String[] { Notes._ID, // 0
			Notes.KEY_TITLE, // 1
			Notes.KEY_CONTENT // 2
	};
	// The index of the note column
	private static final int COLUMN_INDEX_TITLE = 1;
	private static final int COLUMN_INDEX_CONTENT = 2;

	// Identifiers for our menu items.
	private static final int MENU_CONFIRM_ID = Menu.FIRST;
	private static final int MENU_DELETE_ID = Menu.FIRST + 1;
	private static final int MENU_DISCARD_ID = Menu.FIRST + 2;

	// The different distinct states the activity can be run in.
	private static final int ACTION_EDIT = 0;
	private static final int ACTION_INSERT = 1;

	private int mState;
	private boolean mNoteOnly = false;
	private Uri mUri;
	private Cursor mCursor;
	private EditText mContent;
	private EditText mTitle;
	//private String mOriginalContent;

	/**
	 * A custom EditText that draws lines between each line of text that is displayed.
	 */
	public static class LinedEditText extends EditText
	{
		private Rect mRect;
		private Paint mPaint;

		// we need this constructor for LayoutInflater
		public LinedEditText(Context context, AttributeSet attrs)
		{
			super(context, attrs);

			mRect = new Rect();
			mPaint = new Paint();
			mPaint.setStyle(Paint.Style.STROKE);
			mPaint.setColor(0x800000FF);
		}

		@Override
		protected void onDraw(Canvas canvas)
		{
			int count = getLineCount();
			Rect r = mRect;
			Paint paint = mPaint;

			for (int i = 0; i < count; i++)
			{
				int baseline = getLineBounds(i, r);
				canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
			}
			super.onDraw(canvas);
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		final Intent intent = getIntent();

		// Do some setup based on the action being performed.

		final String action = intent.getAction();
		if (Intent.ACTION_EDIT.equals(action))
		{
			// Requested to edit: set that state, and the data being edited.
			mState = ACTION_EDIT;
			mUri = intent.getData();
		}
		else if (Intent.ACTION_INSERT.equals(action))
		{
			// Requested to insert: set that state, and create a new entry
			// in the container.
			mState = ACTION_INSERT;
			Log.i(TAG, "intent.getData() is : " + intent.getData());
			//mUri = getContentResolver().insert(intent.getData(), null);
			mUri = intent.getData();
			// If we were unable to create a new note, then just finish
			// this activity. A RESULT_CANCELED will be sent back to the
			// original activity if they requested a result.
			if (mUri == null)
			{
				Log.e(TAG, "Failed to insert new note into " + getIntent().getData());
				finish();
				return;
			}

			// The new entry was created, so assume all will end well and
			// set the result to be returned.
			setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));

		}
		else
		{
			// Whoops, unknown action! Bail.
			Log.e(TAG, "Unknown action, exiting");
			finish();
			return;
		}

		// Set the layout for this activity. You can find it in res/layout/note_editor.xml
		setContentView(R.layout.note_editor);

		// The text view for our note, identified by its ID in the XML file.
		mContent = (EditText) findViewById(R.id.content);
		mTitle = (EditText) findViewById(R.id.title);

		// Get the note!
		mCursor = managedQuery(mUri, PROJECTION, null, null, null);
	}

	@Override
	protected void onResume()
	{
		super.onResume();

		// If we didn't have any trouble retrieving the data, it is now
		// time to get at the stuff.
		if (mCursor != null)
		{
			// Make sure we are at the one and only row in the cursor.
			mCursor.moveToFirst();

			// Modify our overall title depending on the mode we are running in.
			if (mState == ACTION_EDIT)
			{
				setTitle(getText(R.string.label_edit));
				
				String content = mCursor.getString(COLUMN_INDEX_CONTENT);
				String title = mCursor.getString(COLUMN_INDEX_TITLE);
				
				mContent.setTextKeepState(content);
				mTitle.setTextKeepState(title);
			}
			else if (mState == ACTION_INSERT)
			{
				setTitle(getText(R.string.label_insert));
			}
		}
		else
		{
			
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		super.onCreateOptionsMenu(menu);

		menu.add(0, MENU_CONFIRM_ID, 0, R.string.menu_confirm).setShortcut('0', 'c').setIcon(android.R.drawable.ic_menu_save);
		if (mState == ACTION_EDIT)
		{
			if (!mNoteOnly)
			{
				menu.add(0, MENU_DELETE_ID, 0, R.string.menu_delete).setShortcut('1', 'd').setIcon(android.R.drawable.ic_menu_delete);
			}
		}

		menu.add(0, MENU_DISCARD_ID, 0, R.string.menu_discard).setShortcut('2', 'd').setIcon(android.R.drawable.ic_menu_revert);
		
		if (!mNoteOnly)
		{
			Intent intent = new Intent(null, getIntent().getData());
			intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
			menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, new ComponentName(this, NoteEditor.class), null, intent, 0, null);
		}

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		// Handle all of the possible menu actions.
		switch (item.getItemId())
		{
		case MENU_CONFIRM_ID:
			saveState();
			finish();
			break;
		case MENU_DELETE_ID:
			deleteNote();
			finish();
			break;
		case MENU_DISCARD_ID:
			finish();
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void saveState()
	{
		ContentValues values = new ContentValues();

		values.put(Notes.KEY_CONTENT, mContent.getText().toString());
		values.put(Notes.KEY_TITLE, mTitle.getText().toString());
		String sdate = DateUtil.getTodayTimeStampString();

		if (mState == ACTION_INSERT)
		{
			values.put(Notes.KEY_CREATEAT, DateUtil.getToday());
			values.put(Notes.KEY_UPDATEAT, sdate);
			getContentResolver().insert(mUri, values);
		}
		else if (mState == ACTION_EDIT)
		{
			values.put(Notes.KEY_UPDATEAT, sdate);
			getContentResolver().update(mUri, values, null, null);
		}

	}
	/**
	 * Take care of deleting a note. Simply deletes the entry.
	 */
	private final void deleteNote()
	{
		if (mCursor != null)
		{
			mCursor.close();
			mCursor = null;
			getContentResolver().delete(mUri, null, null);
			mContent.setText("");
		}
	}
}

 

 NotePadProvider.java:

package com.cticc.notepad;

import com.cticc.notepad.NotePad.Notes;
import com.cticc.notepad.util.DateUtil;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import java.util.HashMap;

/**
 * Provides access to a database of notes. Each note has a title, the note itself, a creation date and a modified data.
 */
public class NotePadProvider extends ContentProvider
{

	private static final String TAG = "NotePadProvider";

	private SQLiteDatabase sqlitedb;

	private static HashMap<String, String> sNotesProjectionMap;

	private static final int NOTES = 1;
	private static final int NOTE_ID = 2;

	private static final UriMatcher sUriMatcher;
	
	static
	{
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
		sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);

		sNotesProjectionMap = new HashMap<String, String>();
		sNotesProjectionMap.put(Notes._ID, Notes._ID);
		sNotesProjectionMap.put(Notes.KEY_TITLE, Notes.KEY_TITLE);
		sNotesProjectionMap.put(Notes.KEY_CONTENT, Notes.KEY_CONTENT);
		sNotesProjectionMap.put(Notes.KEY_CREATEAT, Notes.KEY_CREATEAT);
		sNotesProjectionMap.put(Notes.KEY_UPDATEAT, Notes.KEY_UPDATEAT);
	}

	/**
	 * This class helps open, create, and upgrade the database file.
	 */
	private static class DatabaseHelper extends SQLiteOpenHelper
	{

		DatabaseHelper(Context context)
		{
			super(context, Notes.DATABASE_NAME, null, Notes.DATABASE_VERSION);
		}

		@Override
		public void onCreate(SQLiteDatabase db)
		{
			db.execSQL("CREATE TABLE " + Notes.TABLE_NAME + " (" + Notes._ID + " INTEGER PRIMARY KEY," + Notes.KEY_TITLE + " TEXT," + Notes.KEY_CONTENT + " TEXT,"
					+ Notes.KEY_CREATEAT + " TEXT," + Notes.KEY_UPDATEAT + " TEXT" + ");");
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
		{
			Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");
			db.execSQL("DROP TABLE IF EXISTS " + Notes.TABLE_NAME);
			onCreate(db);
		}
	}

	private DatabaseHelper mOpenHelper;

	@Override
	public boolean onCreate()
	{
		mOpenHelper = new DatabaseHelper(getContext());
		sqlitedb = mOpenHelper.getWritableDatabase();
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
	{
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

		switch (sUriMatcher.match(uri))
		{
		case NOTES:
			qb.setTables(Notes.TABLE_NAME);
			qb.setProjectionMap(sNotesProjectionMap);
			break;

		case NOTE_ID:
			qb.setTables(Notes.TABLE_NAME);
			qb.setProjectionMap(sNotesProjectionMap);
			qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1));
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		// If no sort order is specified use the default
		String orderBy;
		if (TextUtils.isEmpty(sortOrder))
		{
			orderBy = Notes.DEFAULT_SORT_ORDER;
		}
		else
		{
			orderBy = sortOrder;
		}

		Cursor c = qb.query(sqlitedb, projection, selection, selectionArgs, null, null, orderBy);

		// Tell the cursor what uri to watch, so it knows when its source data changes
		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}

	@Override
	public String getType(Uri uri)
	{
		Log.i(TAG, "getType: the uri is: " + uri);
		
		switch (sUriMatcher.match(uri))
		{
		case NOTES:
			return Notes.CONTENT_TYPE;

		case NOTE_ID:
			return Notes.CONTENT_ITEM_TYPE;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues initialValues)
	{
		// Validate the requested uri
		if (sUriMatcher.match(uri) != NOTES)
		{
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		ContentValues values;
		if (initialValues != null)
		{
			values = new ContentValues(initialValues);
		}
		else
		{
			values = new ContentValues();
		}

		// Make sure that the fields are all set
		if (values.containsKey(NotePad.Notes.KEY_CREATEAT) == false)
		{
			values.put(NotePad.Notes.KEY_CREATEAT, DateUtil.getToday());
		}

		if (values.containsKey(NotePad.Notes.KEY_UPDATEAT) == false)
		{
			values.put(NotePad.Notes.KEY_UPDATEAT, DateUtil.getTodayTimeStampString());
		}

		if (values.containsKey(NotePad.Notes.KEY_TITLE) == false)
		{
			Resources r = Resources.getSystem();
			values.put(NotePad.Notes.KEY_TITLE, r.getString(android.R.string.untitled));
		}

		if (values.containsKey(NotePad.Notes.KEY_CONTENT) == false)
		{
			values.put(NotePad.Notes.KEY_CONTENT, "");
		}

		long rowId = sqlitedb.insert(Notes.TABLE_NAME, Notes.KEY_CONTENT, values);
		if (rowId > 0)
		{
			Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
			getContext().getContentResolver().notifyChange(noteUri, null);
			return noteUri;
		}

		throw new SQLException("Failed to insert row into " + uri);
	}

	@Override
	public int delete(Uri uri, String where, String[] whereArgs)
	{
		int count;
		switch (sUriMatcher.match(uri))
		{
		case NOTES:
			count = sqlitedb.delete(Notes.TABLE_NAME, where, whereArgs);
			break;

		case NOTE_ID:
			String noteId = uri.getPathSegments().get(1);
			count = sqlitedb.delete(Notes.TABLE_NAME, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public int update(Uri uri, ContentValues values, String where, String[] whereArgs)
	{
		int count;
		switch (sUriMatcher.match(uri))
		{
		case NOTES:
			count = sqlitedb.update(Notes.TABLE_NAME, values, where, whereArgs);
			break;

		case NOTE_ID:
			String noteId = uri.getPathSegments().get(1);
			count = sqlitedb.update(Notes.TABLE_NAME, values, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	
}

 

 NotePad.java

package com.cticc.notepad;

import android.net.Uri;
import android.provider.BaseColumns;

/**
 * Convenience definitions for NotePadProvider
 */
public final class NotePad
{
	public static final String AUTHORITY = "com.google.provider.NotePad";

	// This class cannot be instantiated
	private NotePad()
	{

	}

	/**
	 * Notes table
	 */
	public static final class Notes implements BaseColumns
	{
		// This class cannot be instantiated
		private Notes()
		{
		}

		/****************************************************************************************
		 * 
		 * 
		 * **************************************************************************************/
		public static final String DATABASE_NAME = "notepad.db";
		public static final String TABLE_NAME = "notes";
		public static final int DATABASE_VERSION = 2;

		/****************************************************************************************
		 * 
		 * 
		 * **************************************************************************************/
		// public static final String KEY_ROWID = "_id";
		public static final String KEY_TITLE = "title";
		public static final String KEY_CONTENT = "content";
		public static final String KEY_CREATEAT = "createAt";
		public static final String KEY_UPDATEAT = "updateAt";

		/****************************************************************************************
		 * 
		 * 
		 * **************************************************************************************/
		/**
		 * The content:// style URL for this table
		 */
		public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);

		/**
		 * The MIME type of {@link #CONTENT_URI} providing a directory of notes.
		 */
		public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note";

		/**
		 * The MIME type of a {@link #CONTENT_URI} sub-directory of a single note.
		 */
		public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.note";

		/**
		 * The default sort order for this table
		 */
		public static final String DEFAULT_SORT_ORDER = "updateAt DESC";

	}
}

 

DateUtil.java

 

package com.cticc.notepad.util;

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

public class DateUtil
{
	private static String defaultDatePattern = "yyyy-MM-dd";
	
	private static String defaultTimeStampPattern = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 返回默认格式的当前日期
	 * 
	 * @return String
	 */
	public static String getToday()
	{
		Date today = new Date();
		return convertDateToString(today,defaultDatePattern);
	}
	
	/**
	 * 返回默认格式的当前时间戳字符串格式
	 * 
	 * @return String
	 */
	public static String getTodayTimeStampString()
	{
		Date today = new Date();
		return convertDateToString(today, defaultTimeStampPattern);
	}

	/**
	 * 使用默认格式转换Date成字符串
	 * 
	 * @param date
	 * @return String
	 */
	public static String convertDateToString(Date date)
	{
		return convertDateToString(date, defaultDatePattern);
	}

	/**
	 * 使用指定格式转换Date成字符串
	 * 
	 * @param date
	 * @param pattern
	 * @return String
	 */
	public static String convertDateToString(Date date, String pattern)
	{
		String returnValue = "";

		if (date != null)
		{
			SimpleDateFormat df = new SimpleDateFormat(pattern);
			returnValue = df.format(date);
		}
		return returnValue;
	}
}

 

note_editor.xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
          http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
<LinearLayout android:orientation="horizontal"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content">

		<TextView android="http://schemas.android.com/apk/res/android"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content" 
			android:text="@string/label_title" />
		<EditText android="http://schemas.android.com/apk/res/android"
			android:id="@+id/title" 
		  	android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_weight="1"/>
</LinearLayout>
			
<view xmlns:android="http://schemas.android.com/apk/res/android"
    class="com.cticc.notepad.NoteEditor$LinedEditText"
    android:id="@+id/content"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/transparent"
    android:padding="5dip"
    android:scrollbars="vertical"
    android:fadingEdge="vertical"
    android:gravity="top"
    android:capitalize="sentences"
/>

</LinearLayout>

 

noteslist_item.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2006 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
          http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->




<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content">
    
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="wrap_content"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:gravity="center_vertical"
    android:paddingLeft="5dip"
    android:singleLine="true"
/>
   
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/separation" />

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text2"
    android:layout_width="wrap_content"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:gravity="center_vertical"
    android:paddingLeft="5dip"
    android:singleLine="true"
/>     
    
</LinearLayout>

 

 strings.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
          http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<resources>
    <string name="menu_confirm">Confirm</string>
    <string name="menu_delete">Delete</string>
    <string name="menu_discard">Discard</string>
    
    
    <string name="menu_insert">Add note</string>

    <string name="label_insert">Add note</string>
    <string name="label_edit">Edit note</string>
	<string name="label_title">Title</string>
	
	<string name="layout_note_editor">note_editor</string>
	<string name="layout_noteslist_item">noteslist_item</string>
	
	<string name="app_name">NotePad</string>
	<string name="separation"> | </string>
	

	<string name="error_title">Error</string>
	<string name="error_message">Error loading note</string>
</resources>

 

 

 

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
          http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<!-- Declare the contents of this Android application.  The namespace
     attribute brings in the Android platform namespace, and the package
     supplies a unique name for the application.  When writing your
     own application, the package name must be changed from "com.example.*"
     to come from a domain that you own or have control over. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cticc.notepad"
>
    <application android:icon="@drawable/app_notes"
        android:label="@string/app_name"
    >
        <provider android:name="NotePadProvider"
            android:authorities="com.google.provider.NotePad"
        />

        <activity android:name="NotesList">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="android.intent.action.PICK" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.GET_CONTENT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>
        </activity>
        
        <activity android:name="NoteEditor"
            android:theme="@android:style/Theme.Light"
            android:label="@string/label_edit"
        >
            <!-- This filter says that we can view or edit the data of
                 a single note -->
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.EDIT" />
                <action android:name="com.android.notepad.action.EDIT_NOTE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
            </intent-filter>

            <!-- This filter says that we can create a new note inside
                 of a directory of notes. -->
            <intent-filter>
                <action android:name="android.intent.action.INSERT" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
            </intent-filter>

        </activity>
        
        
    </application>
</manifest>

 

 

上几张图片:

 



 


 



 
 

 

 

在下面这个界面,我本来是想把edit换成delete,可是在onPrepareOptionsMenu()中换了之后菜单就出不来了。

郁闷~~~~

 

 



 

  • 大小: 28.6 KB
  • 大小: 21.8 KB
  • 大小: 23.9 KB
  • 大小: 23.2 KB
分享到:
评论
4 楼 taro3372 2010-01-27  
在你的NoteEditor.java这个文档里面的129行
setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
我不太懂为啥给这个用intent的action的传值呢?难道说这样是活用?
而且在这里setResult是无意义的吧,其他地方没有捕获这个intent,这个activity也不是通过Startactivityforresult来的
3 楼 java.lang.Object 2009-09-17  
xiaohei_119 写道
有没有教程类的东西。我也是刚刚接触。所以不知道如何下手。也没有找到好的资料。如果有请帮忙发到254635362@qq.com

像你这样到处留邮箱的行为是不对的,也是没有用的,谁会吃饱了撑得发东西给你邮箱?
2 楼 xiaohei_119 2009-09-16  
有没有教程类的东西。我也是刚刚接触。所以不知道如何下手。也没有找到好的资料。如果有请帮忙发到254635362@qq.com
1 楼 buyajun 2009-07-17  
你把src 也打个包 连同  .project 和 .class  也发布啊。

我们直接 import 不就可以了么

好麻烦呢

相关推荐

    NotepadDemo

    4. **个人笔记**:对于喜欢手写笔记的人来说,NotepadDemo提供了一个电子化平台,既保留了手写的亲切感,又便于保存和查找。 综上所述,NotepadDemo凭借其独特的手写板功能,为用户带来了全新的文本编辑体验。无论...

    带Androidlogger插件的notepad++

    3. **Androidlogger插件**:Androidlogger插件为Notepad++添加了查看和解析Android Logcat日志的功能。Logcat是Android系统中的一个命令行工具,用于记录应用程序和系统服务的调试信息。通过这个插件,开发者可以...

    notepad笔记本

    9. **版本更新**:随着Windows系统的更新,Notepad也会有所改进,例如Windows 10的Notepad增加了对UTF-8无BOM编码的支持。 总的来说,虽然Notepad功能简单,但它在日常使用中扮演了重要角色,特别是在处理文本和...

    android版的notepad的源码

    在Android平台上,Notepad是一款非常基础的记事本应用,它的源码对于初学者和开发者来说,是一个很好的学习资源。这个源码可以帮助我们理解Android应用的基本结构、UI设计、数据存储以及事件处理等核心概念。 1. **...

    notepad++笔记

    Notepad++是一款非常受欢迎的免费源代码...综上所述,Notepad++以其免费、开源、高效的特点,成为开发者们的首选工具之一。通过不断学习和掌握Notepad++的各种功能,开发者能够提升编程效率,享受更佳的代码编写体验。

    2011.09.23——— android sample之Notepad(context menu)

    标题中的“2011.09.23——— android sample之Notepad(context menu)”表明这是一个关于Android应用开发的示例项目,具体是针对Notepad应用的上下文菜单(Context Menu)功能的实践。在Android开发中,上下文菜单是...

    Notepad++插件AndroidLogger 64位版本

    AndroidLogger是Notepad++的一个查看android log的插件,不过由于近期插件没有更新,而自己使用的NDP7.6已经是64位版本了,不能再直接使用了。于是找来源码重新发布了64位版本,希望能有所帮助。

    Notepad++ 插件,AndroidLogger.V1.2.7. 可以让安卓日志自动显示颜色

    此外,压缩包中的AndroidLogger.src.zip文件包含了插件的源代码,如果你对插件的工作原理感兴趣,或者想要进行二次开发,这是一个很好的学习资源。 Config文件夹可能包含了插件的配置文件或默认设置,这取决于插件...

    android入门Notepad+源代码.rar

    Android入门教程:Notepad+源代码解析 在Android开发领域,初学者往往需要从简单的项目开始学习,以便逐步掌握这个强大的移动平台的工作原理。"Notepad+"是一个经典的入门级项目,它模仿了桌面操作系统中的记事本...

    Android 4.0 Notepad 源代码

    1. **Android SDK和API级别**:Android 4.0(API级别14)引入了许多新特性和改进,包括UI设计、性能优化以及对多任务处理的支持。Notepad源代码将展示如何利用这些特性来创建一个用户友好的应用。 2. **Activity...

    安卓Android源码——NotePad便签.zip

    《安卓Android源码——NotePad便签》 在Android操作系统中,NotePad是...通过研究NotePad的源码,开发者不仅能掌握Android基本的开发技术,还能了解到良好的编程实践,为自己的Android应用开发之路打下坚实的基础。

    Notepad 文本编辑器 5.9版本

    Notepad是一款广受欢迎的免费文本编辑器,专为Windows操作系统设计。它以其简洁的界面、高效的操作和对程序员友好的特性而闻名。在Notepad 5.9版本中,我们可能会发现以下一些重要的更新和特性: 1. **增强的性能**...

    Android 平台 改进的Notepad源代码

    本人自己学习Android时写的学习程序,这个跟Android官网的Demo程序是不一样的,增加了一些改进,比方说带下划线的EditText,仅供参考,注意我在写这个程序是把名字改成了DailyWriter,在Nexus One上用还不错的。

    android练习-notePad

    【标题】"Android练习-notePad" 是一个针对Android平台的简单笔记应用的开发实践项目,旨在帮助开发者加深对Android编程的理解和应用。这个项目可能是基于一个基础的记事本应用程序,提供基本的文本编辑和存储功能,...

    开源国产文本编辑器Notepad介绍.docx

    6. 二进制文件显示和跳转查看:Notepad--支持二进制文件显示和跳转查看,能够查看二进制文件的内容。 7. 文件夹对比及同步:Notepad--支持文件夹对比及同步,能够同步文件夹中的文件。 8. 文件编码批量修改:Notepad...

    android自定义View之NotePad出鞘记

    4. **状态保存与恢复**:Android的`onSaveInstanceState()`和`onRestoreInstanceState()`方法用于在配置改变时(如屏幕旋转)保存和恢复View的状态。对于NotePad,这可能包括当前页面、颜色选择等信息。 5. **动画...

    Android 小应用程序

    NotePad是一个基础的、用于记录和管理简单文本笔记的应用,它是Android开发初学者常用来学习和理解Android应用程序框架的实例。 在Android开发中,NotePad应用展示了以下几个关键知识点: 1. **Activity**:...

    Notepad android 记事本 源码

    《Android SDK 1.6与Eclipse环境下的Notepad记事本源码解析》 在Android应用开发领域,Notepad项目是初学者入门的经典案例,它是一个简单的记事本应用程序,帮助开发者理解基本的Android UI设计、数据存储以及事件...

    NotePad-master_基于安卓的笔记本APP_

    【标题】"NotePad-master" 是一个专门为安卓平台设计的笔记本应用程序项目,它提供了一个全面的解决方案,让用户能够在移动设备上方便地管理他们的笔记。这个应用不仅具备基本的笔记创建、编辑和删除功能,还支持...

    win7 64 位 安卓logger Notepad++ 工具,下载解压后直接使用。

    Notepad++是一个流行的开源文本编辑器,它支持多种编程语言,包括用于Android开发的编程语言如Java。在描述中再次强调了该工具包适用于Notepad++,并且提示用户下载解压后即可直接使用,意味着这是一个便捷的、预...

Global site tag (gtag.js) - Google Analytics