Android添加書簽(二) – Android移動開發技術文章_手機開發 Android移動開發教學課程

運行結果:
 

Bookmarker.java:
Java代碼 
package com.iaiai; 
 
import android.app.Activity; 
import android.app.AlertDialog; 
import android.app.Dialog; 
import android.content.ContentResolver; 
import android.content.ContentValues; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.net.Uri; 
import android.os.Bundle; 
import android.provider.Browser; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ImageButton; 
import android.widget.ListView; 
 
/**
 * 
 * <p>
 * Title: Bookmarker.java
 * </p>
 * <p>
 * E-Mail: 176291935@qq.com
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-8-29
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */ 
public class Bookmarker extends Activity implements OnItemClickListener, 
        OnClickListener { 
     
    /** Called when the activity is first created. */ 
    private ListView mListView; 
    private BookmarkAdapter bookmarkAdapter; 
    private ImageButton upButton; 
    private ImageButton downButton; 
    private ImageButton deleteButton; 
    private ImageButton launchButton; 
    private ImageButton topButton; 
    private ImageButton bottomButton; 
    private static final int DIALOG_YES_NO_MESSAGE = 1; 
    private static final int DIALOG_WELCOME = 2; 
    private int currentPos = -1; 
 
    private static final String PREFS_NAME = "BookmarkerPrefs"; 
    private static final String LAUNCHED_KEY = "LAUNCHED"; 
    private static final int MENU_ABOUT = 0; 
    private static final int MENU_ADD = 1; 
 
    @Override 
    public void onCreate(Bundle icicle) { 
        super.onCreate(icicle); 
        setContentView(R.layout.main); 
         
        ContentValues inputValue = new ContentValues();   
        inputValue.put(android.provider.Browser.BookmarkColumns.BOOKMARK, 1);   
        inputValue.put(android.provider.Browser.BookmarkColumns.TITLE, "丸子");   
        inputValue.put(android.provider.Browser.BookmarkColumns.URL, "http://iaiai.iteye.com");                             
        ContentResolver cr = getContentResolver();   
        Uri uri = cr.insert(android.provider.Browser.BOOKMARKS_URI, inputValue); 
 
        bookmarkAdapter = new BookmarkAdapter(this, "");// new 
                                                        // ArrayAdapter<Bookmark>(this, 
                                                        // android.R.layout.simple_list_item_single_choice,bookmarks); 
        mListView = ((ListView) findViewById(R.id.mylistview)); 
        mListView.setAdapter(bookmarkAdapter); 
        mListView.setOnItemClickListener(this); 
 
        upButton = (ImageButton) findViewById(R.id.upbutton); 
        downButton = (ImageButton) findViewById(R.id.downbutton); 
        deleteButton = (ImageButton) findViewById(R.id.deletebutton); 
        launchButton = (ImageButton) findViewById(R.id.launchbutton); 
        topButton = (ImageButton) findViewById(R.id.topbutton); 
        bottomButton = (ImageButton) findViewById(R.id.bottombutton); 
 
        upButton.setOnClickListener(this); 
        downButton.setOnClickListener(this); 
        deleteButton.setOnClickListener(this); 
        launchButton.setOnClickListener(this); 
        topButton.setOnClickListener(this); 
        bottomButton.setOnClickListener(this); 
 
        // if we have some bookmarks select the first and start everything 
        if (bookmarkAdapter.getCount() > 0) { 
            bookmarkAdapter.initialiseAllRows(); 
            currentPos = 0; 
            bookmarkAdapter.setSelected(currentPos); 
        } 
 
        // Make sure the welcome message only appears on first launch 
        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); 
        if (settings != null) { 
            boolean launchedPreviously = settings.getBoolean(LAUNCHED_KEY, 
                    false); 
            if (!launchedPreviously) { 
                showDialog(DIALOG_WELCOME); 
                SharedPreferences.Editor editor = settings.edit(); 
                editor.putBoolean(LAUNCHED_KEY, true); 
                editor.commit(); 
            } 
        } 
    } 
 
    /**
     * Invoked during init to give the Activity a chance to set up its Menu.
     * 
     * @param menu
     *            the Menu to which entries may be added
     * @return true
     */ 
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
        super.onCreateOptionsMenu(menu); 
        menu.add(0, MENU_ADD, 0, "Add New Bookmark").setIcon( 
                android.R.drawable.ic_menu_info_details); 
        menu.add(0, MENU_ABOUT, 1, R.string.menu_about).setIcon( 
                android.R.drawable.ic_menu_info_details); 
 
        return true; 
    } 
 
    /**
     * Invoked when the user selects an item from the Menu.
     * 
     * @param item
     *            the Menu entry which was selected
     * @return true if the Menu item was legit (and we consumed it), false
     *         otherwise
     */ 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
        if (item.getItemId() == MENU_ABOUT) { 
            showDialog(DIALOG_WELCOME); 
            return true; 
        } else if (item.getItemId() == MENU_ADD) { 
            Browser.saveBookmark(this, "New Bookmark", "http://"); 
            bookmarkAdapter.notifyDataSetChanged(); 
            return true; 
        } else 
            return false; 
    } 
 
    public void onItemClick(AdapterView<?> arg0, View view, int position, 
            long id) { 
        currentPos = position; 
        bookmarkAdapter.setSelected(position); 
    } 
 
    public void onClick(View v) { 
 
        if (v == upButton && currentPos > 0) { 
            bookmarkAdapter.moveItemUp(currentPos); 
            currentPos–; 
        } else if (v == downButton && currentPos >= 0 
                && currentPos < bookmarkAdapter.getCount() – 1) { 
            bookmarkAdapter.moveItemDown(currentPos); 
            currentPos++; 
        } else if (v == deleteButton) { 
            showDialog(DIALOG_YES_NO_MESSAGE); 
        } else if (v == topButton) { 
            currentPos = bookmarkAdapter.moveToTop(currentPos); 
        } else if (v == bottomButton) { 
            currentPos = bookmarkAdapter.moveToBottom(currentPos); 
        } else if (v == launchButton) { 
            String url = bookmarkAdapter.getUrl(currentPos); 
            if (url != null) { 
                Intent i = new Intent("android.intent.action.VIEW", 
                        Uri.parse(url)); 
                startActivity(i); 
            } 
        } 
 
    } 
 
    protected Dialog onCreateDialog(int id) { 
        if (id == DIALOG_YES_NO_MESSAGE) { 
            return new AlertDialog.Builder(Bookmarker.this) 
                    .setIcon(android.R.drawable.ic_dialog_alert) 
                    .setTitle("Confirm Delete") 
                    .setMessage( 
                            "Are you sure you want to delete this bookmark?") 
                    .setPositiveButton("OK", 
                            new DialogInterface.OnClickListener() { 
                                public void onClick(DialogInterface dialog, 
                                        int whichButton) { 
                                    bookmarkAdapter.deleteRow(currentPos); 
                                } 
                            }) 
                    .setNegativeButton("Cancel", 
                            new DialogInterface.OnClickListener() { 
                                public void onClick(DialogInterface dialog, 
                                        int whichButton) { 
                                    // do nothing 
                                } 
                            }).create(); 
        } else if (id == DIALOG_WELCOME) { 
            String message = getString(R.string.welcome); 
            if (bookmarkAdapter.getCount() < 1) { 
                message += getString(R.string.nomarks); 
            } 
 
            AlertDialog dialog = new AlertDialog.Builder(Bookmarker.this) 
                    .create();// new AlertDialog(Bookmarker.this); 
            dialog.setTitle("Welcome"); 
            dialog.setMessage(message); 
            dialog.setButton("OK", new DialogInterface.OnClickListener() { 
                public void onClick(DialogInterface dialog, int whichButton) { 
                    if (bookmarkAdapter.getCount() < 1) { 
                        finish(); 
                    } 
                } 
            }); 
 
            dialog.setCancelable(true); 
            return dialog; 
        } else 
            return null; 
    } 


BookmarkItem.java:
Java代碼 
package com.iaiai; 
 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.view.LayoutInflater; 
import android.widget.ImageView; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 
 
/**
 * 
 * <p>
 * Title: BookmarkItem.java
 * </p>
 * <p>
 * E-Mail: 176291935@qq.com
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-8-29
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */ 
class BookmarkItem extends RelativeLayout { 
 
    private TextView mTextView; // title 
    private TextView mUrlText; // url 
    private ImageView mImageView; // favicon 
    private LayoutInflater mFactory; 
    private RelativeLayout mBookmarkItem; 
 
    /**
     * Instantiate a bookmark item, including a default favicon.
     * 
     * @param context
     *            The application context for the item.
     */ 
    BookmarkItem(Context context) { 
        super(context); 
 
        mFactory = LayoutInflater.from(context); 
        mFactory.inflate(R.layout.bookmark_item, this); 
        mTextView = (TextView) findViewById(R.id.title); 
        mUrlText = (TextView) findViewById(R.id.url); 
        mImageView = (ImageView) findViewById(R.id.favicon); 
        mBookmarkItem = (RelativeLayout) findViewById(R.id.bookmarkitem); 
    } 
 
    public void setSelected() { 
        mBookmarkItem.setBackgroundColor(0xFFFF6633); 
        mUrlText.setTextColor(0xFF000000); 
    } 
 
    public void setUnselected() { 
        mBookmarkItem.setBackgroundColor(0xFF000000); 
        mUrlText.setTextColor(0xFFAAAAAA); 
    } 
 
    /**
     * Copy this BookmarkItem to item.
     * 
     * @param item
     *            BookmarkItem to receive the info from this BookmarkItem.
     */ 
    /* package */void copyTo(BookmarkItem item) { 
        item.mTextView.setText(mTextView.getText()); 
        item.mUrlText.setText(mUrlText.getText()); 
        item.mImageView.setImageDrawable(mImageView.getDrawable()); 
    } 
 
    /**
     * Return the name assigned to this bookmark item.
     */ 
    /* package */CharSequence getName() { 
        return mTextView.getText(); 
    } 
 
    /**
     * Return the TextView which holds the name of this bookmark item.
     */ 
    /* package */TextView getNameTextView() { 
        return mTextView; 
    } 
 
    /**
     * Set the favicon for this item.
     * 
     * @param b
     *            The new bitmap for this item. If it is null, will use the
     *            default.
     */ 
    /* package */void setFavicon(Bitmap b) { 
        if (b != null) { 
            mImageView.setImageBitmap(b); 
        } else { 
            mImageView.setImageResource(R.drawable.app_web_browser_sm); 
        } 
    } 
 
    /**
     * Set the new name for the bookmark item.
     * 
     * @param name
     *            The new name for the bookmark item.
     */ 
    /* package */void setName(String name) { 
        mTextView.setText(name); 
    } 
 
    /**
     * Set the new url for the bookmark item.
     * 
     * @param url
     *            The new url for the bookmark item.
     */ 
    /* package */void setUrl(String url) { 
        mUrlText.setText(url); 
    } 


BookmarkAdapter.java:
Java代碼 
package com.iaiai; 
 
import java.io.ByteArrayOutputStream; 
import java.util.Date; 
 
import android.content.ContentResolver; 
import android.content.ContentUris; 
import android.content.ContentValues; 
import android.database.ContentObserver; 
import android.database.Cursor; 
import android.database.DataSetObserver; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.net.Uri; 
import android.os.Bundle; 
import android.os.Handler; 
import android.provider.Browser; 
import android.view.View; 
import android.view.ViewGroup; 
import android.webkit.WebIconDatabase; 
import android.webkit.WebIconDatabase.IconListener; 
import android.widget.BaseAdapter; 
 
/**
 * 
 * <p>
 * Title: BookmarkAdapter.java
 * </p>
 * <p>
 * E-Mail: 176291935@qq.com
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-8-29
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */ 
class BookmarkAdapter extends BaseAdapter { 
 
    private Cursor mCursor; 
    private int mCount; 
    private ContentResolver mContentResolver; 
    private ChangeObserver mChangeObserver; 
    private DataSetObserver mDataSetObserver; 
    private boolean mDataValid; 
    private Bookmarker mBookmarker; 
 
    // Implementation of WebIconDatabase.IconListener 
    private class IconReceiver implements IconListener { 
        public void onReceivedIcon(String url, Bitmap icon) { 
            updateBookmarkFavicon(mContentResolver, url, icon); 
        } 
    } 
 
    // Instance of IconReceiver 
    private final IconReceiver mIconReceiver = new IconReceiver(); 
 
    /**
     * Create a new BrowserBookmarksAdapter.
     * 
     * @param b
     *            BrowserBookmarksPage that instantiated this. Necessary so it
     *            will adjust its focus appropriately after a search.
     */ 
    public BookmarkAdapter(Bookmarker b, String curPage) { 
        this(b, curPage, false); 
    } 
 
    /**
     * Create a new BrowserBookmarksAdapter.
     * 
     * @param b
     *            BrowserBookmarksPage that instantiated this. Necessary so it
     *            will adjust its focus appropriately after a search.
     */ 
    public BookmarkAdapter(Bookmarker b, String curPage, boolean createShortcut) { 
        mDataValid = false; 
        mBookmarker = b; 
        mContentResolver = b.getContentResolver(); 
        mChangeObserver = new ChangeObserver(); 
        mDataSetObserver = new MyDataSetObserver(); 
        // FIXME: Should have a default sort order that the user selects. 
        search(); 
        // FIXME: This requires another query of the database after the 
        // initial search(null). Can we optimize this? 
        Browser.requestAllIcons(mContentResolver, 
                Browser.BookmarkColumns.FAVICON + " is NULL AND " 
                        + Browser.BookmarkColumns.BOOKMARK + " == 1", 
                mIconReceiver); 
    } 
 
    public void initialiseAllRows() { 
        int processed = 0; 
 
        // ensures each row has a created time 
        while (processed < mCount) { 
            for (int i = 0; i < mCount; i++) { 
                Bundle thisRow = getRow(i, true); 
                Long thisCreateTime = thisRow 
                        .getLong(Browser.BookmarkColumns.CREATED); 
                if (thisCreateTime == null || thisCreateTime < 900) { 
                    // get createTime of row above and subtract 1000; 
                    long createTime = (mCount – i) * 1000; 
                    if (i > 0) { 
                        Bundle prevRow = getRow(i, true); 
                        Long prevCreateTime = prevRow 
                                .getLong(Browser.BookmarkColumns.CREATED); 
                        if (prevCreateTime != null && prevCreateTime > 1001) { 
                            createTime = prevCreateTime – 1000; 
                        } 
                    } 
 
                    thisRow.putLong(Browser.BookmarkColumns.CREATED, createTime); 
                    updateRow(thisRow, true); 
                    break;// underlying dataset has updated so quit the loop and 
                            // start again 
                } 
                processed = i + 1; 
            } 
        } 
    } 
 
    /**
     * Return a hashmap with one row's Title, Url, and favicon.
     * 
     * @param position
     *            Position in the list.
     * @return Bundle Stores title, url of row position, favicon, and id for the
     *         url. Return a blank map if position is out of range.
     */ 
    public Bundle getRow(int position, boolean includeCreateTime) { 
        Bundle map = new Bundle(); 
        if (position < 0 || position >= mCount) { 
            return map; 
        } 
        mCursor.moveToPosition(position); 
        String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX); 
        map.putString(Browser.BookmarkColumns.TITLE, 
                mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX)); 
        map.putString(Browser.BookmarkColumns.URL, url); 
        byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX); 
        if (data != null) { 
            map.putByteArray("FAV_BYTES", data); 
            map.putParcelable(Browser.BookmarkColumns.FAVICON, 
                    BitmapFactory.decodeByteArray(data, 0, data.length)); 
        } 
 
        if (includeCreateTime && createdColumnIndex != -1) { 
            Long createTime = mCursor.getLong(createdColumnIndex); 
            if (createTime != null && createTime != 0) { 
                map.putLong(Browser.BookmarkColumns.CREATED, createTime); 
            } 
        } 
 
        map.putInt("id", mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX)); 
 
        return map; 
    } 
 
    /**
     * Update a row in the database with new information. Requeries the database
     * if the information has changed.
     * 
     * @param map
     *            Bundle storing id, title and url of new information
     */ 
    public void updateRow(Bundle map, boolean includeCreateTime) { 
 
        // Find the record 
        int id = map.getInt("id"); 
        int position = -1; 
        for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor 
                .moveToNext()) { 
            if (mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX) == id) { 
                position = mCursor.getPosition(); 
                break; 
            } 
        } 
        if (position < 0) { 
            return; 
        } 
 
        mCursor.moveToPosition(position); 
        ContentValues values = new ContentValues(); 
        String title = map.getString(Browser.BookmarkColumns.TITLE); 
        if (!title.equals(mCursor 
                .getString(Browser.HISTORY_PROJECTION_TITLE_INDEX))) { 
            values.put(Browser.BookmarkColumns.TITLE, title); 
        } 
        String url = map.getString(Browser.BookmarkColumns.URL); 
        if (!url.equals(mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX))) { 
            values.put(Browser.BookmarkColumns.URL, url); 
        } 
 
        byte[] favicon = map.getByteArray("FAV_BYTES"); 
        if (favicon != null) { 
            values.put(Browser.BookmarkColumns.FAVICON, favicon); 
        } 
 
        if (includeCreateTime) { 
            Long createTime = map.getLong(Browser.BookmarkColumns.CREATED); 
            if (createTime != null) 
                values.put(Browser.BookmarkColumns.CREATED, createTime); 
        } 
 
        if (values.size() > 0 
                && mContentResolver.update(Browser.BOOKMARKS_URI, values, 
                        "_id = " + id, null) != -1) { 
            refreshList(); 
        } 
    } 
 
    /**
     * Delete a row from the database. Requeries the database. Does nothing if
     * the provided position is out of range.
     * 
     * @param position
     *            Position in the list.
     */ 
    public void deleteRow(int position) { 
        if (position < 0 || position >= getCount()) { 
            return; 
        } 
        mCursor.moveToPosition(position); 
        String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX); 
        WebIconDatabase.getInstance().releaseIconForPageUrl(url); 
        Uri uri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI, 
                mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX)); 
        int numVisits = mCursor.getInt(Browser.HISTORY_PROJECTION_VISITS_INDEX); 
        if (0 == numVisits) { 
            mContentResolver.delete(uri, null, null); 
        } else { 
            // It is no longer a bookmark, but it is still a visited site. 
            ContentValues values = new ContentValues(); 
            values.put(Browser.BookmarkColumns.BOOKMARK, 0); 
            mContentResolver.update(uri, values, null, null); 
        } 
        refreshList(); 
    } 
 
    /**
     * Refresh list to recognize a change in the database.
     */ 
    public void refreshList() { 
        searchInternal(); 
    } 
 
    /**
     * Search the database for bookmarks that match the input string.
     * 
     * @param like
     *            String to use to search the database. Strings with spaces are
     *            treated as having multiple search terms using the OR operator.
     *            Search both the title and url.
     */ 
    public void search() { 
        searchInternal(); 
    } 
 
    /**
     * Update the bookmark's favicon.
     * 
     * @param cr
     *            The ContentResolver to use.
     * @param url
     *            The url of the bookmark to update.
     * @param favicon
     *            The favicon bitmap to write to the db.
     */ 
    /* package */static void updateBookmarkFavicon(ContentResolver cr, 
            String url, Bitmap favicon) { 
        if (url == null || favicon == null) { 
            return; 
        } 
        // Strip the query. 
        int query = url.indexOf('?'); 
        String noQuery = url; 
        if (query != -1) { 
            noQuery = url.substring(0, query); 
        } 
        url = noQuery + '?'; 
        // Use noQuery to search for the base url (i.e. if the url is 
        // http://www.yahoo.com/?rs=1, search for http://www.yahoo.com) 
        // Use url to match the base url with other queries (i.e. if the url is 
        // http://www.google.com/m, search for 
        // http://www.google.com/m?some_query) 
        final String[] selArgs = new String[] { noQuery, url }; 
        final String where = "(" + Browser.BookmarkColumns.URL + " == ? OR " 
                + Browser.BookmarkColumns.URL + " GLOB ? || '*') AND " 
                + Browser.BookmarkColumns.BOOKMARK + " == 1"; 
        final String[] projection = new String[] { Browser.BookmarkColumns._ID }; 
        final Cursor c = cr.query(Browser.BOOKMARKS_URI, projection, where, 
                selArgs, null); 
        boolean succeed = c.moveToFirst(); 
        ContentValues values = null; 
        while (succeed) { 
            if (values == null) { 
                final ByteArrayOutputStream os = new ByteArrayOutputStream(); 
                favicon.compress(Bitmap.CompressFormat.PNG, 100, os); 
                values = new ContentValues(); 
                values.put(Browser.BookmarkColumns.FAVICON, os.toByteArray()); 
            } 
            cr.update( 
                    ContentUris.withAppendedId(Browser.BOOKMARKS_URI, 
                            c.getInt(0)), values, null, null); 
            succeed = c.moveToNext(); 
        } 
        c.close(); 
    } 
 
    /**
     * Internal function used in search, sort, and refreshList.
     */ 
    private int createdColumnIndex = -1; 
 
    private void searchInternal() { 
        if (mCursor != null) { 
            mCursor.unregisterContentObserver(mChangeObserver); 
            mCursor.unregisterDataSetObserver(mDataSetObserver); 
            mCursor.deactivate(); 
        } 
 
        // need to add the created date column to the query 
        String[] columns = new String[Browser.HISTORY_PROJECTION.length + 1]; 
        System.arraycopy(Browser.HISTORY_PROJECTION, 0, columns, 0, 
                Browser.HISTORY_PROJECTION.length); 
        createdColumnIndex = columns.length – 1; 
        columns[createdColumnIndex] = Browser.BookmarkColumns.CREATED; 
 
        String whereClause = Browser.BookmarkColumns.BOOKMARK + " == 1"; 
        String orderBy = Browser.BookmarkColumns.CREATED + " DESC"; 
        String[] selectionArgs = null; 
        mCursor = mContentResolver.query(Browser.BOOKMARKS_URI, columns, 
                whereClause, selectionArgs, orderBy); 
        mCursor.registerContentObserver(mChangeObserver); 
        mCursor.registerDataSetObserver(mDataSetObserver); 
 
        mDataValid = true; 
        notifyDataSetChanged(); 
 
        mCount = mCursor.getCount(); 
    } 
 
    /**
     * How many items should be displayed in the list.
     * 
     * @return Count of items.
     */ 
    public int getCount() { 
        if (mDataValid) { 
            return mCount; 
        } else { 
            return 0; 
        } 
    } 
 
    public boolean areAllItemsEnabled() { 
        return true; 
    } 
 
    public boolean isEnabled(int position) { 
        return true; 
    } 
 
    /**
     * Get the data associated with the specified position in the list.
     * 
     * @param position
     *            Index of the item whose data we want.
     * @return The data at the specified position.
     */ 
    public Object getItem(int position) { 
        return null; 
    } 
 
    /**
     * Get the row id associated with the specified position in the list.
     * 
     * @param position
     *            Index of the item whose row id we want.
     * @return The id of the item at the specified position.
     */ 
    public long getItemId(int position) { 
        return position; 
    } 
 
    int mCurrentSelection = -1; 
 
    public void setSelected(int position) { 
        mCurrentSelection = position; 
        notifyDataSetInvalidated(); 
    } 
 
    /**
     * Get a View that displays the data at the specified position in the list.
     * 
     * @param position
     *            Index of the item whose view we want.
     * @return A View corresponding to the data at the specified position.
     */ 
    public View getView(int position, View convertView, ViewGroup parent) { 
        if (!mDataValid) { 
            throw new IllegalStateException( 
                    "this should only be called when the cursor is valid"); 
        } 
        if (position < 0 || position > mCount) { 
            throw new AssertionError( 
                    "BrowserBookmarksAdapter tried to get a view out of range"); 
        } 
 
        if (convertView == null) { 
            convertView = new BookmarkItem(mBookmarker); 
        } 
        bind((BookmarkItem) convertView, position); 
        if (position == mCurrentSelection) { 
            ((BookmarkItem) convertView).setSelected(); 
        } else { 
            ((BookmarkItem) convertView).setUnselected(); 
        } 
 
        return convertView; 
    } 
 
    /**
     * Return the title for this item in the list.
     */ 
    public String getTitle(int position) { 
        return getString(Browser.HISTORY_PROJECTION_TITLE_INDEX, position); 
    } 
 
    /**
     * Return the Url for this item in the list.
     */ 
    public String getUrl(int position) { 
        return getString(Browser.HISTORY_PROJECTION_URL_INDEX, position); 
    } 
 
    /**
     * Private helper function to return the title or url.
     */ 
    private String getString(int cursorIndex, int position) { 
        if (position < 0 || position > mCount) { 
            return ""; 
        } 
        mCursor.moveToPosition(position); 
        return mCursor.getString(cursorIndex); 
    } 
 
    private void bind(BookmarkItem b, int position) { 
        mCursor.moveToPosition(position); 
 
        String title = mCursor 
                .getString(Browser.HISTORY_PROJECTION_TITLE_INDEX); 
        b.setName(title); 
        String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX); 
        b.setUrl(url); 
        byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX); 
        if (data != null) { 
            b.setFavicon(BitmapFactory.decodeByteArray(data, 0, data.length)); 
        } else { 
            b.setFavicon(null); 
        } 
    } 
 
    private class ChangeObserver extends ContentObserver { 
        public ChangeObserver() { 
            super(new Handler()); 
        } 
 
        @Override 
        public boolean deliverSelfNotifications() { 
            return true; 
        } 
 
        @Override 
        public void onChange(boolean selfChange) { 
            refreshList(); 
        } 
    } 
 
    private class MyDataSetObserver extends DataSetObserver { 
        @Override 
        public void onChanged() { 
            mDataValid = true; 
            notifyDataSetChanged(); 
        } 
 
        @Override 
        public void onInvalidated() { 
            mDataValid = false; 
            notifyDataSetInvalidated(); 
        } 
    } 
 
    // returns new position 
    public int moveItemUp(int position) { 
        if (position > 0) { 
            Bundle rowOnTop = getRow(position – 1, false); 
            Bundle rowUnder = getRow(position, false); 
 
            int upId = rowOnTop.getInt("id"); 
            rowOnTop.putInt("id", rowUnder.getInt("id")); 
            rowUnder.putInt("id", upId); 
 
            mCurrentSelection–; 
 
            updateRow(rowOnTop, false); 
            updateRow(rowUnder, false); 
 
            return mCurrentSelection; 
        } else 
            return position; 
    } 
 
    // returns new position 
    public int moveItemDown(int position) { 
        if (position < mCount – 1) { 
            Bundle rowOnTop = getRow(position, false); 
            Bundle rowUnder = getRow(position + 1, false); 
 
            int upId = rowOnTop.getInt("id"); 
            rowOnTop.putInt("id", rowUnder.getInt("id")); 
            rowUnder.putInt("id", upId); 
 
            mCurrentSelection++; 
            updateRow(rowOnTop, false); 
            updateRow(rowUnder, false); 
 
            return mCurrentSelection; 
        } else 
            return position; 
    } 
 
    // returns new position 
    public int moveToTop(int position) { 
        if (position > 0) { 
            // get the row 
            Bundle rowToMove = getRow(position, false); 
            // set its created time to now 
            rowToMove.putLong(Browser.BookmarkColumns.CREATED, 
                    new Date().getTime()); 
            // update the row 
            updateRow(rowToMove, true); 
 
            mCurrentSelection = 0; 
            return mCurrentSelection; 
        } else 
            return position; 
    } 
 
    // returns new post 
    public int moveToBottom(int position) { 
        if (position < mCount – 1) { 
            // get the time the last row in the list was created 
            Bundle lastRow = getRow(mCount – 1, true); 
            Long createTime = lastRow.getLong(Browser.BookmarkColumns.CREATED); 
 
            long newCreateTime = (createTime == null || createTime == 0) ? 0 
                    : createTime – 1; 
            // set the create time of our row to older than the last on the list 
            Bundle rowToMove = getRow(position, false); 
            rowToMove.putLong(Browser.BookmarkColumns.CREATED, newCreateTime); 
            updateRow(rowToMove, true); 
 
            mCurrentSelection = mCount – 1; 
            return mCurrentSelection; 
        } else 
            return position; 
    } 
 
    public String launchUrlOfItem(int position) { 
        try { 
            return getRow(position, false).getString( 
                    Browser.BookmarkColumns.URL); 
        } catch (Exception e) { 
            return null; 
        } 
    } 


bookmark_item.xml:
Java代碼 
<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" android:layout_height="wrap_content" 
    android:paddingLeft="10dip" android:paddingTop="5dip" 
    android:paddingBottom="5dip" android:id="@+id/bookmarkitem"> 
    <ImageView android:id="@+id/favicon" android:layout_width="20dip" 
        android:layout_height="20dip" android:focusable="false" 
        android:padding="2dip" android:layout_marginTop="4dip" 
        android:layout_marginRight="6dip" android:layout_alignParentTop="true" 
        android:background="@drawable/fav_icn_background" android:src="@drawable/app_web_browser_sm" 
        android:layout_alignParentLeft="true" /> 
    <TextView android:id="@+id/title" android:textAppearance="?android:attr/textAppearanceMedium" 
        android:maxLines="1" android:layout_width="wrap_content" 
        android:layout_height="wrap_content" android:layout_toRightOf="@+id/favicon" 
        android:ellipsize="end" /> 
    <TextView android:id="@+id/url" android:textAppearance="?android:attr/textAppearanceSmall" 
        android:maxLines="1" android:layout_width="wrap_content" 
        android:layout_height="wrap_content" android:layout_below="@+id/title" 
        android:layout_toRightOf="@+id/favicon" android:ellipsize="end" /> 
</RelativeLayout> 


main.xml:
Java代碼 
<?xml version="1.0" encoding="utf-8"?> 
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <ListView android:id="@+id/mylistview" android:layout_width="fill_parent" 
        android:layout_height="wrap_content" /> 
    <ImageView android:id="@+id/imageview" android:layout_width="70px" 
        android:layout_height="427px" android:layout_x="250px" 
        android:layout_y="0px" android:background="#66FFFFFF"> 
    </ImageView> 
    <ImageButton android:id="@+id/topbutton" 
        android:layout_width="64px" android:layout_height="60px" android:src="@drawable/top" 
        android:layout_x="252px" android:layout_y="5px" android:scaleType="fitCenter"></ImageButton> 
    <ImageButton android:id="@+id/upbutton" 
        android:layout_width="64px" android:layout_height="60px" android:src="@drawable/up" 
        android:layout_x="252px" android:layout_y="70px" android:scaleType="fitCenter"></ImageButton> 
    <ImageButton android:id="@+id/downbutton" android:src="@drawable/down" 
        android:layout_width="64px" android:layout_height="60px" 
        android:layout_x="252px" android:layout_y="135px" android:scaleType="fitCenter"></ImageButton> 
    <ImageButton android:id="@+id/bottombutton" android:src="@drawable/bottom" 
        android:layout_width="64px" android:layout_height="60px" 
        android:layout_x="252px" android:layout_y="200px" android:scaleType="fitCenter"></ImageButton> 
    <ImageButton android:id="@+id/launchbutton" android:src="@drawable/launch" 
        android:layout_width="64px" android:layout_height="60px" 
        android:layout_x="252px" android:layout_y="305px" android:scaleType="fitCenter"></ImageButton> 
    <ImageButton android:id="@+id/deletebutton" 
        android:layout_width="64px" android:layout_height="60px" android:src="@drawable/trash" 
        android:textSize="12sp" android:layout_x="252px" android:layout_y="370px"> 
    </ImageButton> 
</AbsoluteLayout> 


strings.xml:
Java代碼 
<?xml version="1.0" encoding="utf-8"?> 
<resources> 
<string name="app_name">丸子</string> 
<string name="welcome">Welcome to Bookmarker.\n\nBookmarker is a very simple app which allows you to reorder and delete the bookmarks used in the G1\'s web browser.\nSimple.</string> 
<string name="nomarks">\n\nYou don\'t have any bookmarks at the moment, Bookmarker will now close.</string> 
<string name="menu_about">About</string> 
</resources> 


下面是用到的一些圖片:

 

發佈留言