作者: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快速教程”系列文章