讀古今文學網 > Android程序設計:第2版 > 從白板開始 >

從白板開始

這裡,我們將自上而下設計用戶界面,從在平板設備上顯示的用戶界面核心組件Activity類,到在Activity類的實例內創建的Fragment對象。

在使用可視化工具編輯佈局文件把線框轉換成指定用戶界面的XML代碼之前,需要先邁出關鍵的一步:因為Fragment類總是包含子類,在通過Fragment佈局之前需要先創建這些類。

對於前文所提到的線框,我們需要創建三個Fragment子類:

·ContentFragment

·DetailFragment

·QueryResultsListFragment

在Fragment子類中的很多生命週期回調是為了便於日誌記錄,提供簡單的Fragment對像生命週期可視化,並且支持使用代碼骨架方法構建基於應用的代碼。以下是QueryResultsListFragment類的源代碼。

在這段代碼中:

2 包含日誌代碼的生命週期方法。

1 onCreateView的實現,它對佈局進行擴展並調用attachAdapter方法。

3 私有方法attachAdapter,支持該片段的列表顯示一些測試數據。

4 OnItemClickListener接口的實現,它響應用戶交互,在這個例子中,即執行一些簡單的代碼,把一些測試數據發送給屏幕右側欄的Fragment對象,或者如果屏幕太小無法顯示兩個片段,就執行後續的活動。注意這裡沒有給出該判斷的代碼。


package com.finchframework.uiframework;
import android.app.Activity;
import android.app.Fragment;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class QueryResultsListFragment extends Fragment implements OnItemClickListener{
    // String for logging the class name
    private final String TAG = getClass.getSimpleName;
    // Turn logging on or off
    private final boolean L = true;
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // Notification that the fragment is associated with an Activity
        if (L)
            Log.i(TAG, \"onAttach \" + activity.getClass.getSimpleName);    
    }
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Tell the system we have an options menu
        this.setHasOptionsMenu(true);
        if (null != savedInstanceState)
            restoreState(savedInstanceState);
        // Notification that
        if (L) Log.i(TAG, \"onCreate\");
    }
    // Factor this out of methods that get saved state
    private void restoreState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
1
        final ListView list = (ListView) inflater.inflate(
                R.layout.list_frag_list, container, false);
        if (L) Log.i(TAG, \"onCreateView\");
        attachAdapter(list);
        list.setOnItemClickListener(this);
        return list;
    }
    public void onStart {
2
        super.onStart;
        if (L) Log.i(TAG, \"onStart\");
    }
    public void onresume {
        super.onResume;
        if (L) Log.i(TAG, \"onResume\");
    }
    public void onPause {
        super.onPause;
        if (L) Log.i(TAG, \"onPause\");
    }
    public void onStop {
        super.onStop;
        if (L) Log.i(TAG, \"onStop\");
    }
    public void onDestroyView {
        super.onDestroyView;
        if (L) Log.i(TAG, \"onDestroyView\");
    }
    public void onDestroy {
        super.onDestroy;
        if (L) Log.i(TAG, \"onDestroy\");
    }
    public void onDetach {
        super.onDetach;
        if (L) Log.i(TAG, \"onDetach\");
    }
    // ////////////////////////////////////////////////////////////////////
    // Minor lifecycle methods
    // ////////////////////////////////////////////////////////////////////
    public void onActivityCreated {
        // Notification that the containing activiy and its View hierarchy exist
        if (L) Log.i(TAG, \"onActivityCreated\");
    }
    // //////////////////////////////////////////////////////////////////////////
    // Overrides of the implementations ComponentCallbacks methods in Fragment
    // //////////////////////////////////////////////////////////////////////////
    @Override
    public void onConfigurationChanged(Configuration newConfiguration) {
        super.onConfigurationChanged(newConfiguration);
        // This won\'t happen unless we declare changes we handle in the manifest
        if (L)
            Log.i(TAG, \"onConfigurationChanged\");
    }
    @Override
    public void onLowMemory {
        // No guarantee this is called before or after other callbacks
        if (L)
            Log.i(TAG, \"onLowMemory\");
    }
    /////////////////////////////////////////////////////////////////////////////
    // Menu handling code
    /////////////////////////////////////////////////////////////////////////////
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.search_menu, menu);
    }
    // //////////////////////////////////////////////////////////////////////////
    // App-specific code
    // //////////////////////////////////////////////////////////////////////////
    /**
     * Attach an adapter that loads the data to the specified list
     * @param list
     */
    private void attachAdapter(final ListView list) {
3
        // Make a trivial adapter that loads an array of strings
        ArrayAdapter<String> numbers = new ArrayAdapter<String>(
                list.getContext.getApplicationContext,
                android.R.layout.simple_list_item_1,
                new String  {
                \"one\", \"two\", \"three\", \"four\", \"five\", \"six\"
            });
        // tell the list to use it
        list.setAdapter(numbers);
        // l.setOnItemClickListener(this);
    }
    // //////////////////////////////////////////////////////////////////////////
    // Implementation of the OnItemClickListener interface
    // //////////////////////////////////////////////////////////////////////////
    @Override
    public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
4
        // As an example of sending data to our fragments, we will create a bundle
        // with an int and a string, based on which view was clicked
        Bundle b = new Bundle;
        int ordinal = position + 1;
        b.putInt(\"place\", ordinal);
        b.putString(\"placeName\", Integer.toString(ordinal));
        TabManager.loadTabFragments(getActivity, b);
    }
}
 

Fragment子類需要做的就是通過onCreateView方法返回一個View對象。因此,我們也會為每個Fragment類定義一個簡單的佈局,可以加載並返回結果View層次。