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
17package com.example.android.apis.app;
18
19import com.example.android.apis.R;
20import com.example.android.apis.Shakespeare;
21
22import android.app.Activity;
23import android.app.Fragment;
24import android.app.FragmentTransaction;
25import android.app.ListFragment;
26import android.content.Intent;
27import android.content.res.Configuration;
28import android.os.Bundle;
29import android.util.TypedValue;
30import android.view.LayoutInflater;
31import android.view.View;
32import android.view.ViewGroup;
33import android.widget.ArrayAdapter;
34import android.widget.ListView;
35import android.widget.ScrollView;
36import 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 */
43public class FragmentLayout extends Activity {
44
45//BEGIN_INCLUDE(main)
46    @Override
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
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
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
120        public void onSaveInstanceState(Bundle outState) {
121            super.onSaveInstanceState(outState);
122            outState.putInt("curChoice", mCurCheckPosition);
123        }
124
125        @Override
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         */
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                    if (index == 0) {
154                        ft.replace(R.id.details, details);
155                    } else {
156                        ft.replace(R.id.a_item, details);
157                    }
158                    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
159                    ft.commit();
160                }
161
162            } else {
163                // Otherwise we need to launch a new activity to display
164                // the dialog fragment with selected text.
165                Intent intent = new Intent();
166                intent.setClass(getActivity(), DetailsActivity.class);
167                intent.putExtra("index", index);
168                startActivity(intent);
169            }
170        }
171    }
172//END_INCLUDE(titles)
173
174    /**
175     * This is the secondary fragment, displaying the details of a particular
176     * item.
177     */
178//BEGIN_INCLUDE(details)
179    public static class DetailsFragment extends Fragment {
180        /**
181         * Create a new instance of DetailsFragment, initialized to
182         * show the text at 'index'.
183         */
184        public static DetailsFragment newInstance(int index) {
185            DetailsFragment f = new DetailsFragment();
186
187            // Supply index input as an argument.
188            Bundle args = new Bundle();
189            args.putInt("index", index);
190            f.setArguments(args);
191
192            return f;
193        }
194
195        public int getShownIndex() {
196            return getArguments().getInt("index", 0);
197        }
198
199        @Override
200        public View onCreateView(LayoutInflater inflater, ViewGroup container,
201                Bundle savedInstanceState) {
202            if (container == null) {
203                // We have different layouts, and in one of them this
204                // fragment's containing frame doesn't exist.  The fragment
205                // may still be created from its saved state, but there is
206                // no reason to try to create its view hierarchy because it
207                // won't be displayed.  Note this is not needed -- we could
208                // just run the code below, where we would create and return
209                // the view hierarchy; it would just never be used.
210                return null;
211            }
212
213            ScrollView scroller = new ScrollView(getActivity());
214            TextView text = new TextView(getActivity());
215            int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
216                    4, getActivity().getResources().getDisplayMetrics());
217            text.setPadding(padding, padding, padding, padding);
218            scroller.addView(text);
219            text.setText(Shakespeare.DIALOGUE[getShownIndex()]);
220            return scroller;
221        }
222    }
223//END_INCLUDE(details)
224}
225