Retroactively add EffectiveNavigation and TabCompat sample code.
This sample code was launched with the Implementing Effective Navigation and Creating Backward-Compatible UIs training classes, but the source was never added to AOSP. This retroactively adds the source, unmodified. Change-Id: If6face5a0548107f7fd273e466b1ced2790f4f3a
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2012 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.effectivenavigation;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v4.app.TaskStackBuilder;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class CollectionDemoActivity extends FragmentActivity {
|
||||
|
||||
/**
|
||||
* The {@link android.support.v4.view.PagerAdapter} that will provide fragments representing
|
||||
* each object in a collection. We use a {@link android.support.v4.app.FragmentStatePagerAdapter}
|
||||
* derivative, which will destroy and re-create fragments as needed, saving and restoring their
|
||||
* state in the process. This is important to conserve memory and is a best practice when
|
||||
* allowing navigation between objects in a potentially large collection.
|
||||
*/
|
||||
DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;
|
||||
|
||||
/**
|
||||
* The {@link android.support.v4.view.ViewPager} that will display the object collection.
|
||||
*/
|
||||
ViewPager mViewPager;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_collection_demo);
|
||||
|
||||
// Create an adapter that when requested, will return a fragment representing an object in
|
||||
// the collection.
|
||||
//
|
||||
// ViewPager and its adapters use support library fragments, so we must use
|
||||
// getSupportFragmentManager.
|
||||
mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getSupportFragmentManager());
|
||||
|
||||
// Set up action bar.
|
||||
final ActionBar actionBar = getActionBar();
|
||||
|
||||
// Specify that the Home button should show an "Up" caret, indicating that touching the
|
||||
// button will take the user one step up in the application's hierarchy.
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// Set up the ViewPager, attaching the adapter.
|
||||
mViewPager = (ViewPager) findViewById(R.id.pager);
|
||||
mViewPager.setAdapter(mDemoCollectionPagerAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
// This is called when the Home (Up) button is pressed in the action bar.
|
||||
// Create a simple intent that starts the hierarchical parent activity and
|
||||
// use NavUtils in the Support Package to ensure proper handling of Up.
|
||||
Intent upIntent = new Intent(this, MainActivity.class);
|
||||
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
|
||||
// This activity is not part of the application's task, so create a new task
|
||||
// with a synthesized back stack.
|
||||
TaskStackBuilder.from(this)
|
||||
// If there are ancestor activities, they should be added here.
|
||||
.addNextIntent(upIntent)
|
||||
.startActivities();
|
||||
finish();
|
||||
} else {
|
||||
// This activity is part of the application's task, so simply
|
||||
// navigate up to the hierarchical parent activity.
|
||||
NavUtils.navigateUpTo(this, upIntent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link android.support.v4.app.FragmentStatePagerAdapter} that returns a fragment
|
||||
* representing an object in the collection.
|
||||
*/
|
||||
public static class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
|
||||
|
||||
public DemoCollectionPagerAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int i) {
|
||||
Fragment fragment = new DemoObjectFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1); // Our object is just an integer :-P
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
// For this contrived example, we have a 100-object collection.
|
||||
return 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return "OBJECT " + (position + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A dummy fragment representing a section of the app, but that simply displays dummy text.
|
||||
*/
|
||||
public static class DemoObjectFragment extends Fragment {
|
||||
|
||||
public static final String ARG_OBJECT = "object";
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View rootView = inflater.inflate(R.layout.fragment_collection_object, container, false);
|
||||
Bundle args = getArguments();
|
||||
((TextView) rootView.findViewById(android.R.id.text1)).setText(
|
||||
Integer.toString(args.getInt(ARG_OBJECT)));
|
||||
return rootView;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2012 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.effectivenavigation;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
|
||||
|
||||
/**
|
||||
* The {@link android.support.v4.view.PagerAdapter} that will provide fragments for each of the
|
||||
* three primary sections of the app. We use a {@link android.support.v4.app.FragmentPagerAdapter}
|
||||
* derivative, which will keep every loaded fragment in memory. If this becomes too memory
|
||||
* intensive, it may be best to switch to a {@link android.support.v4.app.FragmentStatePagerAdapter}.
|
||||
*/
|
||||
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
|
||||
|
||||
/**
|
||||
* The {@link ViewPager} that will display the three primary sections of the app, one at a
|
||||
* time.
|
||||
*/
|
||||
ViewPager mViewPager;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// Create the adapter that will return a fragment for each of the three primary sections
|
||||
// of the app.
|
||||
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
|
||||
|
||||
// Set up the action bar.
|
||||
final ActionBar actionBar = getActionBar();
|
||||
|
||||
// Specify that the Home/Up button should not be enabled, since there is no hierarchical
|
||||
// parent.
|
||||
actionBar.setHomeButtonEnabled(false);
|
||||
|
||||
// Specify that we will be displaying tabs in the action bar.
|
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||
|
||||
// Set up the ViewPager, attaching the adapter and setting up a listener for when the
|
||||
// user swipes between sections.
|
||||
mViewPager = (ViewPager) findViewById(R.id.pager);
|
||||
mViewPager.setAdapter(mAppSectionsPagerAdapter);
|
||||
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
// When swiping between different app sections, select the corresponding tab.
|
||||
// We can also use ActionBar.Tab#select() to do this if we have a reference to the
|
||||
// Tab.
|
||||
actionBar.setSelectedNavigationItem(position);
|
||||
}
|
||||
});
|
||||
|
||||
// For each of the sections in the app, add a tab to the action bar.
|
||||
for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
|
||||
// Create a tab with text corresponding to the page title defined by the adapter.
|
||||
// Also specify this Activity object, which implements the TabListener interface, as the
|
||||
// listener for when this tab is selected.
|
||||
actionBar.addTab(
|
||||
actionBar.newTab()
|
||||
.setText(mAppSectionsPagerAdapter.getPageTitle(i))
|
||||
.setTabListener(this));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
|
||||
// When the given tab is selected, switch to the corresponding page in the ViewPager.
|
||||
mViewPager.setCurrentItem(tab.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to one of the primary
|
||||
* sections of the app.
|
||||
*/
|
||||
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter {
|
||||
|
||||
public AppSectionsPagerAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
// The first section of the app is the most interesting -- it offers
|
||||
// a launchpad into the other demonstrations in this example application.
|
||||
return new LaunchpadSectionFragment();
|
||||
|
||||
default:
|
||||
// The other sections of the app are dummy placeholders.
|
||||
Fragment fragment = new DummySectionFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return "Section " + (position + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A fragment that launches other parts of the demo application.
|
||||
*/
|
||||
public static class LaunchpadSectionFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View rootView = inflater.inflate(R.layout.fragment_section_launchpad, container, false);
|
||||
|
||||
// Demonstration of a collection-browsing activity.
|
||||
rootView.findViewById(R.id.demo_collection_button)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent intent = new Intent(getActivity(), CollectionDemoActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
// Demonstration of navigating to external activities.
|
||||
rootView.findViewById(R.id.demo_external_activity)
|
||||
.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
// Create an intent that asks the user to pick a photo, but using
|
||||
// FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET, ensures that relaunching
|
||||
// the application from the device home screen does not return
|
||||
// to the external activity.
|
||||
Intent externalActivityIntent = new Intent(Intent.ACTION_PICK);
|
||||
externalActivityIntent.setType("image/*");
|
||||
externalActivityIntent.addFlags(
|
||||
Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||
startActivity(externalActivityIntent);
|
||||
}
|
||||
});
|
||||
|
||||
return rootView;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A dummy fragment representing a section of the app, but that simply displays dummy text.
|
||||
*/
|
||||
public static class DummySectionFragment extends Fragment {
|
||||
|
||||
public static final String ARG_SECTION_NUMBER = "section_number";
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, false);
|
||||
Bundle args = getArguments();
|
||||
((TextView) rootView.findViewById(android.R.id.text1)).setText(
|
||||
getString(R.string.dummy_section_text, args.getInt(ARG_SECTION_NUMBER)));
|
||||
return rootView;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user