安卓第九夜 狂風


作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝!

 

我們經常需要在安卓應用中包含簡易的網頁顯示功能。我將在這一講中實現網頁的顯示。

《狂風》,來自小Willem,荷蘭畫派黃金時代的作品。作為當時海上馬車夫的荷蘭,對航海題材的畫情有獨鍾。 這種傾斜的船身,是當時的畫家常用的手法,用於表現很強的風。

 

描述

上一講實現了一個類別條目頁面。現在,我希望點擊某個類別后,能再次以條目的方式顯示所有的聯系人。在這個新的條目頁面中,點擊某個聯系人后,能顯示該聯系人的URL指向的頁面。相關的安卓知識點為:

  • Intent和Bundle。傳遞數據。
  • WebView。用於顯示一個網頁。

 

新的數據庫查詢方法

我將增加一個條目頁面,用於顯示某個類別下的所有聯系人。在數據層面上,我需要從數據庫中取出某個類別下的所有聯系人。在上一講中,我創建了ContactsManager類,用於和數據庫交互。但之前的CRUD方法無法滿足我的需求。我將為該類增加新的方法,以便從數據庫中取出某個類別下的所有聯系人。這個方法如下:

    // Getting all contacts of a category
    public List<Contact> getContactsByCategoryId(int categoryId) { List<Contact> contacts = new LinkedList<Contact>(); SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID, KEY_NAME, KEY_URL, KEY_CATEGORY_ID }, KEY_CATEGORY_ID + "=?", new String[] { String.valueOf(categoryId) }, null, null, null, null); // iterate over all retrieved rows
        Contact contact = null; if (cursor.moveToFirst()) { do { contact = new Contact(); contact.setId(Integer.parseInt(cursor.getString(0))); contact.setName(cursor.getString(1)); contact.setUrl(cursor.getString(2)); Category category = getCategory(Integer.parseInt(cursor.getString(3))); contact.setCategory(category); // Add contact to contacts
 contacts.add(contact); } while (cursor.moveToNext()); } // return contacts
        return contacts; }

上面方法中查詢了數據庫的TABLE_CONTACTS表格。我在數據庫的query()方法中規定,在數據庫查詢時,將只保留符合KEY_CATEGORY_ID等於categoryId條件的數據記錄。該方法將返回某個categoryId下的所有Contact數據,也就是某個目錄下的所有聯系人信息。

我將在后面使用這一新增方法。

 

在Intent放入附加數據

我希望點擊類別后,能夠進入顯示該類別所有聯系人,即啟動一個新的聯系人條目頁面。由於類別的數目是動態變化的,我不可能為每個類別創建一個下游頁面(而且這樣也太麻煩了)。然而,我可以把類別信息傳遞給同一個下游頁面,讓該下游頁面根據類別,進行不同的處理。這個數據傳遞的任務,將由Intent完成。從概念漫游(上)中,我們已經知道,Intent就像傳令兵。現在,我要讓傳令兵夾帶一點“私貨”了。

package me.vamei.vamei; import java.util.List; import me.vamei.vamei.model.Category; import me.vamei.vamei.model.ContactsManager; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; public class CategoryActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_category); ListView listview = (ListView) findViewById(R.id.categoryList); ContactsManager cm = new ContactsManager(this); final List<Category> categories = cm.getAllCategories(); CategoryAdapter adapter = new CategoryAdapter(this, R.layout.list_category, categories); listview.setAdapter(adapter); listview.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view,int position, long id) { Intent intent = new Intent(CategoryActivity.this, ContactListActivity.class); // put extra data into intent // the data will be passed along with the intent, as a key-value pair
                intent.putExtra("CATEGORY_ID", categories.get(position).getId()); startActivity(intent); } }); } }

putExtra()方法在Intent中放入一個鍵值對。"CATEGORY_ID"是“鍵”,而點擊條目對應Category的ID是“值”。

putExtra()方法會先創建一個Bundle對象,再傳遞這個Bundle對象。在安卓中,一個Bundle對象即一個鍵值對。鍵是一個字符串,值是任意可以打包的對象(parcelable object)。Bundle在安卓中的用途非常廣泛。

 

我可以用下面的語句,等效的代替上面的putExtra():

Bundle extra = new Bundle(); extra.putString("CATEGORY_ID", categories.get(position).getId()); intent.putExtra(extra);

即手動創建Bundle對象,再利用putExtra()將Bundle對象附加在Intent對象上。

 

提取Intent中的附加數據

在下游的Activity中,我可以通過Context的getIntent()方法來獲取Intent對象。下游Activity是新建的ContactListActivity。它將以條目的方式,顯示類別下所有聯系人:

package me.vamei.vamei; import java.util.List; import me.vamei.vamei.model.Contact; import me.vamei.vamei.model.ContactsManager; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; public class ContactListActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contact_list); // Get extra data from the Intent // i.e., category id
         Intent intent = getIntent(); int cat_id    = intent.getIntExtra("CATEGORY_ID", -1); ContactsManager cm = new ContactsManager(this); final List<Contact> contacts = cm.getContactsByCategoryId(cat_id); ListView listview = (ListView) findViewById(R.id.contactList); ContactAdapter adapter = new ContactAdapter(this, R.layout.list_contact, contacts); listview.setAdapter(adapter); listview.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view,int position, long id) { Intent intent = new Intent(ContactListActivity.this, BlogActivity.class); // Put extra data into the Intent, which is a URL
                intent.putExtra("BLOG_URL", contacts.get(position).getUrl()); startActivity(intent); } }); } }

我在第一部分編寫的數據庫交互方法getContactsByCategoryId(),在上面的Activity中登場。提取出的Contact表,通過ListView和ContactAdapter,顯示為聯系人的條目頁面。在點擊條目后,URL信息放入Intent中,並啟動下游的BlogActivity。BlogActivity根據Intent中的URL,來打開聯系人的網頁。

練習 參考安卓第八夜 瑪麗蓮夢露,增加ContactAdapter,activity_category_list.xml和list_contact.xml,以完整的實現聯系人條目頁面。 

練習 根據之前提到的adb shell,為數據庫增加Category和Contact記錄。

 

聯系人條目

 

使用WebView

下面我要添加BlogActivity。它使用了WebView視圖元素來顯示Web頁面。我將增加一個布局文件activity_blog.xml,這個文件包含一個簡單的WebView視圖元素:

<WebView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/web" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" />

通過操縱該視圖元素,我可以把網頁加載入這個視圖元素。 

 

下面,我將創建對應的BlogActivity。它將從Intent中提取URL地址。WebView的loadUrl()方法,用於加載URL所指向的網頁:

package me.vamei.vamei; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.webkit.WebView; @SuppressLint("SetJavaScriptEnabled") public class BlogActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_blog); // Receive the URL from the upstream activity
         Intent intent = getIntent(); String url = intent.getStringExtra("BLOG_URL"); WebView webView = (WebView) findViewById(R.id.web); // Enable JavaScript
        webView.getSettings().setJavaScriptEnabled(true); // Load the web page of the URL
 webView.loadUrl(url); } }

注意上面的getSettings()方法將返回一個WebSettings對象,包含了WebView的設置功能。該對象的setJavaScriptEnabled()方法,將允許WebView運行網頁上的JavaScript腳本。

 

為了WebView正常運行,我需要賦予應用訪問互聯網的權限,在AndroidManifest.xml中增加uses-permission標簽:

 

<manifest ...> ... <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>

 

 

 

 

 

總結

putExtra(), getIntent(), getIntExtra()

WebView, getSettings(), loadUrl()

 

歡迎繼續閱讀“Java快速教程”系列文章  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM