2 - Personalize
這個教學列出使用 Facebook SDK for android 如何個人化你的app 經驗的大綱。個人化則藉由顯示使用者的 profile 裡的照片與名子來達成。
- 使用 Request, 來建構一個使用Facebook API calls 的單一要求 。 需要被授權的使用者的一個request, 它必須在一個 open Session 被傳遞。Request 也可以是匿名的, 這是說它們並不一定需要一個使用者來授權。 在這個例子裡, 沒有 Session 需要被定義出來。當一個Request 被完成時, 假如有需要的話 , Facebook SDK 將在background 裡延展 access token 。
- Response 封裝了來自Facebook API call 的 response
- ProfilePictureView 是一個顯示profile 照片的客製化 view
- GraphUse 是一個 提供一個強烈樣式表現的介面
你將會使用這些class 跟 interface 來獲取使用者的基本資訊以用來個人化你的 app。 你將使用一個 屬於 Request class 叫做 newMeRequest() 的靜態的方法呼叫程序。 這個方法會回傳使用者的資料。 當設定好 request , 你將定義一個 callback 來處理回復。這個回復是一個 GraphUser 種類的物件。你也將處理被傳回的使用者物件, 然後使用ProfilePictureView 顯示出使用者 profile 的照片,使用 TextView 顯示使用者的名子。
這個教學帶領你走過
- 步驟 1 : 設定使用者介面
- 步驟 2 : 展示使用者資訊
- 下一步
- 相關範例
步驟 1 : 設定使用者介面
在這個步驟, 你將設定使用者介面來展示使用者 profile 的照片跟名子。
在前面的教學理, 你建立了一個基本授權狀態與使用TextView展示歡迎訊息的UI 。現在你將去除這個TextView 取代而之的是然後使用者 profile 的照片和名子。
打開authenicated view 的layout: res/layout/selection.xml。 去掉 TextView 元件, 然後取而代之的是一個LinearLayout , 它又包含著一個用來展示使用者profile 照片的ProfilePictureView與一個用來展示她們名子 的 Textview。
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:orientation="horizontal" >
<com.facebook.widget.ProfilePictureView
android:id="@+id/selection_profile_pic"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
facebook:preset_size="small" />
<TextView
android:id="@+id/selection_user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_gravity="center"
android:textColor="#333"
android:textSize="18sp" />
</LinearLayout>
你應該會得到一個錯誤訊息關於客製 custom view:
com.facebook.widget.ProfilePictureView
. 加上 facebook namespace 在目前的 package上<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:facebook="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
....
乎視那些關於 一個 LinearLayout 伴隨著另一個LinearLayout 的警示訊息。 稍後你加入更多 components 後, 這個訊息就會消失了。
步驟 2 : 展示使用者資訊
在這個步驟 ,你將加入展是使用者照片與名子資料的邏輯步驟。
開啟 SelectionFragment class 並做一些修改。首先定義用來設定使用者照片與名稱資料的 private variables 。
private ProfilePictureView profilePictureView;
private TextView userNameView;
接下來修改 onCreateView() 方法來只定變數給相關的 layout element :
View view = inflater.inflate(R.layout.selection, container, false);
// Find the user's profile picture custom view
profilePictureView = (ProfilePictureView) view.findViewById(R.id.selection_profile_pic);
profilePictureView.setCropped(true);
// Find the user's name view
userNameView = (TextView) view.findViewById(R.id.selection_user_name);
當 session 打開時, 你將執行一個 API call 來獲取 使用者資料以及完整這個畫面。 之前在authenticate 交學使用過的 UiLifecycleHelper class , 也可以用在 SelectionFragment class 來偵測 session 狀態的改變然後觸發使用者資料的 API call
首先, 建立一個 private 方法用來要求使用者資料:
private void makeMeRequest(final Session session) {
// Make an API call to get user data and define a
// new callback to handle the response.
Request request = Request.newMeRequest(session,
new Request.GraphUserCallback() {
@Override
public void onCompleted(GraphUser user, Response response) {
// If the response is successful
if (session == Session.getActiveSession()) {
if (user != null) {
// Set the id for the ProfilePictureView
// view that in turn displays the profile picture.
profilePictureView.setProfileId(user.getId());
// Set the Textview's text to the user's name.
userNameView.setText(user.getName());
}
}
if (response.getError() != null) {
// Handle errors, will do so later.
}
}
});
request.executeAsync();
}
你也許需要整理一下 import 在你加入這段 code 以後, 因為會有錯誤。 假如你是經由 Eclipse 來 import 的話, 選擇 com.facebook.Session 當你看到這選項時。 同樣的選擇 com.facebook.Request 當你看到這選項。
將下來定義一個private 方法來回應 session 的改變然後呼叫 makeMeRequest() 方法 假如 session 打開了:
private void onSessionStateChange(final Session session, SessionState state, Exception exception) {
if (session != null && session.isOpened()) {
// Get the user's data.
makeMeRequest(session);
}
}
現在你已經設定好對 session state 改變的回應方式, 你可以設定 UiLifecycleHelper instance以及一個關連的 會呼叫 onSessionStateChange() 方法的 listener
定義 private 變數給 UiLifecycleHelper 物件 還有 Session.StatusCallback listener 的 implementation。 這個 listener 覆寫 call() 方法來開啟 之前定義的 onSessionStateChange() 方法
private UiLifecycleHelper uiHelper;
private Session.StatusCallback callback = new Session.StatusCallback() {
@Override
public void call(final Session session, final SessionState state, final Exception exception) {
onSessionStateChange(session, state, exception);
}
};
接下來覆寫 onCreate()方法來初始化 UiLifecycleHelper 物件然後呼叫它的 onCreate()方法 :
接下來, 定義一個 private 常數, 稍後你將會在每次要求一個新的 permissions request 食用道。你將用他來決定在 onActivityResult()時要不要更新一個 session 得資訊:
private static final int REAUTH_ACTIVITY_CODE = 100;
現在覆寫 onActivityResult() 方法然後呼叫對應的 UiLifecycleHelper 方法假如 REAUTH_ACTIVITY_CODE request code 被送進去時
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REAUTH_ACTIVITY_CODE) {
uiHelper.onActivityResult(requestCode, resultCode, data);
}
}
接下來確認其他的 fragment 生命週期的方法會呼叫相關 UiLifecycleHelper class方法:
@Override
public void onResume() {
super.onResume();
uiHelper.onResume();
}
@Override
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
uiHelper.onSaveInstanceState(bundle);
}
@Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
最後, 一但 fragment 設定好了然後一個使用者的 session 打開了, 獲取使用者資料。 修改 onCreateView() 方法來做這件事 :
....
// Check for an open session
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
// Get the user's data
makeMeRequest(session);
}
確保沒有任何錯誤訊息下, Build 跟 run project 。 登入。 你應該會看到你的檔案照片和你的名子
十分感謝,真開心有這麼一篇詳細的解說,對於英文十分頭痛的我給了個良藥,謝謝你~非常有幫助^^
回覆刪除而在複寫oncreat()z方法那邊的code:
回覆刪除@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiHelper = new UiLifecycleHelper(getActivity(), callback);
uiHelper.onCreate(savedInstanceState);
}