Some cleanup of fragment API demos:

- Rename FragmentAnim to FragmentHideShow, and tweak it to look
  less stupid.
- Reworking FragmentLayout to better represent a typical way to
  use fragments.
- Tweak various UI elements.

Change-Id: I3f4861c33bafafd27108fe0e4193e0ac7711f69e
This commit is contained in:
Dianne Hackborn
2011-01-04 11:35:55 -08:00
parent d7394da1a0
commit 9d247ad58b
14 changed files with 136 additions and 79 deletions

View File

@@ -174,7 +174,8 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.SendResult"> <activity android:name=".app.SendResult"
android:theme="@android:style/Theme.Holo.DialogWhenLarge">
</activity> </activity>
<activity android:name=".app.Forwarding" android:label="@string/activity_forwarding"> <activity android:name=".app.Forwarding" android:label="@string/activity_forwarding">
@@ -250,8 +251,9 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".app.FragmentAnim" <activity android:name=".app.FragmentHideShow"
android:label="@string/fragment_anim"> android:label="@string/fragment_hide_show"
android:windowSoftInputMode="stateUnchanged">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" /> <category android:name="android.intent.category.SAMPLE_CODE" />

View File

@@ -26,8 +26,7 @@
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" />
<fragment class="com.example.android.apis.app.FragmentLayout$DetailsFragment" <FrameLayout android:id="@+id/details" android:layout_weight="1"
android:id="@+id/details" android:layout_weight="1"
android:layout_width="0px" android:layout_height="match_parent" /> android:layout_width="0px" android:layout_height="match_parent" />
</LinearLayout> </LinearLayout>

View File

@@ -24,6 +24,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/fragment_context_menu_msg" /> android:text="@string/fragment_context_menu_msg" />
<Button android:id="@+id/long_press" <Button android:id="@+id/long_press"

View File

@@ -27,6 +27,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:layout_gravity="center_vertical|center_horizontal" android:layout_gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="top|center_horizontal" /> android:gravity="top|center_horizontal" />
<Button android:id="@+id/show" <Button android:id="@+id/show"

View File

@@ -28,6 +28,7 @@
android:layout_weight="0" android:layout_weight="0"
android:layout_gravity="center_vertical|center_horizontal" android:layout_gravity="center_vertical|center_horizontal"
android:gravity="top|center_horizontal" android:gravity="top|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/fragment_dialog_or_activity_msg" /> android:text="@string/fragment_dialog_or_activity_msg" />
<Button android:id="@+id/show_dialog" <Button android:id="@+id/show_dialog"
@@ -47,6 +48,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:layout_gravity="center_vertical|center_horizontal" android:layout_gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/fragment_dialog_or_activity_inline" /> android:text="@string/fragment_dialog_or_activity_inline" />
<FrameLayout <FrameLayout

View File

@@ -21,33 +21,36 @@
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:layout_width="match_parent" android:layout_height="match_parent"> android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:layout_width="match_parent" android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Demonstration of hiding and showing fragments." />
<LinearLayout android:orientation="horizontal" android:padding="4dip" <LinearLayout android:orientation="horizontal" android:padding="4dip"
android:gravity="center_vertical" android:layout_weight="1" android:gravity="center_vertical" android:layout_weight="1"
android:layout_width="wrap_content" android:layout_height="wrap_content"> android:layout_width="match_parent" android:layout_height="wrap_content">
<fragment android:name="com.example.android.apis.app.FragmentAnim$FirstFragment"
android:id="@+id/fragment1" android:layout_weight="1"
android:layout_width="0px" android:layout_height="wrap_content" />
<Button android:id="@+id/frag1hide" <Button android:id="@+id/frag1hide"
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" />
</Button>
<fragment android:name="com.example.android.apis.app.FragmentHideShow$FirstFragment"
android:id="@+id/fragment1" android:layout_weight="1"
android:layout_width="0px" android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>
<LinearLayout android:orientation="horizontal" android:padding="4dip" <LinearLayout android:orientation="horizontal" android:padding="4dip"
android:gravity="center_vertical" android:layout_weight="1" android:gravity="center_vertical" android:layout_weight="1"
android:layout_width="wrap_content" android:layout_height="wrap_content"> android:layout_width="match_parent" android:layout_height="wrap_content">
<fragment android:name="com.example.android.apis.app.FragmentAnim$SecondFragment"
android:id="@+id/fragment2" android:layout_weight="1"
android:layout_width="0px" android:layout_height="wrap_content" />
<Button android:id="@+id/frag2hide" <Button android:id="@+id/frag2hide"
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" />
</Button>
<fragment android:name="com.example.android.apis.app.FragmentHideShow$SecondFragment"
android:id="@+id/fragment2" android:layout_weight="1"
android:layout_width="0px" android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>

View File

@@ -24,6 +24,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/fragment_menu_msg" /> android:text="@string/fragment_menu_msg" />
<CheckBox android:id="@+id/menu1" <CheckBox android:id="@+id/menu1"

View File

@@ -24,6 +24,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/fragment_retain_instance_msg" /> android:text="@string/fragment_retain_instance_msg" />
<ProgressBar android:id="@+id/progress_horizontal" <ProgressBar android:id="@+id/progress_horizontal"

View File

@@ -22,4 +22,5 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text" <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
android:layout_width="match_parent" android:layout_height="match_parent" android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal" android:gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/hello_world"/> android:text="@string/hello_world"/>

View File

@@ -27,12 +27,15 @@
android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0"
android:paddingBottom="4dip" android:paddingBottom="4dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/receive_result_instructions"/> android:text="@string/receive_result_instructions"/>
<TextView android:id="@+id/results" <TextView android:id="@+id/results"
android:layout_width="match_parent" android:layout_height="10dip" android:layout_width="match_parent" android:layout_height="10dip"
android:layout_weight="1" android:layout_weight="1"
android:paddingBottom="4dip" android:paddingBottom="4dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#000"
android:background="@drawable/green"> android:background="@drawable/green">
</TextView> </TextView>

View File

@@ -108,7 +108,7 @@
<string name="fragment_alert_dialog">App/Fragment/Alert Dialog</string> <string name="fragment_alert_dialog">App/Fragment/Alert Dialog</string>
<string name="fragment_anim">App/Fragment/Anim</string> <string name="fragment_hide_show">App/Fragment/Hide and Show</string>
<string name="fragment_context_menu">App/Fragment/Context Menu</string> <string name="fragment_context_menu">App/Fragment/Context Menu</string>
<string name="fragment_context_menu_msg">Fragment populating a context <string name="fragment_context_menu_msg">Fragment populating a context

View File

@@ -20,45 +20,46 @@ import com.example.android.apis.R;
import android.app.Activity; import android.app.Activity;
import android.app.Fragment; import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction; import android.app.FragmentTransaction;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.view.animation.AnimationUtils;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
/** /**
* Demonstration of animations when changing fragment states. * Demonstration of hiding and showing fragments.
*/ */
public class FragmentAnim extends Activity { public class FragmentHideShow extends Activity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_anim); setContentView(R.layout.fragment_hide_show);
addShowHideListener(R.id.frag1hide, findFragmentById(R.id.fragment1)); // The content view embeds two fragments; now retrieve them and attach
addShowHideListener(R.id.frag2hide, findFragmentById(R.id.fragment2)); // their "hide" button.
FragmentManager fm = getFragmentManager();
addShowHideListener(R.id.frag1hide, fm.findFragmentById(R.id.fragment1));
addShowHideListener(R.id.frag2hide, fm.findFragmentById(R.id.fragment2));
} }
void addShowHideListener(int buttonId, final Fragment fragment) { void addShowHideListener(int buttonId, final Fragment fragment) {
final Button button = (Button)findViewById(buttonId); final Button button = (Button)findViewById(buttonId);
button.setOnClickListener(new OnClickListener() { button.setOnClickListener(new OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
FragmentTransaction ft = openFragmentTransaction(); FragmentTransaction ft = getFragmentManager().openTransaction();
ft.setCustomAnimations(android.R.anim.animator_fade_in, ft.setCustomAnimations(android.R.anim.animator_fade_in,
android.R.anim.animator_fade_out); android.R.anim.animator_fade_out);
if (fragment.isHidden()) { if (fragment.isHidden()) {
button.setAnimation(AnimationUtils.loadAnimation(
FragmentAnim.this, android.R.anim.slide_in_left));
ft.show(fragment); ft.show(fragment);
button.setText("Hide");
} else { } else {
button.setAnimation(AnimationUtils.loadAnimation(
FragmentAnim.this, android.R.anim.slide_out_right));
ft.hide(fragment); ft.hide(fragment);
button.setText("Show");
} }
ft.commit(); ft.commit();
} }

View File

@@ -21,11 +21,11 @@ import com.example.android.apis.Shakespeare;
import android.app.Activity; import android.app.Activity;
import android.app.Fragment; import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.ListFragment; import android.app.ListFragment;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -73,17 +73,23 @@ public class FragmentLayout extends Activity {
if (savedInstanceState == null) { if (savedInstanceState == null) {
// During initial setup, plug in the details fragment. // During initial setup, plug in the details fragment.
DetailsFragment details = new DetailsFragment(); DetailsFragment details = new DetailsFragment();
details.setArguments(getIntent().getExtras());
getFragmentManager().openTransaction().add(android.R.id.content, details).commit(); getFragmentManager().openTransaction().add(android.R.id.content, details).commit();
details.setText(getIntent().getIntExtra("text", -1));
} }
} }
} }
//END_INCLUDE(details_activity) //END_INCLUDE(details_activity)
/**
* This is the "top-level" fragment, showing a list of items that the
* user can pick. Upon picking an item, it takes care of displaying the
* data to the user as appropriate based on the currrent UI layout.
*/
//BEGIN_INCLUDE(titles) //BEGIN_INCLUDE(titles)
public static class TitlesFragment extends ListFragment { public static class TitlesFragment extends ListFragment {
DetailsFragment mDetails; boolean mDualPane;
int mCurCheckPosition = 0; int mCurCheckPosition = 0;
int mShownCheckPosition = -1;
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
@@ -93,17 +99,22 @@ public class FragmentLayout extends Activity {
setListAdapter(new ArrayAdapter<String>(getActivity(), setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES)); android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES));
// Restore last state for checked position. // Check to see if we have a frame in which to embed the details
// fragment directly in the containing UI.
View detailsFrame = getActivity().findViewById(R.id.details);
mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE;
if (savedInstanceState != null) { if (savedInstanceState != null) {
// Restore last state for checked position.
mCurCheckPosition = savedInstanceState.getInt("curChoice", 0); mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
mShownCheckPosition = savedInstanceState.getInt("shownChoice", -1);
} }
// If we are showing details in the screen, set up the list to highlight. if (mDualPane) {
mDetails = (DetailsFragment)getFragmentManager().findFragmentById(R.id.details); // In dual-pane mode, the list view highlights the selected item.
if (mDetails != null && mDetails.isInLayout()) {
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
getListView().setItemChecked(mCurCheckPosition, true); // Make sure our UI is in the correct state.
mDetails.setText(mCurCheckPosition); showDetails(mCurCheckPosition);
} }
} }
@@ -111,67 +122,97 @@ public class FragmentLayout extends Activity {
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putInt("curChoice", mCurCheckPosition); outState.putInt("curChoice", mCurCheckPosition);
outState.putInt("shownChoice", mShownCheckPosition);
} }
@Override @Override
public void onListItemClick(ListView l, View v, int position, long id) { public void onListItemClick(ListView l, View v, int position, long id) {
mCurCheckPosition = position; showDetails(position);
}
/**
* Helper function to show the details of a selected item, either by
* displaying a fragment in-place in the current UI, or starting a
* whole new activity in which it is displayed.
*/
void showDetails(int index) {
mCurCheckPosition = index;
if (mDualPane) {
// We can display everything in-place with fragments, so update
// the list to highlight the selected item and show the data.
getListView().setItemChecked(index, true);
if (mShownCheckPosition != mCurCheckPosition) {
// If we are not currently showing a fragment for the new
// position, we need to create and install a new one.
DetailsFragment df = DetailsFragment.newInstance(index);
// Execute a transaction, replacing any existing fragment
// with this one inside the frame.
FragmentTransaction ft = getFragmentManager().openTransaction();
ft.replace(R.id.details, df);
ft.setTransition(index > mCurCheckPosition
? FragmentTransaction.TRANSIT_FRAGMENT_NEXT
: FragmentTransaction.TRANSIT_FRAGMENT_PREV);
ft.commit();
mShownCheckPosition = index;
}
if (mDetails != null && mDetails.isVisible()) {
// If the activity has a fragment to display the dialog,
// point it to what the user has selected.
mDetails.setText(position);
getListView().setItemChecked(position, true);
} else { } else {
// Otherwise we need to launch a new activity to display // Otherwise we need to launch a new activity to display
// the dialog fragment with selected text. // the dialog fragment with selected text.
Intent intent = new Intent(); Intent intent = new Intent();
intent.setClass(getActivity(), DetailsActivity.class); intent.setClass(getActivity(), DetailsActivity.class);
intent.putExtra("text", position); intent.putExtra("index", index);
startActivity(intent); startActivity(intent);
} }
} }
} }
//END_INCLUDE(titles) //END_INCLUDE(titles)
/**
* This is the secondary fragment, displaying the details of a particular
* item.
*/
//BEGIN_INCLUDE(details) //BEGIN_INCLUDE(details)
public static class DetailsFragment extends Fragment { public static class DetailsFragment extends Fragment {
int mDisplayedText = -1; /**
TextView mText; * Create a new instance of DetailsFragment, initialized to
* show the text at 'index'.
*/
public static DetailsFragment newInstance(int index) {
DetailsFragment f = new DetailsFragment();
public void setText(int id) { // Supply index input as an argument.
mDisplayedText = id; Bundle args = new Bundle();
if (mText != null && id >= 0) { args.putInt("index", index);
mText.setText(Shakespeare.DIALOGUE[id]); f.setArguments(args);
}
}
@Override return f;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mDisplayedText = savedInstanceState.getInt("text", -1);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("text", mDisplayedText);
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
if (container == null) {
// We have different layouts, and in one of them this
// fragment's containing frame doesn't exist. The fragment
// may still be created from its saved state, but there is
// no reason to try to create its view hierarchy because it
// won't be displayed. Note this is not needed -- we could
// just run the code below, where we would create and return
// the view hierarchy; it would just never be used.
return null;
}
ScrollView scroller = new ScrollView(getActivity()); ScrollView scroller = new ScrollView(getActivity());
mText = new TextView(getActivity()); TextView text = new TextView(getActivity());
int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, int padding = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
4, getActivity().getResources().getDisplayMetrics()); 4, getActivity().getResources().getDisplayMetrics());
mText.setPadding(padding, padding, padding, padding); text.setPadding(padding, padding, padding, padding);
scroller.addView(mText); scroller.addView(text);
if (mDisplayedText >= 0) { text.setText(Shakespeare.DIALOGUE[getArguments().getInt("index", 0)]);
mText.setText(Shakespeare.DIALOGUE[mDisplayedText]);
}
return scroller; return scroller;
} }
} }

View File

@@ -116,6 +116,7 @@ public class FragmentStack extends Activity {
View v = inflater.inflate(R.layout.hello_world, container, false); View v = inflater.inflate(R.layout.hello_world, container, false);
View tv = v.findViewById(R.id.text); View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum); ((TextView)tv).setText("Fragment #" + mNum);
tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
return v; return v;
} }
} }