fangyukuan

永无止境的追求...追求卓越!!!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

记事本2

在这个练习我们 将增加一个Activity到我们的应用程序。而且用户不但可以创建记事本,编辑记事本还可以删除已存在的记事本。

通过这个练习我们将可以学习到下面几个知识点:

创建一个新的Activity 并添加到manifest

l 使用startActivityForResult()异步调用其它Activity 

Activity之间传递数据包

怎么作用更多高级屏幕布局

怎么创建一个菜单上下文

 

1)先改个错

官方提供的notepad2有一个方法写错了。

打开src/com/android/demo/notepad2/Notepadv2.java定位到97行。

把方法onCreateOptionsMenu改成onCreateContextMenu

2)新增的字符串和方法

打开字符串资源(res/values/strings.xml),增加了几个字符串。

    <string name="menu_delete">Delete Note</string>

    <string name="title">Title</string>

    <string name="body">Body</string>

    <string name="confirm">Confirm</string>

    <string name="edit_note">Edit Note</string>

 

Notepadv2添加了一个成员mNotesCursor

private Cursor mNotesCursor;

 

fillData()方法做相应修改,粉红色部分。

    private void fillData()

    {

        // Get all of the rows from the database and create the item list

        mNotesCursor = mDbHelper.fetchAllNotes();

        startManagingCursor(mNotesCursor);

 

        // Create an array to specify the fields we want to display in the list

        // (only TITLE)

        String[] from = new String[]

        { NotesDbAdapter.KEY_TITLE };

 

        // and an array of the fields we want to bind those fields to (in this

        // case just text1)

        int[] to = new int[]

        { R.id.text1 };

 

        // Now create a simple cursor adapter and set it to display

        SimpleCursorAdapter notes = new SimpleCursorAdapter(this,

                R.layout.notes_row, mNotesCursor, from, to);

        setListAdapter(notes);

    }

 

添加了几个新的方法

onCreateContextMenu()

onContextItemSelected()

onListItemClick()

onActivityResult()

3)创建一个可以删除记事本的菜单

在方法onCreate最后添加菜单注册(粉红色)

    public void onCreate(Bundle savedInstanceState)

    {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.notes_list);

        mDbHelper = new NotesDbAdapter(this);

        mDbHelper.open();

        fillData();

        registerForContextMenu(getListView());

    }

 

public void registerForContextMenu (View view)view注册一个上下文菜单,当菜单显示时,将会调用方法 onCreateContextMenu(ContextMenu, View, ContextMenuInfo)

getListView()ListView对象。

 

onCreateContextMenu增加代码

    @Override

    public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo)

    {

        super.onCreateContextMenu(menu, v, menuInfo);

        menu.add(0, DELETE_ID, 0, R.string.menu_delete);

    }

 

4)onContextItemSelected增加代码

我已经为我们的ListView 注册了上下文件菜单并且定义了上下文菜单项,菜单项被选中时,将会调用onContextItemSelected

    @Override

    public boolean onContextItemSelected(MenuItem item)

    {

        switch(item.getItemId())

        {

        case DELETE_ID:

            AdapterContextMenuInfo info = ()item.getMenuInfo();

            mDbHelper.deleteNote(info.id);

            return true;

        }

        return super.onContextItemSelected(item);

    }

AdapterContextMenuInfoonCreateContextMenu提供额外的菜单信息。

这里的id就是菜单项的位置。

 

5)创建记事本createNote

这里跟第一个练习不同。

@Override

private void ()

{

    Intent i = new Intent(this, NoteEdit.class);

    (i, ACTIVITY_CREATE);

}

这里我们用了“意图”。意图是一个操作的描述。

startActivityForResultActivity ,并且当启动完后,将回调onActivityResult

startActivity也可以启动一个Activity,但它不回调通知我们。

关于“意图”的更多内容请参考

http://androidappdocs.appspot.com/guide/topics/intents/intents-filters.html

注意:这里的NoteEdit现在还没有创建,等一下将会创建。

 

6)onListItemClick

    @Override

    protected void onListItemClick(ListView l, View v, int position, long id)

    {

        super.onListItemClick(l, v, position, id);

        Cursor c =  ;

        c.(position);

        Intent i = new Intent(this, NoteEdit.class);

        i.putExtra(NotesDbAdapter.KEY_ROWID, id);

        i.(NotesDbAdapter.KEY_TITLE, c.getString(

                c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));

        i.putExtra(NotesDbAdapter.KEY_BODY, c.getString(

                c.(NotesDbAdapter.KEY_BODY)));

        (i, ACTIVITY_EDIT);

    }

当用户单击列表某一项时。将会调用

void onListItemClick(ListView l, View v, int position, long id);

 

它一共有四个参数:

ListView就是用户单击项所在的列表

View 就是我们单击项的视图

Position 单击在列表的位置

Id 单击项的id

 

通过moveToPosition把光标移到相应位置。

putExtra增加额外的数据到意图里。

getColumnIndexOrThrow返回给定列名称的从零开始的索引

 

注意:这里之所以把光标mNotesCursor赋给一个本地的光标,是为了优化。存取本地变量效率比较高。

 

7) 回调函数onActivityResult

    @Override

    protected void onActivityResult(int requestCode, int resultCode,Intent intent)

    {

        super.onActivityResult(requestCode, resultCode, intent);

       

        Bundle extras = intent.();

 

        switch (requestCode)

        {

        case  :

            String title = extras.getString(NotesDbAdapter.KEY_TITLE);

            String body = extras.getString(NotesDbAdapter.KEY_BODY);

            mDbHelper.createNote(title, body);

            fillData();

            break;

        case  :

            Long mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);

            if (mRowId != null)

            {

                String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE);

                String editBody = extras.getString(NotesDbAdapter.KEY_BODY);

                mDbHelper.updateNote(mRowId, editTitle, editBody);

            }

            fillData();

            break;

        }

    }

 

Bundle 相当于一个容器。

getExtras从意图里取额外的数据。(那些数据是通过putExtra加到意图里的)

我们之前的startActivityForResult调用给第二个参数传了ACTIVITY_CREATEACTIVITY_EDIT在这里用一个switch来区别是哪个回调过来。

ACTIVITY_CREATE里的代码。这里是创建一个记事本,看看他们跟第一个练习(http://www.cnblogs.com/fangyukuan/archive/2010/04/05/1704806.html,方法 createNote的差别。

 

8)note_edit.xml

打开res/layout/

  

这个是我们的编辑记事本的界面

 

<?xml version="1.0" encoding="utf-8"?>

 

<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:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="@string/title" />

        <EditText android:id="@+id/title"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:layout_weight="1"/>

    </LinearLayout>

 

    <TextView android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="@string/body" />

    <EditText android:id="@+id/body"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:layout_weight="1"

        android:scrollbars="vertical" />

   

    <Button android:id="@+id/confirm"

        android:text="@string/confirm"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" />

 

</LinearLayout>

 

9)创建NoteEdit 

com.android.demo.notepad2右键。New > Class

在弹出的对话框:

name输入:NoteEdit 

Superclass输入:android.app.Activity

然后点击完成按钮。

在打开的NoteEdit类中,右键,选择Source > Override/Implement Methods...

找到onCreate(Bundle)在前面打勾。并点击OK

这样就可以对方法onCreate进行重写。

    @Override

    protected void onCreate(Bundle savedInstanceState)

    {

        // TODO Auto-generated method stub

        super.onCreate(savedInstanceState);

    }

 

10) 完善NoteEdit 类的onCreate

声明三个成员

    private EditText mTitleText;

    private EditText mBodyText;

    private Long mRowId;

 

onCreate里加以下代码

    setContentView(R.layout.note_edit);

 

    // 通过id找到相应组件

    mTitleText = (EditText)findViewById(R.id.title);

    mBodyText = (EditText)findViewById(R.id.body);

    Button confirmButton = (Button)findViewById(R.id.confirm);

 

// 从意图取数据,并应用到想关组件,如设置标题等。

    mRowId = null;

    Bundle extras = getIntent().getExtras();

    if (null != extras)

    {

        String title = extras.getString(NotesDbAdapter.KEY_TITLE);

        String body = extras.getString(NotesDbAdapter.KEY_BODY);

        mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);

       

        if (null != title)

        {

            mTitleText.setText(title);

        }

        if (null != body)

        {

            mBodyText.setText(body);

        }

    }

           

// 侦听按钮单击事件

        confirmButton.setOnClickListener(new View.OnClickListener()

        {

            @Override

            public void (View v)

            {

                // TODO Auto-generated method stub

               

            }

        });

 

 

11)完善onClick

@Override

            public void onClick(View v)

            {

                // 创建一个Bundle并把要返回的数据放到里面去。

                Bundle bundle = new Bundle();

               

                bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());

                bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());

                if (null != mRowId)

                {

                    bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);

                }

               

                // 创建一个意图,差把Bundle加进去,返回差结束这个Activity

                Intent mIntent = new Intent();

                mIntent.putExtras(bundle);

                setResult(RESULT_OK, mIntent);

                finish();

            }

 

12) 修改AndroidManifest

l 双击文件AndroidManifest.xml

l 单击下面的标签Application 

l  Application Nodes模块单击Add按钮。

l 在弹出的对话框中选择Activity

 Application Nodes模块单击Activity,在右边的Name输入:.NoteEdit

 

选择AndroidManifest.xml标签看源代码可以看到。我们新增的代码。

<activity android:name=".NoteEdit"></activity>

这样系统就知道我们新建了一个activity而且可以被调用。

13)运行

 

 

 

点击Add Note增加一个记事本。这个时候将出现下面的界面。

 输入标标题和内容

 

 

 

 

点击确定按钮

14) 仍然存在错误

当我们在编辑记事本时,如果没有点击提交按钮,而是按了返回按钮的时候。将出现错误的提示。

 

返回到记事本时,我们可以发现,刚才编辑的内容不见了。记事本3将解决这个问题。

http://www.cnblogs.com/fangyukuan/archive/2010/04/07/1704841.html

 

2010-4-7

fangyukuan

 

posted on 2010-04-07 01:33  fangyukuan  阅读(1026)  评论(0编辑  收藏  举报