diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-06-13 13:48:13 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2011-06-13 16:27:17 -0700 |
commit | be6b6b494f094eea0abcd83eb8770bc4b9f7e34e (patch) | |
tree | 2c8c2cf1da4a6fc7b2018f8cd3910b70400957f3 /samples/Support13Demos | |
parent | e4ccbd68ec540739819bea7e109d29d08a54122a (diff) | |
download | android_development-be6b6b494f094eea0abcd83eb8770bc4b9f7e34e.tar.gz android_development-be6b6b494f094eea0abcd83eb8770bc4b9f7e34e.tar.bz2 android_development-be6b6b494f094eea0abcd83eb8770bc4b9f7e34e.zip |
New API demos showing use of tabs with fragments.
Also various cleanup in other demos.
Change-Id: I4f5669117e28312bcd4b28795c5eca5f4ab6dcfb
Diffstat (limited to 'samples/Support13Demos')
6 files changed, 395 insertions, 1 deletions
diff --git a/samples/Support13Demos/AndroidManifest.xml b/samples/Support13Demos/AndroidManifest.xml index e54bf7f23..bc32d099f 100644 --- a/samples/Support13Demos/AndroidManifest.xml +++ b/samples/Support13Demos/AndroidManifest.xml @@ -26,7 +26,10 @@ <uses-sdk android:minSdkVersion="13" /> - <!-- This app has not been optimized for large screens. --> + <!-- The smallest screen this app works on is a phone. The app will + scale its UI to larger screens but doesn't make good use of them + so allow the compatibility mode button to be shown (mostly because + this is just convenient for testing). --> <supports-screens android:requiresSmallestWidthDp="320" android:compatibleWidthLimitDp="480" /> @@ -60,5 +63,13 @@ </intent-filter> </activity> + <activity android:name=".app.ActionBarTabsPager" + android:label="@string/action_bar_tabs_pager"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="com.example.android.supportv13.SUPPORT13_SAMPLE_CODE" /> + </intent-filter> + </activity> + </application> </manifest> diff --git a/samples/Support13Demos/res/values/strings.xml b/samples/Support13Demos/res/values/strings.xml index 818597c58..2fd12d496 100644 --- a/samples/Support13Demos/res/values/strings.xml +++ b/samples/Support13Demos/res/values/strings.xml @@ -29,4 +29,5 @@ <string name="fragment_state_pager_support">Fragment/State Pager</string> + <string name="action_bar_tabs_pager">Fragment/Action Bar Tabs Pager</string> </resources> diff --git a/samples/Support13Demos/src/com/example/android/supportv13/app/ActionBarTabsPager.java b/samples/Support13Demos/src/com/example/android/supportv13/app/ActionBarTabsPager.java new file mode 100644 index 000000000..6c0f803de --- /dev/null +++ b/samples/Support13Demos/src/com/example/android/supportv13/app/ActionBarTabsPager.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.android.supportv13.app; + +import java.util.ArrayList; + +import com.example.android.supportv13.R; + +import android.app.ActionBar; +import android.app.ActionBar.Tab; +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentTransaction; +import android.content.Context; +import android.os.Bundle; +import android.support.v13.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; + +/** + * This demonstrates the use of action bar tabs and how they interact + * with other action bar features. + */ +public class ActionBarTabsPager extends Activity { + ViewPager mViewPager; + TabsAdapter mTabsAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mViewPager = new ViewPager(this); + mViewPager.setId(R.id.pager); + setContentView(mViewPager); + + final ActionBar bar = getActionBar(); + bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); + bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); + + mTabsAdapter = new TabsAdapter(this, mViewPager); + mTabsAdapter.addTab(bar.newTab().setText("Simple"), + CountingFragment.class, null); + mTabsAdapter.addTab(bar.newTab().setText("List"), + FragmentPagerSupport.ArrayListFragment.class, null); + mTabsAdapter.addTab(bar.newTab().setText("Cursor"), + CursorFragment.class, null); + + if (savedInstanceState != null) { + bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0)); + } + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt("tab", getActionBar().getSelectedNavigationIndex()); + } + + /** + * This is a helper class that implements the management of tabs and all + * details of connecting a ViewPager with associated TabHost. It relies on a + * trick. Normally a tab host has a simple API for supplying a View or + * Intent that each tab will show. This is not sufficient for switching + * between pages. So instead we make the content part of the tab host + * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy + * view to show as the tab content. It listens to changes in tabs, and takes + * care of switch to the correct paged in the ViewPager whenever the selected + * tab changes. + */ + public static class TabsAdapter extends FragmentPagerAdapter + implements ActionBar.TabListener, ViewPager.OnPageChangeListener { + private final Context mContext; + private final ActionBar mActionBar; + private final ViewPager mViewPager; + private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); + + static final class TabInfo { + private final Class<?> clss; + private final Bundle args; + + TabInfo(Class<?> _class, Bundle _args) { + clss = _class; + args = _args; + } + } + + public TabsAdapter(Activity activity, ViewPager pager) { + super(activity.getFragmentManager()); + mContext = activity; + mActionBar = activity.getActionBar(); + mViewPager = pager; + mViewPager.setAdapter(this); + mViewPager.setOnPageChangeListener(this); + } + + public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { + TabInfo info = new TabInfo(clss, args); + tab.setTag(info); + tab.setTabListener(this); + mTabs.add(info); + mActionBar.addTab(tab); + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return mTabs.size(); + } + + @Override + public Fragment getItem(int position) { + TabInfo info = mTabs.get(position); + return Fragment.instantiate(mContext, info.clss.getName(), info.args); + } + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + } + + @Override + public void onPageSelected(int position) { + mActionBar.setSelectedNavigationItem(position); + } + + @Override + public void onTabSelected(Tab tab, FragmentTransaction ft) { + Object tag = tab.getTag(); + for (int i=0; i<mTabs.size(); i++) { + if (mTabs.get(i) == tag) { + mViewPager.setCurrentItem(i); + } + } + } + + @Override + public void onTabUnselected(Tab tab, FragmentTransaction ft) { + } + + @Override + public void onTabReselected(Tab tab, FragmentTransaction ft) { + } + } +} diff --git a/samples/Support13Demos/src/com/example/android/supportv13/app/CountingFragment.java b/samples/Support13Demos/src/com/example/android/supportv13/app/CountingFragment.java new file mode 100644 index 000000000..8672ed22a --- /dev/null +++ b/samples/Support13Demos/src/com/example/android/supportv13/app/CountingFragment.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.android.supportv13.app; + +import com.example.android.supportv13.R; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +public class CountingFragment extends Fragment { + int mNum; + + /** + * Create a new instance of CountingFragment, providing "num" + * as an argument. + */ + static CountingFragment newInstance(int num) { + CountingFragment f = new CountingFragment(); + + // Supply num input as an argument. + Bundle args = new Bundle(); + args.putInt("num", num); + f.setArguments(args); + + return f; + } + + /** + * When creating, retrieve this instance's number from its arguments. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mNum = getArguments() != null ? getArguments().getInt("num") : 1; + } + + /** + * The Fragment's UI is just a simple text view showing its + * instance number. + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.hello_world, container, false); + View tv = v.findViewById(R.id.text); + ((TextView)tv).setText("Fragment #" + mNum); + tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb)); + return v; + } +} diff --git a/samples/Support13Demos/src/com/example/android/supportv13/app/CursorFragment.java b/samples/Support13Demos/src/com/example/android/supportv13/app/CursorFragment.java new file mode 100644 index 000000000..38be2479e --- /dev/null +++ b/samples/Support13Demos/src/com/example/android/supportv13/app/CursorFragment.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.android.supportv13.app; + +import android.app.ListFragment; +import android.app.LoaderManager; +import android.content.CursorLoader; +import android.content.Loader; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.provider.ContactsContract.Contacts; +import android.text.TextUtils; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.ListView; +import android.widget.SearchView; +import android.widget.SimpleCursorAdapter; +import android.widget.SearchView.OnQueryTextListener; + + +public class CursorFragment extends ListFragment + implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> { + + // This is the Adapter being used to display the list's data. + SimpleCursorAdapter mAdapter; + + // If non-null, this is the current filter the user has provided. + String mCurFilter; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText("No phone numbers"); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + // Create an empty adapter we will use to display the loaded data. + mAdapter = new SimpleCursorAdapter(getActivity(), + android.R.layout.simple_list_item_2, null, + new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS }, + new int[] { android.R.id.text1, android.R.id.text2 }, 0); + setListAdapter(mAdapter); + + // Start out with a progress indicator. + setListShown(false); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(0, null, this); + } + + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + // Place an action bar item for searching. + MenuItem item = menu.add("Search"); + item.setIcon(android.R.drawable.ic_menu_search); + item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + SearchView sv = new SearchView(getActivity()); + sv.setOnQueryTextListener(this); + item.setActionView(sv); + } + + public boolean onQueryTextChange(String newText) { + // Called when the action bar search text has changed. Update + // the search filter, and restart the loader to do a new query + // with this filter. + mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; + getLoaderManager().restartLoader(0, null, this); + return true; + } + + @Override public boolean onQueryTextSubmit(String query) { + // Don't care about this. + return true; + } + + @Override public void onListItemClick(ListView l, View v, int position, long id) { + // Insert desired behavior here. + Log.i("FragmentComplexList", "Item clicked: " + id); + } + + // These are the Contacts rows that we will retrieve. + static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { + Contacts._ID, + Contacts.DISPLAY_NAME, + Contacts.CONTACT_STATUS, + Contacts.CONTACT_PRESENCE, + Contacts.PHOTO_ID, + Contacts.LOOKUP_KEY, + }; + + public Loader<Cursor> onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + // First, pick the base URI to use depending on whether we are + // currently filtering. + Uri baseUri; + if (mCurFilter != null) { + baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, + Uri.encode(mCurFilter)); + } else { + baseUri = Contacts.CONTENT_URI; + } + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + + Contacts.DISPLAY_NAME + " != '' ))"; + return new CursorLoader(getActivity(), baseUri, + CONTACTS_SUMMARY_PROJECTION, select, null, + Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); + } + + public void onLoadFinished(Loader<Cursor> loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); + + // The list should now be shown. + if (isResumed()) { + setListShown(true); + } else { + setListShownNoAnimation(true); + } + } + + public void onLoaderReset(Loader<Cursor> loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); + } +} diff --git a/samples/Support13Demos/src/com/example/android/supportv13/app/_index.html b/samples/Support13Demos/src/com/example/android/supportv13/app/_index.html index 47673dad9..832d60ebc 100644 --- a/samples/Support13Demos/src/com/example/android/supportv13/app/_index.html +++ b/samples/Support13Demos/src/com/example/android/supportv13/app/_index.html @@ -8,10 +8,16 @@ package features of the static support library fir API 13 or later. <h3 id="Fragment">Fragment</h3> <dl> + <dt><a href="ActionBarTabsPager.html">Action Bar Tabs Pager</a></dt> + <dd>Demonstrates the use of fragments to implement switching between + ActionBar tabs, using a ViewPager to manager the fragments so that + the user can also fling left and right to switch tabs.</dd> + <dt><a href="FragmentPagerSupport.html">Fragment Pager Support</a></dt> <dd>Demonstrates the use of the v4 support class ViewPager with a FragmentPagerAdapter to build a user interface where the user can fling left or right to switch between fragments.</dd> + <dt><a href="FragmentStatePagerSupport.html">Fragment State Pager Support</a></dt> <dd>Demonstrates the use of the v4 support class ViewPager with a FragmentStatePagerAdapter to build a user interface where the user can fling |