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