Android 3.0のフラグメントAPI

Android 3.0では、フラグメントの新しい概念が導入されています。これにより、さまざまな画面サイズのインターフェイスの操作が簡単になります。 このトピックは、android-developers.blogspot.comの記事の翻訳です。 フラグメントの利点について説明し、この原則に基づいて動作するアプリケーションのシンプルだが完全な例を提供します。



Android 3.0の重要な目標は、画面のサイズに応じてスケーリングする必要があるプログラムの作成を簡素化することです。 このため、次のツールがAndroidプラットフォームですでに利用可能です。





レイアウトマネージャーとさまざまなリソースの選択の組み合わせは、スケーラブルなインターフェイスを作成する長い道のりを表しています。 その結果、多くのハンドセットアプリケーションは、ハニカムで動作するタブレット用の特別なインターフェイスを使用しません。



フラグメントの概要





Android 3.0では、アプリケーションがフラグメントと呼ばれるインターフェースのスケーリングを支援する新しいクラスのサポートを導入しています。 フラグメントは、独自のインターフェースとライフサイクルを持つ独立したコンポーネントです。 特定のデバイスまたは画面に必要なUIストリームに応じて、ユーザーインターフェイスのさまざまな部分で繰り返し使用できます。



ある意味では、フラグメントをミニアクティビティと見なすことができますが、個別に起動することはできず、アクティビティ内に配置する必要があります。 実際、フラグメントAPIの導入により、アクティビティの操作時に開発者が直面した多くの問題を解決する機会が与えられました。フラグメントの有用性は、さまざまな画面解像度の通常の設定をはるかに超えているためです。





はじめに





これは、フラグメントを使用して複数のUIスレッドを実装する単純ですが完全な例です。 左側の要素のリストと右側の要素のデータを含むランドスケープレイアウトの設計から始めましょう。 必要なレイアウトは次のとおりです。



画像



Activityのコードは特に興味深いものではなく、次のレイアウトでsetContentView()を呼び出すだけです。



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment class="com.example.android.apis.app.TitlesFragment" android:id="@+id/titles" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent" /> <FrameLayout android:id="@+id/details" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent" /> </LinearLayout>
      
      





最初の機能に気付くかもしれません:タグ
 <fragment>
      
      



インターフェイス階層にフラグメントを設定できます。 上記のフラグメントはListFragmentプロパティを継承します。このプロパティは、レイアウトに応じて、現在の場所または別のアクティビティにある要素のデータを表示します。 フラグメント状態の変更がどのように保存されるかに注意してください。



 public static class TitlesFragment extends ListFragment { boolean mDualPane; int mCurCheckPosition = 0; @Override public void onActivityCreated(Bundle savedState) { super.onActivityCreated(savedState); // Populate list with our static array of titles. setListAdapter(new ArrayAdapter<String>(getActivity(), R.layout.simple_list_item_checkable_1, Shakespeare.TITLES)); // Check to see if we have a frame in which to embed the details // fragment directly in the containing UI. View detailsFrame = getActivity().findViewById(R.id.details); mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE; if (savedState != null) { // Restore last state for checked position. mCurCheckPosition = savedState.getInt("curChoice", 0); } if (mDualPane) { // In dual-pane mode, list view highlights selected item. getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); // Make sure our UI is in the correct state. showDetails(mCurCheckPosition); } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("curChoice", mCurCheckPosition); } @Override public void onListItemClick(ListView l, View v, int pos, long id) { showDetails(pos); } /** * Helper function to show the details of a selected item, either by * displaying a fragment in-place in the current UI, or starting a * whole new activity in which it is displayed. */ void showDetails(int index) { mCurCheckPosition = index; if (mDualPane) { // We can display everything in-place with fragments. // Have the list highlight this item and show the data. getListView().setItemChecked(index, true); // Check what fragment is shown, replace if needed. DetailsFragment details = (DetailsFragment) getFragmentManager().findFragmentById(R.id.details); if (details == null || details.getShownIndex() != index) { // Make new fragment to show this selection. details = DetailsFragment.newInstance(index); // Execute a transaction, replacing any existing // fragment with this one inside the frame. FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.details, details); ft.setTransition( FragmentTransaction.TRANSIT_FRAGMENT_FADE); ft.commit(); } } else { // Otherwise we need to launch a new activity to display // the dialog fragment with selected text. Intent intent = new Intent(); intent.setClass(getActivity(), DetailsActivity.class); intent.putExtra("index", index); startActivity(intent); } } }
      
      





また、通常のTextViewの要素にデータを表示するDetailsFragmentを実装する必要があります。



 public static class DetailsFragment extends Fragment { /** * Create a new instance of DetailsFragment, initialized to * show the text at 'index'. */ public static DetailsFragment newInstance(int index) { DetailsFragment f = new DetailsFragment(); // Supply index input as an argument. Bundle args = new Bundle(); args.putInt("index", index); f.setArguments(args); return f; } public int getShownIndex() { return getArguments().getInt("index", 0); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (container == null) { // Currently in a layout without a container, so no // reason to create our view. return null; } ScrollView scroller = new ScrollView(getActivity()); TextView text = new TextView(getActivity()); int padding = (int)TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 4, getActivity().getResources().getDisplayMetrics()); text.setPadding(padding, padding, padding, padding); scroller.addView(text); text.setText(Shakespeare.DIALOGUE[getShownIndex()]); return scroller; } }
      
      





もう1つのUIスレッドをアプリケーションに追加します。 画面がポートレートモードの場合、2つのフラグメントを並べて表示するのに十分なスペースがありません。 つまり、リストのみを表示する必要があります。



画像



縦向きの新しいレイアウトを書きましょう:



 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment class="com.example.android.apis.app.TitlesFragment" android:id="@+id/titles" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
      
      





これで、TitlesFragmentのデータを表示するコンテナがなくなり、リストのみが表示されます。 リスト項目をクリックすると、データが表示される別のアクティビティを呼び出す必要があります。



画像



今、私たちに必要なのは、すでに準備されたDetailsFragmentを使用することです:

 public static class DetailsActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { // If the screen is now in landscape mode, we can show the // dialog in-line so we don't need this activity. finish(); return; } if (savedInstanceState == null) { // During initial setup, plug in the details fragment. DetailsFragment details = new DetailsFragment(); details.setArguments(getIntent().getExtras()); getSupportFragmentManager().beginTransaction().add( android.R.id.content, details).commit(); } } }
      
      





Activityを接続することにより、現在使用されている構成に基づいて、ストリームのUIの根本的な変更を使用するアプリケーションの完全に機能する例を取得します。 また、構成を変更すると、アプリケーションは画面サイズの要件に合わせて自動的に調整されます。



この例は、UIに合わせてフラグメントを使用する1つの方法を示しています。 デザインによっては、他のものを好む場合があります。 たとえば、アプリケーション全体を1つのアクティビティに入れることができます。このアクティビティでは、フラグメントの構造が変更されます。



いつものように、より多くの情報はSDKドキュメントにあります。 ApiDemosでも例を見つけることができます。



皆のための断片化



Fragment APIは、Android 3.0用に設計されたタブレット指向のアプリケーションで作業を開始する開発者に役立ちます。多くの場合、大画面が含まれます。 また、フラグメントを使用すると、TVなどのAndroid上の新しいデバイス用のアプリケーションのUIを簡単に構成できるようになります。



ただし、現在、Fragment APIは、タブレット用の電話用の既存のアプリケーションのインターフェースを改善するために最も需要があります。



また、フラグメントAPI( Hurray !!! )を使用する静的ライブラリを作成して、以前のバージョンのAndroidで上記のメソッドを使用することも計画されています。 実際、この例のすべてのコードは静的クラスライブラリのみを使用し、Android 2.3で実行されます(Android 3.0 SDKの例と比較できますが、ほとんど違いはありません)。 私たちの目標は、これらのAPIを可能な限り類似させて、Android 3.0にアップグレードする時期に関係なく、すぐに作業を開始できるようにすることです。



ライブラリが利用可能になる正確な日付はまだありませんが、間違いなくすぐになります。 今のところ、Android 3.0でフラグメントの操作を開始できます。



All Articles