Clean up support library samples.

Move them off into their own directory, so it is less confusing to
find them.

Also put in some additional samples -- throttle and arguments.

And add some docs.

Change-Id: I221e56c7ff203934796979bb5ed7ab8835f84b83
This commit is contained in:
Dianne Hackborn
2011-03-08 18:18:10 -08:00
parent f6ab64affe
commit 6b3f9b3ac9
24 changed files with 876 additions and 42 deletions

View File

@@ -368,7 +368,7 @@
<!-- Fragment Support Samples --> <!-- Fragment Support Samples -->
<activity android:name=".app.FragmentAlertDialogSupport" <activity android:name=".support.app.FragmentAlertDialogSupport"
android:label="@string/fragment_alert_dialog_support"> android:label="@string/fragment_alert_dialog_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -376,7 +376,15 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentHideShowSupport" <activity android:name=".support.app.FragmentArgumentsSupport"
android:label="@string/fragment_arguments_support">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
<activity android:name=".support.app.FragmentHideShowSupport"
android:label="@string/fragment_hide_show_support" android:label="@string/fragment_hide_show_support"
android:windowSoftInputMode="stateUnchanged"> android:windowSoftInputMode="stateUnchanged">
<intent-filter> <intent-filter>
@@ -385,7 +393,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentContextMenuSupport" <activity android:name=".support.app.FragmentContextMenuSupport"
android:label="@string/fragment_context_menu_support"> android:label="@string/fragment_context_menu_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -393,7 +401,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentDialogSupport" <activity android:name=".support.app.FragmentDialogSupport"
android:label="@string/fragment_dialog_support"> android:label="@string/fragment_dialog_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -401,7 +409,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentDialogOrActivitySupport" <activity android:name=".support.app.FragmentDialogOrActivitySupport"
android:label="@string/fragment_dialog_or_activity_support"> android:label="@string/fragment_dialog_or_activity_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -409,7 +417,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentLayoutSupport" <activity android:name=".support.app.FragmentLayoutSupport"
android:label="@string/fragment_layout_support"> android:label="@string/fragment_layout_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -417,7 +425,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentListCursorLoaderSupport" <activity android:name=".support.app.FragmentListCursorLoaderSupport"
android:label="@string/fragment_list_cursor_loader_support"> android:label="@string/fragment_list_cursor_loader_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -425,7 +433,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentListArraySupport" <activity android:name=".support.app.FragmentListArraySupport"
android:label="@string/fragment_list_array_support"> android:label="@string/fragment_list_array_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -433,9 +441,9 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentLayoutSupport$DetailsActivity" /> <activity android:name=".support.app.FragmentLayoutSupport$DetailsActivity" />
<activity android:name=".app.FragmentMenuSupport" <activity android:name=".support.app.FragmentMenuSupport"
android:label="@string/fragment_menu_support"> android:label="@string/fragment_menu_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -443,7 +451,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentRetainInstanceSupport" <activity android:name=".support.app.FragmentRetainInstanceSupport"
android:label="@string/fragment_retain_instance_support"> android:label="@string/fragment_retain_instance_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -451,7 +459,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentReceiveResultSupport" <activity android:name=".support.app.FragmentReceiveResultSupport"
android:label="@string/fragment_receive_result_support"> android:label="@string/fragment_receive_result_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -459,7 +467,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentStackSupport" <activity android:name=".support.app.FragmentStackSupport"
android:label="@string/fragment_stack_support"> android:label="@string/fragment_stack_support">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -483,6 +491,18 @@
android:enabled="@bool/atLeastHoneycomb" /> android:enabled="@bool/atLeastHoneycomb" />
<!-- END_INCLUDE(loader_throttle) --> <!-- END_INCLUDE(loader_throttle) -->
<!-- Fragment Support Samples -->
<activity android:name=".support.app.LoaderThrottleSupport"
android:label="@string/loader_throttle_support">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
<provider android:name=".support.app.LoaderThrottleSupport$SimpleProvider"
android:authorities="com.example.android.apis.support.app.LoaderThrottle" />
<!-- Intent Samples --> <!-- Intent Samples -->
<activity android:name=".app.Intents" android:label="@string/activity_intents"> <activity android:name=".app.Intents" android:label="@string/activity_intents">

View File

@@ -37,7 +37,8 @@ document.write(""+
" <li><a href='src/com/example/android/apis/media/index.html'>Media</a></li>"+ " <li><a href='src/com/example/android/apis/media/index.html'>Media</a></li>"+
" <li><a href='src/com/example/android/apis/os/index.html'>OS</a></li>"+ " <li><a href='src/com/example/android/apis/os/index.html'>OS</a></li>"+
" <li><a href='src/com/example/android/apis/text/index.html'>Text</a></li>"+ " <li><a href='src/com/example/android/apis/text/index.html'>Text</a></li>"+
" <li><a href='src/com/example/android/apis/view/index.html'>Views</a></li></ul>"); " <li><a href='src/com/example/android/apis/view/index.html'>Views</a></li></ul>"+
" <li><a href='src/com/example/android/apis/support/index.html'>Static Support Library</a></li>");
} }

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<!-- Top-level content view for the simple fragment sample. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:padding="4dip"
android:layout_gravity="center_vertical|center_horizontal"
android:gravity="top|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/fragment_arguments_msg" />
<LinearLayout android:orientation="horizontal" android:padding="4dip"
android:layout_width="match_parent" android:layout_height="wrap_content">
<fragment class="com.example.android.apis.support.app.FragmentArgumentsSupport$MyFragment"
android:id="@+id/embedded"
android:layout_width="0px" android:layout_height="wrap_content"
android:layout_weight="1"
android:label="@string/fragment_arguments_embedded" />
<FrameLayout
android:id="@+id/created"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<fragment class="com.example.android.apis.support.app.FragmentArgumentsSupport$MyFragment"
android:id="@+id/embedded_land"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:label="@string/fragment_arguments_embedded_land" />
</LinearLayout>

View File

@@ -22,7 +22,7 @@
android:orientation="horizontal" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_height="match_parent"> android:layout_width="match_parent" android:layout_height="match_parent">
<fragment class="com.example.android.apis.app.FragmentLayoutSupport$TitlesFragment" <fragment class="com.example.android.apis.support.app.FragmentLayoutSupport$TitlesFragment"
android:id="@+id/titles" android:layout_weight="1" android:id="@+id/titles" android:layout_weight="1"
android:layout_width="0px" android:layout_height="match_parent" /> android:layout_width="0px" android:layout_height="match_parent" />

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<!-- Top-level content view for the simple fragment sample. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:padding="4dip"
android:layout_gravity="center_vertical|center_horizontal"
android:gravity="top|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/fragment_arguments_msg" />
<LinearLayout android:orientation="horizontal" android:padding="4dip"
android:layout_width="match_parent" android:layout_height="wrap_content">
<!-- BEGIN_INCLUDE(from_attributes) -->
<fragment class="com.example.android.apis.support.app.FragmentArgumentsSupport$MyFragment"
android:id="@+id/embedded"
android:layout_width="0px" android:layout_height="wrap_content"
android:layout_weight="1"
android:label="@string/fragment_arguments_embedded" />
<!-- END_INCLUDE(from_attributes) -->
<FrameLayout
android:id="@+id/created"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>

View File

@@ -34,7 +34,7 @@
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Hide" /> android:text="Hide" />
<fragment android:name="com.example.android.apis.app.FragmentHideShowSupport$FirstFragment" <fragment android:name="com.example.android.apis.support.app.FragmentHideShowSupport$FirstFragment"
android:id="@+id/fragment1" android:layout_weight="1" android:id="@+id/fragment1" android:layout_weight="1"
android:layout_width="0px" android:layout_height="wrap_content" /> android:layout_width="0px" android:layout_height="wrap_content" />
@@ -48,7 +48,7 @@
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Hide" /> android:text="Hide" />
<fragment android:name="com.example.android.apis.app.FragmentHideShowSupport$SecondFragment" <fragment android:name="com.example.android.apis.support.app.FragmentHideShowSupport$SecondFragment"
android:id="@+id/fragment2" android:layout_weight="1" android:id="@+id/fragment2" android:layout_weight="1"
android:layout_width="0px" android:layout_height="wrap_content" /> android:layout_width="0px" android:layout_height="wrap_content" />

View File

@@ -20,7 +20,7 @@
<!-- BEGIN_INCLUDE(layout) --> <!-- BEGIN_INCLUDE(layout) -->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"> android:layout_width="match_parent" android:layout_height="match_parent">
<fragment class="com.example.android.apis.app.FragmentLayoutSupport$TitlesFragment" <fragment class="com.example.android.apis.support.app.FragmentLayoutSupport$TitlesFragment"
android:id="@+id/titles" android:id="@+id/titles"
android:layout_width="match_parent" android:layout_height="match_parent" /> android:layout_width="match_parent" android:layout_height="match_parent" />
</FrameLayout> </FrameLayout>

View File

@@ -152,32 +152,36 @@
<string name="fragment_stack">App/Fragment/Stack</string> <string name="fragment_stack">App/Fragment/Stack</string>
<string name="new_fragment">New fragment</string> <string name="new_fragment">New fragment</string>
<string name="fragment_alert_dialog_support">App/Fragment Support/Alert Dialog</string> <string name="fragment_alert_dialog_support">Support/App/Fragment/Alert Dialog</string>
<string name="fragment_hide_show_support">App/Fragment Support/Hide and Show</string> <string name="fragment_arguments_support">Support/App/Fragment/Arguments</string>
<string name="fragment_context_menu_support">App/Fragment Support/Context Menu</string> <string name="fragment_hide_show_support">Support/App/Fragment/Hide and Show</string>
<string name="fragment_dialog_support">App/Fragment Support/Dialog</string> <string name="fragment_context_menu_support">Support/App/Fragment/Context Menu</string>
<string name="fragment_dialog_or_activity_support">App/Fragment Support/Dialog or Activity</string> <string name="fragment_dialog_support">Support/App/Fragment/Dialog</string>
<string name="fragment_layout_support">App/Fragment Support/Layout</string> <string name="fragment_dialog_or_activity_support">Support/App/Fragment/Dialog or Activity</string>
<string name="fragment_list_array_support">App/Fragment Support/List Array</string> <string name="fragment_layout_support">Support/App/Fragment/Layout</string>
<string name="fragment_list_cursor_loader_support">App/Fragment Support/List Cursor Loader</string> <string name="fragment_list_array_support">Support/App/Fragment/List Array</string>
<string name="fragment_menu_support">App/Fragment Support/Menu</string> <string name="fragment_list_cursor_loader_support">Support/App/Fragment/List Cursor Loader</string>
<string name="fragment_retain_instance_support">App/Fragment Support/Retain Instance</string> <string name="fragment_menu_support">Support/App/Fragment/Menu</string>
<string name="fragment_receive_result_support">App/Fragment Support/Receive Result</string> <string name="fragment_retain_instance_support">Support/App/Fragment/Retain Instance</string>
<string name="fragment_stack_support">App/Fragment Support/Stack</string> <string name="fragment_receive_result_support">Support/App/Fragment/Receive Result</string>
<string name="fragment_stack_support">Support/App/Fragment/Stack</string>
<string name="loader_throttle">App/Loader/Throttle</string> <string name="loader_throttle">App/Loader/Throttle</string>
<string name="loader_throttle_support">Support/Loader/Throttle</string>
<string name="activity_menu">App/Activity/Menu</string> <string name="activity_menu">App/Activity/Menu</string>
<string name="open_menu">Open menu</string> <string name="open_menu">Open menu</string>
<string name="close_menu">Close menu</string> <string name="close_menu">Close menu</string>

View File

@@ -92,6 +92,11 @@
<dd>Demonstrates how to use a DialogFragment to show and manage an <dd>Demonstrates how to use a DialogFragment to show and manage an
AlertDialog.</dd> AlertDialog.</dd>
<dt><a href="FragmentArguments.html">Fragment Arguments</a></dt>
<dd>Demonstrates how a fragment can be initialized with arguments,
supplying them either as an argument Bundle at runtime or XML attributes
in a &lt;fragment> tag.</dd>
<dt><a href="FragmentContextMenu.html">Fragment Context Menu</a></dt> <dt><a href="FragmentContextMenu.html">Fragment Context Menu</a></dt>
<dd>Demonstrates how to display and respond to a context menu that is <dd>Demonstrates how to display and respond to a context menu that is
display from a fragment's view hierarchy.</dd> display from a fragment's view hierarchy.</dd>

View File

@@ -0,0 +1,76 @@
<p>This section includes samples showing the use of Android's
static support library. This library contains code that you can
build in to your application to access new features and common
utilities while being able to run down to version 1.6 (API 4)
of the platform.</p>
<ul>
<li><a href="#Fragment">Fragment</a></li>
<li><a href="#LoaderManager">LoaderManager</a></li>
</ul>
<h3 id="Fragment">Fragment</h3>
<dl>
<dt><a href="app/FragmentAlertDialogSupport.html">Fragment Alert Dialog</a></dt>
<dd>Demonstrates how to use a DialogFragment to show and manage an
AlertDialog.</dd>
<dt><a href="app/FragmentArgumentsSupport.html">Fragment Arguments</a></dt>
<dd>Demonstrates how a fragment can be initialized with arguments,
supplying them either as an argument Bundle at runtime or XML attributes
in a &lt;fragment> tag.</dd>
<dt><a href="app/FragmentContextMenuSupport.html">Fragment Context Menu</a></dt>
<dd>Demonstrates how to display and respond to a context menu that is
display from a fragment's view hierarchy.</dd>
<dt><a href="app/FragmentDialogSupport.html">Fragment Dialog</a></dt>
<dd>Demonstrates use of DialogFragment to show various types of dialogs.</dd>
<dt><a href="app/FragmentDialogOrActivitySupport.html">Fragment Dialog or Activity</a></dt>
<dd>Demonstrates how the same Fragment implementation can be used to provide the UI
for either an Activity or Dialog.</dd>
<dt><a href="app/FragmentHideShowSupport.html">Fragment Hide Show</a></dt>
<dd>Demonstrates hiding and showing fragments.</dd>
<dt><a href="app/FragmentLayoutSupport.html">Fragment Layout</a></dt>
<dd>Demonstrates use of the &lt;fragment&gt; tag to embed a Fragment in
an Activity's content view layout, and making the layout change based on
configuration to achieve different UI flows.</dd>
<dt><a href="app/FragmentListArraySupport.html">Fragment List Array</a></dt>
<dd>Demonstrates use of ListFragment to show the contents of a simple ArrayAdapter.</dd>
<dt><a href="app/FragmentListCursorLoaderSupport.html">Fragment List Cursor Loader</a></dt>
<dd>Demonstrates use of LoaderManager to perform a query for a Cursor that
populates a ListFragment.</dd>
<dt><a href="app/FragmentMenuSupport.html">Fragment Menu</a></dt>
<dd>Demonstrates populating custom menu items from a Fragment.</dd>
<dt><a href="app/FragmentReceiveResultSupport.html">Fragment Receive Result</a></dt>
<dd>Demonstrates starting a new Activity from a Fragment, and receiving
a result back from it.</dd>
<dt><a href="app/FragmentRetainInstanceSupport.html">Fragment Retain Instance</a></dt>
<dd>Demonstrates a Fragment can be used to easily retain active state across
an Activity's configuration change.</dd>
<dt><a href="app/FragmentStackSupport.html">Fragment Stack</a></dt>
<dd>Demonstrates creating a stack of Fragment instances similar to the
traditional stack of activities.</dd>
</dl>
<h3 id="LoaderManager">LoaderManager</h3>
<dl>
<dt><a href="app/LoaderThrottleSupport.html">Loader Throttle</a></dt>
<dd>Complete end-to-end demonstration of a simple content provider that
populates data in a list through a cursor loader. The UI allows the list
to be populated with a series of items, showing how AsyncTaskLoader's
throttling facility can be used to control how much a Loader is refreshed
in this case.</dd>
</dl>

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;

View File

@@ -0,0 +1,113 @@
/*
* 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.apis.support.app;
import com.example.android.apis.R;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.app.Activity;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Demonstrates a fragment that can be configured through both Bundle arguments
* and layout attributes.
*/
public class FragmentArgumentsSupport extends FragmentActivity {
//BEGIN_INCLUDE(create)
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_arguments_support);
if (savedInstanceState == null) {
// First-time init; create fragment to embed in activity.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment newFragment = MyFragment.newInstance("From Arguments");
ft.add(R.id.created, newFragment);
ft.commit();
}
}
//END_INCLUDE(create)
//BEGIN_INCLUDE(fragment)
public static class MyFragment extends Fragment {
CharSequence mLabel;
/**
* Create a new instance of MyFragment that will be initialized
* with the given arguments.
*/
static MyFragment newInstance(CharSequence label) {
MyFragment f = new MyFragment();
Bundle b = new Bundle();
b.putCharSequence("label", label);
f.setArguments(b);
return f;
}
/**
* Parse attributes during inflation from a view hierarchy into the
* arguments we handle.
*/
@Override public void onInflate(Activity activity, AttributeSet attrs,
Bundle savedInstanceState) {
super.onInflate(activity, attrs, savedInstanceState);
TypedArray a = activity.obtainStyledAttributes(attrs,
R.styleable.FragmentArguments);
mLabel = a.getText(R.styleable.FragmentArguments_android_label);
a.recycle();
}
/**
* During creation, if arguments have been supplied to the fragment
* then parse those out.
*/
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args != null) {
CharSequence label = args.getCharSequence("label");
if (label != null) {
mLabel = label;
}
}
}
/**
* Create the view for this fragment, using the arguments given to it.
*/
@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(mLabel != null ? mLabel : "(no label)");
tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
return v;
}
}
//END_INCLUDE(fragment)
}

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;
import com.example.android.apis.Shakespeare; import com.example.android.apis.Shakespeare;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.Shakespeare; import com.example.android.apis.Shakespeare;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;

View File

@@ -14,9 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;
import com.example.android.apis.app.SendResult;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.example.android.apis.app; package com.example.android.apis.support.app;
import com.example.android.apis.R; import com.example.android.apis.R;

View File

@@ -0,0 +1,503 @@
/*
* 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.apis.support.app;
//BEGIN_INCLUDE(complete)
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.BaseColumns;
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 java.util.HashMap;
/**
* Demonstration of bottom to top implementation of a content provider holding
* structured data through displaying it in the UI, using throttling to reduce
* the number of queries done when its data changes.
*/
public class LoaderThrottleSupport extends FragmentActivity {
// Debugging.
static final String TAG = "LoaderThrottle";
/**
* The authority we use to get to our sample provider.
*/
public static final String AUTHORITY = "com.example.android.apis.support.app.LoaderThrottle";
/**
* Definition of the contract for the main table of our provider.
*/
public static final class MainTable implements BaseColumns {
// This class cannot be instantiated
private MainTable() {}
/**
* The table name offered by this provider
*/
public static final String TABLE_NAME = "main";
/**
* The content:// style URL for this table
*/
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/main");
/**
* The content URI base for a single row of data. Callers must
* append a numeric row id to this Uri to retrieve a row
*/
public static final Uri CONTENT_ID_URI_BASE
= Uri.parse("content://" + AUTHORITY + "/main/");
/**
* The MIME type of {@link #CONTENT_URI}.
*/
public static final String CONTENT_TYPE
= "vnd.android.cursor.dir/vnd.example.api-demos-throttle";
/**
* The MIME type of a {@link #CONTENT_URI} sub-directory of a single row.
*/
public static final String CONTENT_ITEM_TYPE
= "vnd.android.cursor.item/vnd.example.api-demos-throttle";
/**
* The default sort order for this table
*/
public static final String DEFAULT_SORT_ORDER = "data COLLATE LOCALIZED ASC";
/**
* Column name for the single column holding our data.
* <P>Type: TEXT</P>
*/
public static final String COLUMN_NAME_DATA = "data";
}
/**
* This class helps open, create, and upgrade the database file.
*/
static class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "loader_throttle.db";
private static final int DATABASE_VERSION = 2;
DatabaseHelper(Context context) {
// calls the super constructor, requesting the default cursor factory.
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
*
* Creates the underlying database with table name and column names taken from the
* NotePad class.
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + MainTable.TABLE_NAME + " ("
+ MainTable._ID + " INTEGER PRIMARY KEY,"
+ MainTable.COLUMN_NAME_DATA + " TEXT"
+ ");");
}
/**
*
* Demonstrates that the provider must consider what happens when the
* underlying datastore is changed. In this sample, the database is upgraded the database
* by destroying the existing data.
* A real application should upgrade the database in place.
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Logs that the database is being upgraded
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
// Kills the table and existing data
db.execSQL("DROP TABLE IF EXISTS notes");
// Recreates the database with a new version
onCreate(db);
}
}
/**
* A very simple implementation of a content provider.
*/
public static class SimpleProvider extends ContentProvider {
// A projection map used to select columns from the database
private final HashMap<String, String> mNotesProjectionMap;
// Uri matcher to decode incoming URIs.
private final UriMatcher mUriMatcher;
// The incoming URI matches the main table URI pattern
private static final int MAIN = 1;
// The incoming URI matches the main table row ID URI pattern
private static final int MAIN_ID = 2;
// Handle to a new DatabaseHelper.
private DatabaseHelper mOpenHelper;
/**
* Global provider initialization.
*/
public SimpleProvider() {
// Create and initialize URI matcher.
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME, MAIN);
mUriMatcher.addURI(AUTHORITY, MainTable.TABLE_NAME + "/#", MAIN_ID);
// Create and initialize projection map for all columns. This is
// simply an identity mapping.
mNotesProjectionMap = new HashMap<String, String>();
mNotesProjectionMap.put(MainTable._ID, MainTable._ID);
mNotesProjectionMap.put(MainTable.COLUMN_NAME_DATA, MainTable.COLUMN_NAME_DATA);
}
/**
* Perform provider creation.
*/
@Override
public boolean onCreate() {
mOpenHelper = new DatabaseHelper(getContext());
// Assumes that any failures will be reported by a thrown exception.
return true;
}
/**
* Handle incoming queries.
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// Constructs a new query builder and sets its table name
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(MainTable.TABLE_NAME);
switch (mUriMatcher.match(uri)) {
case MAIN:
// If the incoming URI is for main table.
qb.setProjectionMap(mNotesProjectionMap);
break;
case MAIN_ID:
// The incoming URI is for a single row.
qb.setProjectionMap(mNotesProjectionMap);
qb.appendWhere(MainTable._ID + "=?");
selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
new String[] { uri.getLastPathSegment() });
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (TextUtils.isEmpty(sortOrder)) {
sortOrder = MainTable.DEFAULT_SORT_ORDER;
}
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs,
null /* no group */, null /* no filter */, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
/**
* Return the MIME type for an known URI in the provider.
*/
@Override
public String getType(Uri uri) {
switch (mUriMatcher.match(uri)) {
case MAIN:
return MainTable.CONTENT_TYPE;
case MAIN_ID:
return MainTable.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
/**
* Handler inserting new data.
*/
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
if (mUriMatcher.match(uri) != MAIN) {
// Can only insert into to main URI.
throw new IllegalArgumentException("Unknown URI " + uri);
}
ContentValues values;
if (initialValues != null) {
values = new ContentValues(initialValues);
} else {
values = new ContentValues();
}
if (values.containsKey(MainTable.COLUMN_NAME_DATA) == false) {
values.put(MainTable.COLUMN_NAME_DATA, "");
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long rowId = db.insert(MainTable.TABLE_NAME, null, values);
// If the insert succeeded, the row ID exists.
if (rowId > 0) {
Uri noteUri = ContentUris.withAppendedId(MainTable.CONTENT_ID_URI_BASE, rowId);
getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
/**
* Handle deleting data.
*/
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
String finalWhere;
int count;
switch (mUriMatcher.match(uri)) {
case MAIN:
// If URI is main table, delete uses incoming where clause and args.
count = db.delete(MainTable.TABLE_NAME, where, whereArgs);
break;
// If the incoming URI matches a single note ID, does the delete based on the
// incoming data, but modifies the where clause to restrict it to the
// particular note ID.
case MAIN_ID:
// If URI is for a particular row ID, delete is based on incoming
// data but modified to restrict to the given ID.
finalWhere = DatabaseUtils.concatenateWhere(
MainTable._ID + " = " + ContentUris.parseId(uri), where);
count = db.delete(MainTable.TABLE_NAME, finalWhere, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
/**
* Handle updating data.
*/
@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
String finalWhere;
switch (mUriMatcher.match(uri)) {
case MAIN:
// If URI is main table, update uses incoming where clause and args.
count = db.update(MainTable.TABLE_NAME, values, where, whereArgs);
break;
case MAIN_ID:
// If URI is for a particular row ID, update is based on incoming
// data but modified to restrict to the given ID.
finalWhere = DatabaseUtils.concatenateWhere(
MainTable._ID + " = " + ContentUris.parseId(uri), where);
count = db.update(MainTable.TABLE_NAME, values, finalWhere, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = getSupportFragmentManager();
// Create the list fragment and add it as our sole content.
if (fm.findFragmentById(android.R.id.content) == null) {
ThrottledLoaderListFragment list = new ThrottledLoaderListFragment();
fm.beginTransaction().add(android.R.id.content, list).commit();
}
}
public static class ThrottledLoaderListFragment extends ListFragment
implements LoaderManager.LoaderCallbacks<Cursor> {
// Menu identifiers
static final int POPULATE_ID = Menu.FIRST;
static final int CLEAR_ID = Menu.FIRST+1;
// 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;
// Task we have running to populate the database.
AsyncTask<Void, Void, Void> mPopulatingTask;
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setEmptyText("No data. Select 'Populate' to fill with data from Z to A at a rate of 4 per second.");
setHasOptionsMenu(true);
// Create an empty adapter we will use to display the loaded data.
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, null,
new String[] { MainTable.COLUMN_NAME_DATA },
new int[] { android.R.id.text1 }, 0);
setListAdapter(mAdapter);
// 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) {
menu.add(Menu.NONE, POPULATE_ID, 0, "Populate")
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(Menu.NONE, CLEAR_ID, 0, "Clear")
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
@Override public boolean onOptionsItemSelected(MenuItem item) {
final ContentResolver cr = getActivity().getContentResolver();
switch (item.getItemId()) {
case POPULATE_ID:
if (mPopulatingTask != null) {
mPopulatingTask.cancel(false);
}
mPopulatingTask = new AsyncTask<Void, Void, Void>() {
@Override protected Void doInBackground(Void... params) {
for (char c='Z'; c>='A'; c--) {
if (isCancelled()) {
break;
}
StringBuilder builder = new StringBuilder("Data ");
builder.append(c);
ContentValues values = new ContentValues();
values.put(MainTable.COLUMN_NAME_DATA, builder.toString());
cr.insert(MainTable.CONTENT_URI, values);
// Wait a bit between each insert.
try {
Thread.sleep(250);
} catch (InterruptedException e) {
}
}
return null;
}
};
mPopulatingTask.executeOnExecutor(
AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
return true;
case CLEAR_ID:
if (mPopulatingTask != null) {
mPopulatingTask.cancel(false);
mPopulatingTask = null;
}
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
@Override protected Void doInBackground(Void... params) {
cr.delete(MainTable.CONTENT_URI, null, null);
return null;
}
};
task.execute((Void[])null);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i(TAG, "Item clicked: " + id);
}
// These are the rows that we will retrieve.
static final String[] PROJECTION = new String[] {
MainTable._ID,
MainTable.COLUMN_NAME_DATA,
};
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
CursorLoader cl = new CursorLoader(getActivity(), MainTable.CONTENT_URI,
PROJECTION, null, null, null);
cl.setUpdateThrottle(2000); // update at most every 2 seconds.
return cl;
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
}
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
}
//END_INCLUDE(complete)