论坛首页 移动开发技术论坛

Android笔记之二:改进的NotePad Demo

浏览 14504 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-04-22   最后修改:2009-04-22

 下面是对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
   发表时间:2009-07-17  
你把src 也打个包 连同  .project 和 .class  也发布啊。

我们直接 import 不就可以了么

好麻烦呢
0 请登录后投票
   发表时间:2009-09-16  
有没有教程类的东西。我也是刚刚接触。所以不知道如何下手。也没有找到好的资料。如果有请帮忙发到254635362@qq.com
0 请登录后投票
   发表时间:2009-09-17  
xiaohei_119 写道
有没有教程类的东西。我也是刚刚接触。所以不知道如何下手。也没有找到好的资料。如果有请帮忙发到254635362@qq.com

像你这样到处留邮箱的行为是不对的,也是没有用的,谁会吃饱了撑得发东西给你邮箱?
0 请登录后投票
   发表时间:2010-01-27  
在你的NoteEditor.java这个文档里面的129行
setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
我不太懂为啥给这个用intent的action的传值呢?难道说这样是活用?
而且在这里setResult是无意义的吧,其他地方没有捕获这个intent,这个activity也不是通过Startactivityforresult来的
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics