• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.apis.app;
18 
19 import com.example.android.apis.R;
20 import com.example.android.apis.Shakespeare;
21 
22 import android.app.Activity;
23 import android.app.Fragment;
24 import android.app.FragmentTransaction;
25 import android.app.ListFragment;
26 import android.content.Intent;
27 import android.content.res.Configuration;
28 import android.os.Bundle;
29 import android.util.TypedValue;
30 import android.view.LayoutInflater;
31 import android.view.View;
32 import android.view.ViewGroup;
33 import android.widget.ArrayAdapter;
34 import android.widget.ListView;
35 import android.widget.ScrollView;
36 import android.widget.TextView;
37 
38 /**
39  * Demonstration of using fragments to implement different activity layouts.
40  * This sample provides a different layout (and activity flow) when run in
41  * landscape.
42  */
43 public class FragmentLayout extends Activity {
44 
45 //BEGIN_INCLUDE(main)
46     @Override
onCreate(Bundle savedInstanceState)47     protected void onCreate(Bundle savedInstanceState) {
48         super.onCreate(savedInstanceState);
49 
50         setContentView(R.layout.fragment_layout);
51     }
52 //END_INCLUDE(main)
53 
54     /**
55      * This is a secondary activity, to show what the user has selected
56      * when the screen is not large enough to show it all in one activity.
57      */
58 //BEGIN_INCLUDE(details_activity)
59     public static class DetailsActivity extends Activity {
60 
61         @Override
onCreate(Bundle savedInstanceState)62         protected void onCreate(Bundle savedInstanceState) {
63             super.onCreate(savedInstanceState);
64 
65             if (getResources().getConfiguration().orientation
66                     == Configuration.ORIENTATION_LANDSCAPE) {
67                 // If the screen is now in landscape mode, we can show the
68                 // dialog in-line with the list so we don't need this activity.
69                 finish();
70                 return;
71             }
72 
73             if (savedInstanceState == null) {
74                 // During initial setup, plug in the details fragment.
75                 DetailsFragment details = new DetailsFragment();
76                 details.setArguments(getIntent().getExtras());
77                 getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
78             }
79         }
80     }
81 //END_INCLUDE(details_activity)
82 
83     /**
84      * This is the "top-level" fragment, showing a list of items that the
85      * user can pick.  Upon picking an item, it takes care of displaying the
86      * data to the user as appropriate based on the currrent UI layout.
87      */
88 //BEGIN_INCLUDE(titles)
89     public static class TitlesFragment extends ListFragment {
90         boolean mDualPane;
91         int mCurCheckPosition = 0;
92 
93         @Override
onActivityCreated(Bundle savedInstanceState)94         public void onActivityCreated(Bundle savedInstanceState) {
95             super.onActivityCreated(savedInstanceState);
96 
97             // Populate list with our static array of titles.
98             setListAdapter(new ArrayAdapter<String>(getActivity(),
99                     android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES));
100 
101             // Check to see if we have a frame in which to embed the details
102             // fragment directly in the containing UI.
103             View detailsFrame = getActivity().findViewById(R.id.details);
104             mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE;
105 
106             if (savedInstanceState != null) {
107                 // Restore last state for checked position.
108                 mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
109             }
110 
111             if (mDualPane) {
112                 // In dual-pane mode, the list view highlights the selected item.
113                 getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
114                 // Make sure our UI is in the correct state.
115                 showDetails(mCurCheckPosition);
116             }
117         }
118 
119         @Override
onSaveInstanceState(Bundle outState)120         public void onSaveInstanceState(Bundle outState) {
121             super.onSaveInstanceState(outState);
122             outState.putInt("curChoice", mCurCheckPosition);
123         }
124 
125         @Override
onListItemClick(ListView l, View v, int position, long id)126         public void onListItemClick(ListView l, View v, int position, long id) {
127             showDetails(position);
128         }
129 
130         /**
131          * Helper function to show the details of a selected item, either by
132          * displaying a fragment in-place in the current UI, or starting a
133          * whole new activity in which it is displayed.
134          */
showDetails(int index)135         void showDetails(int index) {
136             mCurCheckPosition = index;
137 
138             if (mDualPane) {
139                 // We can display everything in-place with fragments, so update
140                 // the list to highlight the selected item and show the data.
141                 getListView().setItemChecked(index, true);
142 
143                 // Check what fragment is currently shown, replace if needed.
144                 DetailsFragment details = (DetailsFragment)
145                         getFragmentManager().findFragmentById(R.id.details);
146                 if (details == null || details.getShownIndex() != index) {
147                     // Make new fragment to show this selection.
148                     details = DetailsFragment.newInstance(index);
149 
150                     // Execute a transaction, replacing any existing fragment
151                     // with this one inside the frame.
152                     FragmentTransaction ft = getFragmentManager().beginTransaction();
153                     ft.replace(R.id.details, details);
154                     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
155                     ft.commit();
156                 }
157 
158             } else {
159                 // Otherwise we need to launch a new activity to display
160                 // the dialog fragment with selected text.
161                 Intent intent = new Intent();
162                 intent.setClass(getActivity(), DetailsActivity.class);
163                 intent.putExtra("index", index);
164                 startActivity(intent);
165             }
166         }
167     }
168 //END_INCLUDE(titles)
169 
170     /**
171      * This is the secondary fragment, displaying the details of a particular
172      * item.
173      */
174 //BEGIN_INCLUDE(details)
175     public static class DetailsFragment extends Fragment {
176         /**
177          * Create a new instance of DetailsFragment, initialized to
178          * show the text at 'index'.
179          */
newInstance(int index)180         public static DetailsFragment newInstance(int index) {
181             DetailsFragment f = new DetailsFragment();
182 
183             // Supply index input as an argument.
184             Bundle args = new Bundle();
185             args.putInt("index", index);
186             f.setArguments(args);
187 
188             return f;
189         }
190 
getShownIndex()191         public int getShownIndex() {
192             return getArguments().getInt("index", 0);
193         }
194 
195         @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)196         public View onCreateView(LayoutInflater inflater, ViewGroup container,
197                 Bundle savedInstanceState) {
198             if (container == null) {
199                 // We have different layouts, and in one of them this
200                 // fragment's containing frame doesn't exist.  The fragment
201                 // may still be created from its saved state, but there is
202                 // no reason to try to create its view hierarchy because it
203                 // won't be displayed.  Note this is not needed -- we could
204                 // just run the code below, where we would create and return
205                 // the view hierarchy; it would just never be used.
206                 return null;
207             }
208 
209             ScrollView scroller = new ScrollView(getActivity());
210             TextView text = new TextView(getActivity());
211             int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
212                     4, getActivity().getResources().getDisplayMetrics());
213             text.setPadding(padding, padding, padding, padding);
214             scroller.addView(text);
215             text.setText(Shakespeare.DIALOGUE[getShownIndex()]);
216             return scroller;
217         }
218     }
219 //END_INCLUDE(details)
220 }
221