am 2622ae27: am 98c5d4a2: Add Support4Demos examples for DrawerLayout and SlidingPaneLayout

* commit '2622ae27adefc16299deb611dc040bec5ad59c73':
  Add Support4Demos examples for DrawerLayout and SlidingPaneLayout
This commit is contained in:
Adam Powell
2013-04-19 09:23:31 -07:00
committed by Android Git Automerger
12 changed files with 601 additions and 1 deletions

View File

@@ -24,7 +24,7 @@
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="13" />
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="17" />
<!-- 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
@@ -276,6 +276,22 @@
</intent-filter>
</activity>
<activity android:name=".widget.DrawerLayoutActivity"
android:label="@string/drawer_layout_support">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.example.android.supportv4.SUPPORT4_SAMPLE_CODE" />
</intent-filter>
</activity>
<activity android:name=".widget.SlidingPaneLayoutActivity"
android:label="@string/sliding_pane_layout_support">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="com.example.android.supportv4.SUPPORT4_SAMPLE_CODE" />
</intent-filter>
</activity>
<provider android:authorities="com.example.supportv4.content.sharingsupportprovider"
android:name=".content.SharingSupportProvider" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 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.
-->
<!--
A DrawerLayout is indended to be used as the top-level content view
using match_parent for both width and height to consume the full space available.
-->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:scrollbarStyle="outsideOverlay">
<TextView android:id="@+id/content_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/drawer_layout_summary"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</ScrollView>
<!-- android:layout_gravity="left" tells DrawerLayout to treat
this as a sliding drawer on the left side. The drawer is
given a fixed width in dp and extends the full height of
the container. A solid background is used for contrast
with the content view. -->
<ListView android:id="@+id/left_drawer"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#ff333333"/>
</android.support.v4.widget.DrawerLayout>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 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.
-->
<!--
A SlidingPaneLayout is indended to be used as the top-level content view
using match_parent for both width and height to consume the full space available.
-->
<android.support.v4.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The first child view becomes the left pane. When the combined
desired width (expressed using android:layout_width) would
not fit on-screen at once, the right pane is permitted to
overlap the left. -->
<ListView android:id="@+id/left_pane"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="left"/>
<!-- The second child becomes the right (content) pane. In this
example, android:layout_weight is used to express that this
pane should grow to consume leftover available space when the
window is wide enough. This allows the content pane to
responsively grow in width on larger screens while still
requiring at least the minimum width expressed by
android:layout_width. -->
<ScrollView
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:scrollbarStyle="outsideOverlay"
android:background="#ff333333">
<TextView android:id="@+id/content_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/sliding_pane_layout_summary"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</ScrollView>
</android.support.v4.widget.SlidingPaneLayout>

View File

@@ -134,4 +134,15 @@
<string name="sharing_support_title">ShareCompat Demo</string>
<string name="sharing_receiver_title">ShareCompat Receiver</string>
<string name="drawer_layout_support">Widget/Drawer layout</string>
<string name="drawer_layout_summary">This activity illustrates the use of sliding drawers. The drawer may be pulled out from the left edge with an edge swipe. If this demo is running on Ice Cream Sandwich or newer you may tap the icon at the left side of the action bar to open the drawer as well.</string>
<string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string>
<string name="sliding_pane_layout_support">Widget/Sliding pane layout</string>
<string name="sliding_pane_layout_summary">This activity illustrates the use of sliding panes. The content pane may be slid to one side on narrow devices to reveal the left pane used to select content. Sliding panes can be used to fit a UI intended for wider screens in a smaller space. Tapping the Action Bar\'s Up button at the left side of the bar will navigate up in the hierarchy, represented by the left pane. If you rotate the device to landscape mode, on most devices you will see that both panes fit together side by side with no sliding necessary.</string>
</resources>

View File

@@ -0,0 +1,244 @@
/*
* Copyright (C) 2013 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.supportv4.widget;
import android.app.ActionBar;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.example.android.supportv4.R;
import com.example.android.supportv4.Shakespeare;
/**
* This example illustrates a common usage of the DrawerLayout widget
* in the Android support library.
*
* <p>A DrawerLayout should be positioned at the top of your view hierarchy, placing it
* below the action bar but above your content views. The primary content should match_parent
* in both dimensions. Each drawer should define a reasonable width and match_parent for height.
* Drawer views should be positioned after the content view in your layout to preserve proper
* ordering.</p>
*
* <p>When a navigation (left) drawer is present, the host activity should detect presses of
* the action bar's Up affordance as a signal to open and close the navigation drawer.
* Items within the drawer should fall into one of two categories.</p>
*
* <ul>
* <li><strong>View switches</strong>. A view switch follows the same basic policies as
* list or tab navigation in that a view switch does not create navigation history.
* This pattern should only be used at the root activity of a task, leaving some form
* of Up navigation active for activities further down the navigation hierarchy.</li>
* <li><strong>Selective Up</strong>. The drawer allows the user to choose an alternate
* parent for Up navigation. This allows a user to jump across an app's navigation
* hierarchy at will. The application should treat this as it treats Up navigation from
* a different task, replacing the current task stack using TaskStackBuilder or similar.
* This is the only form of navigation drawer that should be used outside of the root
* activity of a task.</li>
* </ul>
*
* <p>Right side drawers should be used for actions, not navigation. This follows the pattern
* established by the Action Bar that navigation should be to the left and actions to the right.
* An action should be an operation performed on the current contents of the window,
* for example enabling or disabling a data overlay on top of the current content.</p>
*/
public class DrawerLayoutActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawer;
private TextView mContent;
private ActionBarHelper mActionBar;
private ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.drawer_layout);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawer = (ListView) findViewById(R.id.left_drawer);
mContent = (TextView) findViewById(R.id.content_text);
mDrawerLayout.setDrawerListener(new DemoDrawerListener());
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
mDrawer.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
Shakespeare.TITLES));
mDrawer.setOnItemClickListener(new DrawerItemClickListener());
mActionBar = createActionBarHelper();
mActionBar.init();
// ActionBarDrawerToggle provides convenient helpers for tying together the
// prescribed interactions between a top-level sliding drawer and the action bar.
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/*
* The action bar home/up action should open or close the drawer.
* mDrawerToggle will take care of this.
*/
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
/**
* This list item click listener implements very simple view switching by changing
* the primary content text. The drawer is closed when a selection is made.
*/
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mContent.setText(Shakespeare.DIALOGUE[position]);
mActionBar.setTitle(Shakespeare.TITLES[position]);
mDrawerLayout.closeDrawer(mDrawer);
}
}
/**
* A drawer listener can be used to respond to drawer events such as becoming
* fully opened or closed. You should always prefer to perform expensive operations
* such as drastic relayout when no animation is currently in progress, either before
* or after the drawer animates.
*
* When using ActionBarDrawerToggle, all DrawerLayout listener methods should be forwarded
* if the ActionBarDrawerToggle is not used as the DrawerLayout listener directly.
*/
private class DemoDrawerListener implements DrawerLayout.DrawerListener {
@Override
public void onDrawerOpened(View drawerView) {
mDrawerToggle.onDrawerOpened(drawerView);
mActionBar.onDrawerOpened();
}
@Override
public void onDrawerClosed(View drawerView) {
mDrawerToggle.onDrawerClosed(drawerView);
mActionBar.onDrawerClosed();
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
}
@Override
public void onDrawerStateChanged(int newState) {
mDrawerToggle.onDrawerStateChanged(newState);
}
}
/**
* Create a compatible helper that will manipulate the action bar if available.
*/
private ActionBarHelper createActionBarHelper() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return new ActionBarHelperICS();
} else {
return new ActionBarHelper();
}
}
/**
* Stub action bar helper; this does nothing.
*/
private class ActionBarHelper {
public void init() {}
public void onDrawerClosed() {}
public void onDrawerOpened() {}
public void setTitle(CharSequence title) {}
}
/**
* Action bar helper for use on ICS and newer devices.
*/
private class ActionBarHelperICS extends ActionBarHelper {
private final ActionBar mActionBar;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
ActionBarHelperICS() {
mActionBar = getActionBar();
}
@Override
public void init() {
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setHomeButtonEnabled(true);
mTitle = mDrawerTitle = getTitle();
}
/**
* When the drawer is closed we restore the action bar state reflecting
* the specific contents in view.
*/
@Override
public void onDrawerClosed() {
super.onDrawerClosed();
mActionBar.setTitle(mTitle);
}
/**
* When the drawer is open we set the action bar to a generic title.
* The action bar should only contain data relevant at the top level of
* the nav hierarchy represented by the drawer, as the rest of your content
* will be dimmed down and non-interactive.
*/
@Override
public void onDrawerOpened() {
super.onDrawerOpened();
mActionBar.setTitle(mDrawerTitle);
}
@Override
public void setTitle(CharSequence title) {
mTitle = title;
}
}
}

View File

@@ -0,0 +1,222 @@
/*
* Copyright (C) 2013 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.supportv4.widget;
import android.app.ActionBar;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.widget.SlidingPaneLayout;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.example.android.supportv4.Shakespeare;
import com.example.android.supportv4.R;
/**
* This example illustrates a common usage of SlidingPaneLayout in the Android support library.
*
* <p>A SlidingPaneLayout should be positioned at the top of your view hierarchy, placing it
* below the action bar but above your content views. It is ideal as a two-pane layout
* for larger screens, used in place of a horizontal LinearLayout.</p>
*
* <p>What separates SlidingPaneLayout from LinearLayout in this usage is that SlidingPaneLayout
* allows these wide, two-pane layouts to overlap when horizontal space is at a premium. The user
* can then access both panes by physically sliding the content pane into view or out of the way
* or implicitly by moving focus between the two panes. This can greatly simplify development
* of Android apps that support multiple form factors and screen sizes.</p>
*
* <p>When it comes to your navigation hierarchy, the left pane of a SlidingPaneLayout is always
* considered to be one level up from the right content pane. As such, your Action Bar's
* Up navigation should be enabled if the right pane is obscuring the left pane, and invoking it
* should open the panes, revealing the left pane for normal interaction. From this open state
* where the left pane is in primary focus, the Action Bar's Up affordance should act as if
* both panes were fully visible in the activity window and navigate to the activity one level up
* in the app's logical hierarchy. If the activity is the root of the application's task, the up
* affordance should be disabled when the sliding pane is open and showing the left pane.
* This code example illustrates this root activity case.</p>
*
* <p>Note that SlidingPaneLayout differs in usage from DrawerLayout. While DrawerLayout offers
* sliding utility drawers for extended navigation options and actions, the panes of a
* SlidingPaneLayout are firmly part of the content itself. If it would not make sense for
* both panes to be visible all the time on a sufficiently wide screen, DrawerLayout and its
* associated patterns are likely to be a better choice for your usage.</p>
*/
public class SlidingPaneLayoutActivity extends Activity {
private SlidingPaneLayout mSlidingLayout;
private ListView mList;
private TextView mContent;
private ActionBarHelper mActionBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sliding_pane_layout);
mSlidingLayout = (SlidingPaneLayout) findViewById(R.id.sliding_pane_layout);
mList = (ListView) findViewById(R.id.left_pane);
mContent = (TextView) findViewById(R.id.content_text);
mSlidingLayout.setPanelSlideListener(new SliderListener());
mSlidingLayout.openPane();
mList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
Shakespeare.TITLES));
mList.setOnItemClickListener(new ListItemClickListener());
mActionBar = createActionBarHelper();
mActionBar.init();
mSlidingLayout.getViewTreeObserver().addOnGlobalLayoutListener(new FirstLayoutListener());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/*
* The action bar up action should open the slider if it is currently closed,
* as the left pane contains content one level up in the navigation hierarchy.
*/
if (item.getItemId() == android.R.id.home && !mSlidingLayout.isOpen()) {
mSlidingLayout.smoothSlideOpen();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* This list item click listener implements very simple view switching by changing
* the primary content text. The slider is closed when a selection is made to fully
* reveal the content.
*/
private class ListItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mContent.setText(Shakespeare.DIALOGUE[position]);
mActionBar.setTitle(Shakespeare.TITLES[position]);
mSlidingLayout.smoothSlideClosed();
}
}
/**
* This panel slide listener updates the action bar accordingly for each panel state.
*/
private class SliderListener extends SlidingPaneLayout.SimplePanelSlideListener {
@Override
public void onPanelOpened(View panel) {
mActionBar.onPanelOpened();
}
@Override
public void onPanelClosed(View panel) {
mActionBar.onPanelClosed();
}
}
/**
* This global layout listener is used to fire an event after first layout occurs
* and then it is removed. This gives us a chance to configure parts of the UI
* that adapt based on available space after they have had the opportunity to measure
* and layout.
*/
private class FirstLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
@Override
public void onGlobalLayout() {
mActionBar.onFirstLayout();
mSlidingLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
/**
* Create a compatible helper that will manipulate the action bar if available.
*/
private ActionBarHelper createActionBarHelper() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return new ActionBarHelperICS();
} else {
return new ActionBarHelper();
}
}
/**
* Stub action bar helper; this does nothing.
*/
private class ActionBarHelper {
public void init() {}
public void onPanelClosed() {}
public void onPanelOpened() {}
public void onFirstLayout() {}
public void setTitle(CharSequence title) {}
}
/**
* Action bar helper for use on ICS and newer devices.
*/
private class ActionBarHelperICS extends ActionBarHelper {
private final ActionBar mActionBar;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
ActionBarHelperICS() {
mActionBar = getActionBar();
}
@Override
public void init() {
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setHomeButtonEnabled(true);
mTitle = mDrawerTitle = getTitle();
}
@Override
public void onPanelClosed() {
super.onPanelClosed();
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setHomeButtonEnabled(true);
mActionBar.setTitle(mTitle);
}
@Override
public void onPanelOpened() {
super.onPanelOpened();
mActionBar.setHomeButtonEnabled(false);
mActionBar.setDisplayHomeAsUpEnabled(false);
mActionBar.setTitle(mDrawerTitle);
}
@Override
public void onFirstLayout() {
if (mSlidingLayout.canSlide() && !mSlidingLayout.isOpen()) {
onPanelClosed();
} else {
onPanelOpened();
}
}
@Override
public void setTitle(CharSequence title) {
mTitle = title;
}
}
}