mirror of https://github.com/tasks/tasks
updated actionbarsherlock to 3.5.0
parent
cae873ae69
commit
fc99549dec
Binary file not shown.
@ -1,52 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 Johan Nilsson <http://markupartist.com>
|
||||
Copyright (C) 2011 Jake Wharton <jakewharton@gmail.com>
|
||||
|
||||
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.
|
||||
-->
|
||||
<com.actionbarsherlock.internal.view.menu.ActionMenuItemView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:addStatesFromChildren="true"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center"
|
||||
android:minWidth="45dip"
|
||||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
>
|
||||
<ImageView
|
||||
android:id="@+id/abs__item_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center_vertical"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/abs__item_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toRightOf="@id/abs__item_icon"
|
||||
android:gravity="center_vertical"
|
||||
android:visibility="gone"
|
||||
android:textColor="?attr/actionMenuTextColor"
|
||||
style="?attr/actionMenuTextAppearance"
|
||||
/>
|
||||
<FrameLayout
|
||||
android:id="@+id/abs__item_custom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
</com.actionbarsherlock.internal.view.menu.ActionMenuItemView>
|
@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 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.
|
||||
-->
|
||||
|
||||
<com.actionbarsherlock.internal.view.menu.ActionMenuItemView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:addStatesFromChildren="true"
|
||||
android:gravity="center"
|
||||
android:focusable="true"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
style="?attr/actionButtonStyle">
|
||||
<ImageButton android:id="@+id/abs__imageButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="4dip"
|
||||
android:layout_marginBottom="4dip"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:layout_marginRight="4dip"
|
||||
android:scaleType="fitCenter"
|
||||
android:adjustViewBounds="true"
|
||||
android:background="@null"
|
||||
android:focusable="false" />
|
||||
<Button android:id="@+id/abs__textButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"
|
||||
android:textAppearance="?attr/actionMenuTextAppearance"
|
||||
android:textColor="?attr/actionMenuTextColor"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="none"
|
||||
android:background="@null"
|
||||
android:paddingTop="4dip"
|
||||
android:paddingBottom="4dip"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:focusable="false" />
|
||||
</com.actionbarsherlock.internal.view.menu.ActionMenuItemView>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 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.
|
||||
-->
|
||||
|
||||
<com.actionbarsherlock.internal.view.menu.ActionMenuView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:divider="?attr/abDivider"
|
||||
android:dividerPadding="12dip"
|
||||
android:gravity="center_vertical" />
|
@ -1,48 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 The Android Open Source Project
|
||||
Copyright (C) 2011 Jake Wharton
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This is an optimized layout for a screen with the Action Bar (Tab's inlined) enabled.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical"
|
||||
android:fitsSystemWindows="true"
|
||||
>
|
||||
<com.actionbarsherlock.internal.widget.ActionBarContainer
|
||||
android:id="@+id/abs__action_bar_container"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="?attr/abHeight"
|
||||
android:background="?attr/abBackground"
|
||||
>
|
||||
<com.actionbarsherlock.internal.widget.ActionBarView
|
||||
android:id="@+id/abs__action_bar"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
</com.actionbarsherlock.internal.widget.ActionBarContainer>
|
||||
<FrameLayout
|
||||
android:id="@+id/abs__content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
android:foregroundGravity="fill_horizontal|top"
|
||||
android:foreground="?android:attr/windowContentOverlay"
|
||||
/>
|
||||
</LinearLayout>
|
@ -1,49 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 The Android Open Source Project
|
||||
Copyright (C) 2011 Jake Wharton
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This is an optimized layout for a screen with
|
||||
the Action Bar (Tab's inlined) enabled overlaying application content.
|
||||
-->
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
<FrameLayout
|
||||
android:id="@+id/abs__content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
<com.actionbarsherlock.internal.widget.ActionBarContainer
|
||||
android:id="@+id/abs__action_bar_container"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="?attr/abHeight"
|
||||
android:background="?attr/abBackground"
|
||||
android:gravity="top">
|
||||
<com.actionbarsherlock.internal.widget.ActionBarView
|
||||
android:id="@+id/abs__action_bar"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
</com.actionbarsherlock.internal.widget.ActionBarContainer>
|
||||
<ImageView
|
||||
android:src="?android:attr/windowContentOverlay"
|
||||
android:scaleType="fitXY"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/abs__action_bar_container" />
|
||||
</RelativeLayout>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/* //device/apps/common/assets/res/any/dimens.xml
|
||||
**
|
||||
** Copyright 2006, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<!-- Default height of an action bar. -->
|
||||
<dimen name="abs__action_bar_default_height">40dip</dimen>
|
||||
</resources>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/* //device/apps/common/assets/res/any/dimens.xml
|
||||
**
|
||||
** Copyright 2006, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<!-- Default height of an action bar. -->
|
||||
<dimen name="abs__action_bar_default_height">48dip</dimen>
|
||||
</resources>
|
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2009, 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!-- These resources are around just to allow their values to be customized
|
||||
for different hardware and product builds. -->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<!-- Whether action menu items should obey the "withText" showAsAction
|
||||
flag. This may be set to false for situations where space is
|
||||
extremely limited. -->
|
||||
<bool name="abs__config_allowActionMenuItemTextWithIcon">true</bool>
|
||||
|
||||
</resources>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/* //device/apps/common/assets/res/any/dimens.xml
|
||||
**
|
||||
** Copyright 2006, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<!-- Default height of an action bar. -->
|
||||
<dimen name="abs__action_bar_default_height">56dip</dimen>
|
||||
</resources>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/* //device/apps/common/assets/res/any/dimens.xml
|
||||
**
|
||||
** Copyright 2006, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<!-- Default height of an action bar. -->
|
||||
<dimen name="abs__action_bar_default_height">56dip</dimen>
|
||||
</resources>
|
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2009, 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!-- These resources are around just to allow their values to be customized
|
||||
for different hardware and product builds. -->
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<!-- Whether action menu items should obey the "withText" showAsAction
|
||||
flag. This may be set to false for situations where space is
|
||||
extremely limited. -->
|
||||
<bool name="abs__config_allowActionMenuItemTextWithIcon">false</bool>
|
||||
|
||||
<color name="abs__item_focused">#FF6899FF</color>
|
||||
<integer name="abs__max_action_buttons">3</integer>
|
||||
<string name="abs__tab_under_ab_tag">tabUnderAb</string>
|
||||
|
||||
</resources>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<color name="abs__item_focused">#FF6899FF</color>
|
||||
<integer name="abs__max_action_buttons">3</integer>
|
||||
<string name="abs__tab_under_ab_tag">tabUnderAb</string>
|
||||
</resources>
|
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/* //device/apps/common/assets/res/any/dimens.xml
|
||||
**
|
||||
** Copyright 2006, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<!-- Default height of an action bar. -->
|
||||
<dimen name="abs__action_bar_default_height">48dip</dimen>
|
||||
</resources>
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
**
|
||||
** Copyright 2007, 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.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<item type="id" name="abs__action_menu_presenter" />
|
||||
</resources>
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 android.support.v4.app;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Use {@link FragmentActivity}.
|
||||
*/
|
||||
@Deprecated
|
||||
class ActivityCompatHoneycomb {
|
||||
/** @Deprecated Use {@link FragmentActivity#invalidateOptionsMenu()}. */
|
||||
@Deprecated
|
||||
static void invalidateOptionsMenu(Activity activity) {
|
||||
activity.invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
/** @Deprecated Use {@link FragmentActivity#dump(String, FileDescriptor, PrintWriter, String[])}. */
|
||||
@Deprecated
|
||||
static void dump(Activity activity, String prefix, FileDescriptor fd,
|
||||
PrintWriter writer, String[] args) {
|
||||
activity.dump(prefix, fd, writer, args);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 android.support.v4.app;
|
||||
|
||||
/**
|
||||
* Helper for accessing features in {@link android.app.Service}
|
||||
* introduced after API level 4 in a backwards compatible fashion.
|
||||
*/
|
||||
public class ServiceCompat {
|
||||
|
||||
private ServiceCompat() {
|
||||
/* Hide constructor */
|
||||
}
|
||||
|
||||
/**
|
||||
* Constant to return from {@link android.app.Service#onStartCommand}: if this
|
||||
* service's process is killed while it is started (after returning from
|
||||
* {@link android.app.Service#onStartCommand}), then leave it in the started
|
||||
* state but don't retain this delivered intent. Later the system will try to
|
||||
* re-create the service. Because it is in the started state, it will
|
||||
* guarantee to call {@link android.app.Service#onStartCommand} after creating
|
||||
* the new service instance; if there are not any pending start commands to be
|
||||
* delivered to the service, it will be called with a null intent
|
||||
* object, so you must take care to check for this.
|
||||
*
|
||||
* <p>This mode makes sense for things that will be explicitly started
|
||||
* and stopped to run for arbitrary periods of time, such as a service
|
||||
* performing background music playback.
|
||||
*/
|
||||
public static final int START_STICKY = 1;
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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 android.support.v4.content;
|
||||
|
||||
/**
|
||||
* Helper for accessing features in {@link android.content.Intent}
|
||||
* introduced after API level 4 in a backwards compatible fashion.
|
||||
*/
|
||||
public class IntentCompat {
|
||||
|
||||
private IntentCompat() {
|
||||
/* Hide constructor */
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast Action: Resources for a set of packages (which were
|
||||
* previously unavailable) are currently
|
||||
* available since the media on which they exist is available.
|
||||
* The extra data {@link #EXTRA_CHANGED_PACKAGE_LIST} contains a
|
||||
* list of packages whose availability changed.
|
||||
* The extra data {@link #EXTRA_CHANGED_UID_LIST} contains a
|
||||
* list of uids of packages whose availability changed.
|
||||
* Note that the
|
||||
* packages in this list do <em>not</em> receive this broadcast.
|
||||
* The specified set of packages are now available on the system.
|
||||
* <p>Includes the following extras:
|
||||
* <ul>
|
||||
* <li> {@link #EXTRA_CHANGED_PACKAGE_LIST} is the set of packages
|
||||
* whose resources(were previously unavailable) are currently available.
|
||||
* {@link #EXTRA_CHANGED_UID_LIST} is the set of uids of the
|
||||
* packages whose resources(were previously unavailable)
|
||||
* are currently available.
|
||||
* </ul>
|
||||
*
|
||||
* <p class="note">This is a protected intent that can only be sent
|
||||
* by the system.
|
||||
*/
|
||||
public static final String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE =
|
||||
"android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE";
|
||||
|
||||
/**
|
||||
* Broadcast Action: Resources for a set of packages are currently
|
||||
* unavailable since the media on which they exist is unavailable.
|
||||
* The extra data {@link #EXTRA_CHANGED_PACKAGE_LIST} contains a
|
||||
* list of packages whose availability changed.
|
||||
* The extra data {@link #EXTRA_CHANGED_UID_LIST} contains a
|
||||
* list of uids of packages whose availability changed.
|
||||
* The specified set of packages can no longer be
|
||||
* launched and are practically unavailable on the system.
|
||||
* <p>Inclues the following extras:
|
||||
* <ul>
|
||||
* <li> {@link #EXTRA_CHANGED_PACKAGE_LIST} is the set of packages
|
||||
* whose resources are no longer available.
|
||||
* {@link #EXTRA_CHANGED_UID_LIST} is the set of packages
|
||||
* whose resources are no longer available.
|
||||
* </ul>
|
||||
*
|
||||
* <p class="note">This is a protected intent that can only be sent
|
||||
* by the system.
|
||||
*/
|
||||
public static final String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE =
|
||||
"android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE";
|
||||
|
||||
/**
|
||||
* This field is part of
|
||||
* {@link android.content.Intent#ACTION_EXTERNAL_APPLICATIONS_AVAILABLE},
|
||||
* {@link android.content.Intent#ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE}
|
||||
* and contains a string array of all of the components that have changed.
|
||||
*/
|
||||
public static final String EXTRA_CHANGED_PACKAGE_LIST =
|
||||
"android.intent.extra.changed_package_list";
|
||||
|
||||
/**
|
||||
* This field is part of
|
||||
* {@link android.content.Intent#ACTION_EXTERNAL_APPLICATIONS_AVAILABLE},
|
||||
* {@link android.content.Intent#ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE}
|
||||
* and contains an integer array of uids of all of the components
|
||||
* that have changed.
|
||||
*/
|
||||
public static final String EXTRA_CHANGED_UID_LIST =
|
||||
"android.intent.extra.changed_uid_list";
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 android.support.v4.content.pm;
|
||||
|
||||
/**
|
||||
* Helper for accessing features in {@link android.content.pm.ActivityInfo}
|
||||
* introduced after API level 4 in a backwards compatible fashion.
|
||||
*/
|
||||
public class ActivityInfoCompat {
|
||||
|
||||
private ActivityInfoCompat() {
|
||||
/* Hide constructor */
|
||||
}
|
||||
|
||||
/**
|
||||
* Bit in ActivityInfo#configChanges that indicates that the
|
||||
* activity can itself handle the ui mode. Set from the
|
||||
* {@link android.R.attr#configChanges} attribute.
|
||||
*/
|
||||
public static final int CONFIG_UI_MODE = 0x0200;
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 android.support.v4.database;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
/**
|
||||
* Helper for accessing features in {@link android.database.DatabaseUtils}
|
||||
* introduced after API level 4 in a backwards compatible fashion.
|
||||
*/
|
||||
public class DatabaseUtilsCompat {
|
||||
|
||||
private DatabaseUtilsCompat() {
|
||||
/* Hide constructor */
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates two SQL WHERE clauses, handling empty or null values.
|
||||
*/
|
||||
public static String concatenateWhere(String a, String b) {
|
||||
if (TextUtils.isEmpty(a)) {
|
||||
return b;
|
||||
}
|
||||
if (TextUtils.isEmpty(b)) {
|
||||
return a;
|
||||
}
|
||||
|
||||
return "(" + a + ") AND (" + b + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends one set of selection args to another. This is useful when adding a selection
|
||||
* argument to a user provided set.
|
||||
*/
|
||||
public static String[] appendSelectionArgs(String[] originalValues, String[] newValues) {
|
||||
if (originalValues == null || originalValues.length == 0) {
|
||||
return newValues;
|
||||
}
|
||||
String[] result = new String[originalValues.length + newValues.length ];
|
||||
System.arraycopy(originalValues, 0, result, 0, originalValues.length);
|
||||
System.arraycopy(newValues, 0, result, originalValues.length, newValues.length);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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 android.support.v4.view;
|
||||
|
||||
import android.view.MenuItem;
|
||||
|
||||
/**
|
||||
* Use {@link FragmentActivity}, {@link Menu}, and {@link MenuItem}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MenuCompat {
|
||||
|
||||
/**
|
||||
* Interface for the full API.
|
||||
*/
|
||||
interface MenuVersionImpl {
|
||||
public boolean setShowAsAction(MenuItem item, int actionEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface implementation that doesn't use anything about v4 APIs.
|
||||
*/
|
||||
static class BaseMenuVersionImpl implements MenuVersionImpl {
|
||||
@Override
|
||||
public boolean setShowAsAction(MenuItem item, int actionEnum) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface implementation for devices with at least v11 APIs.
|
||||
*/
|
||||
static class HoneycombMenuVersionImpl implements MenuVersionImpl {
|
||||
@Override
|
||||
public boolean setShowAsAction(MenuItem item, int actionEnum) {
|
||||
MenuItemCompatHoneycomb.setShowAsAction(item, actionEnum);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the correct implementation to use for the current platform.
|
||||
*/
|
||||
static final MenuVersionImpl IMPL;
|
||||
static {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
IMPL = new HoneycombMenuVersionImpl();
|
||||
} else {
|
||||
IMPL = new BaseMenuVersionImpl();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Call {@link MenuItem#setShowAsAction(int) MenuItem.setShowAsAction()}.
|
||||
* If running on a pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} device,
|
||||
* does nothing and returns false. Otherwise returns true.
|
||||
*
|
||||
* @deprecated Use {@link MenuItemCompat#setShowAsAction(MenuItem, int)
|
||||
* MenuItemCompat.setShowAsAction(MenuItem, int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean setShowAsAction(MenuItem item, int actionEnum) {
|
||||
return IMPL.setShowAsAction(item, actionEnum);
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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 android.support.v4.view;
|
||||
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* @Deprecated Use {@link FragmentActivity}, {@link Menu}, and {@link MenuItem}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MenuItemCompat {
|
||||
|
||||
/**
|
||||
* @Deprecated Use {@link MenuItem#SHOW_AS_ACTION_NEVER}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int SHOW_AS_ACTION_NEVER = 0;
|
||||
|
||||
/**
|
||||
* @Deprecated Use {@link MenuItem#SHOW_AS_ACTION_IF_ROOM}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int SHOW_AS_ACTION_IF_ROOM = 1;
|
||||
|
||||
/**
|
||||
* @Deprecated Use {@link MenuItem#SHOW_AS_ACTION_ALWAYS}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int SHOW_AS_ACTION_ALWAYS = 2;
|
||||
|
||||
/**
|
||||
* @Deprecated Use {@link MenuItem#SHOW_AS_ACTION_WITH_TEXT}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int SHOW_AS_ACTION_WITH_TEXT = 4;
|
||||
|
||||
/**
|
||||
* This item's action view collapses to a normal menu item.
|
||||
* When expanded, the action view temporarily takes over
|
||||
* a larger segment of its container.
|
||||
*/
|
||||
public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8;
|
||||
|
||||
/**
|
||||
* Interface for the full API.
|
||||
*/
|
||||
interface MenuVersionImpl {
|
||||
public boolean setShowAsAction(MenuItem item, int actionEnum);
|
||||
public MenuItem setActionView(MenuItem item, View view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface implementation that doesn't use anything about v4 APIs.
|
||||
*/
|
||||
static class BaseMenuVersionImpl implements MenuVersionImpl {
|
||||
@Override
|
||||
public boolean setShowAsAction(MenuItem item, int actionEnum) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuItem setActionView(MenuItem item, View view) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface implementation for devices with at least v11 APIs.
|
||||
*/
|
||||
static class HoneycombMenuVersionImpl implements MenuVersionImpl {
|
||||
@Override
|
||||
public boolean setShowAsAction(MenuItem item, int actionEnum) {
|
||||
MenuItemCompatHoneycomb.setShowAsAction(item, actionEnum);
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public MenuItem setActionView(MenuItem item, View view) {
|
||||
return MenuItemCompatHoneycomb.setActionView(item, view);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the correct implementation to use for the current platform.
|
||||
*/
|
||||
static final MenuVersionImpl IMPL;
|
||||
static {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
IMPL = new HoneycombMenuVersionImpl();
|
||||
} else {
|
||||
IMPL = new BaseMenuVersionImpl();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
/** @Deprecated Use {@link MenuItem#setShowAsAction(int)}. */
|
||||
@Deprecated
|
||||
public static boolean setShowAsAction(MenuItem item, int actionEnum) {
|
||||
return IMPL.setShowAsAction(item, actionEnum);
|
||||
}
|
||||
|
||||
/** @Deprecated Use {@link MenuItem#setActionView(int)}. */
|
||||
@Deprecated
|
||||
public static MenuItem setActionView(MenuItem item, View view) {
|
||||
return IMPL.setActionView(item, view);
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 android.support.v4.view;
|
||||
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Implementation of menu compatibility that can call Honeycomb APIs.
|
||||
*/
|
||||
class MenuItemCompatHoneycomb {
|
||||
public static void setShowAsAction(MenuItem item, int actionEnum) {
|
||||
item.setShowAsAction(actionEnum);
|
||||
}
|
||||
|
||||
public static MenuItem setActionView(MenuItem item, View view) {
|
||||
return item.setActionView(view);
|
||||
}
|
||||
}
|
@ -0,0 +1,326 @@
|
||||
/*
|
||||
* 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 android.support.v4.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.database.DataSetObserver;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils.TruncateAt;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* PagerTitleStrip is a non-interactive indicator of the current, next,
|
||||
* and previous pages of a {@link ViewPager}. It is intended to be used as a
|
||||
* child view of a ViewPager widget in your XML layout.
|
||||
* Add it as a child of a ViewPager in your layout file and set its
|
||||
* android:layout_gravity to TOP or BOTTOM to pin it to the top or bottom
|
||||
* of the ViewPager. The title from each page is supplied by the method
|
||||
* {@link PagerAdapter#getPageTitle(int)} in the adapter supplied to
|
||||
* the ViewPager.
|
||||
*/
|
||||
public class PagerTitleStrip extends ViewGroup implements ViewPager.Decor {
|
||||
//private static final String TAG = "PagerTitleStrip";
|
||||
|
||||
ViewPager mPager;
|
||||
private TextView mPrevText;
|
||||
private TextView mCurrText;
|
||||
private TextView mNextText;
|
||||
|
||||
private int mLastKnownCurrentPage = -1;
|
||||
private float mLastKnownPositionOffset = -1;
|
||||
private int mScaledTextSpacing;
|
||||
|
||||
private boolean mUpdatingText;
|
||||
private boolean mUpdatingPositions;
|
||||
|
||||
private final PageListener mPageListener = new PageListener();
|
||||
|
||||
private static final int[] ATTRS = new int[] {
|
||||
android.R.attr.textAppearance,
|
||||
android.R.attr.textColor,
|
||||
android.R.attr.textSize
|
||||
};
|
||||
|
||||
private static final int SIDE_ALPHA = 0x99; // single-byte alpha, 0 = invisible, FF = opaque
|
||||
private static final int TEXT_SPACING = 16; // dip
|
||||
|
||||
public PagerTitleStrip(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public PagerTitleStrip(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
addView(mPrevText = new TextView(context));
|
||||
addView(mCurrText = new TextView(context));
|
||||
addView(mNextText = new TextView(context));
|
||||
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
|
||||
final int textAppearance = a.getResourceId(0, 0);
|
||||
if (textAppearance != 0) {
|
||||
mPrevText.setTextAppearance(context, textAppearance);
|
||||
mCurrText.setTextAppearance(context, textAppearance);
|
||||
mNextText.setTextAppearance(context, textAppearance);
|
||||
}
|
||||
if (a.hasValue(1)) {
|
||||
final int textColor = a.getColor(1, 0);
|
||||
mPrevText.setTextColor(textColor);
|
||||
mCurrText.setTextColor(textColor);
|
||||
mNextText.setTextColor(textColor);
|
||||
}
|
||||
final int textSize = a.getDimensionPixelSize(2, 0);
|
||||
if (textSize != 0) {
|
||||
mPrevText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
|
||||
mCurrText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
|
||||
mNextText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
|
||||
}
|
||||
a.recycle();
|
||||
|
||||
final int defaultColor = mPrevText.getTextColors().getDefaultColor();
|
||||
final int transparentColor = (SIDE_ALPHA << 24) | (defaultColor & 0xFFFFFF);
|
||||
mPrevText.setTextColor(transparentColor);
|
||||
mNextText.setTextColor(transparentColor);
|
||||
|
||||
mPrevText.setEllipsize(TruncateAt.END);
|
||||
mCurrText.setEllipsize(TruncateAt.END);
|
||||
mNextText.setEllipsize(TruncateAt.END);
|
||||
mPrevText.setSingleLine();
|
||||
mCurrText.setSingleLine();
|
||||
mNextText.setSingleLine();
|
||||
|
||||
final float density = context.getResources().getDisplayMetrics().density;
|
||||
mScaledTextSpacing = (int) (TEXT_SPACING * density);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
final ViewParent parent = getParent();
|
||||
if (!(parent instanceof ViewPager)) {
|
||||
throw new IllegalStateException(
|
||||
"PagerTitleStrip must be a direct child of a ViewPager.");
|
||||
}
|
||||
|
||||
final ViewPager pager = (ViewPager) parent;
|
||||
final PagerAdapter adapter = pager.getAdapter();
|
||||
|
||||
pager.setInternalPageChangeListener(mPageListener);
|
||||
pager.setOnAdapterChangeListener(mPageListener);
|
||||
mPager = pager;
|
||||
updateAdapter(null, adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
updateAdapter(mPager.getAdapter(), null);
|
||||
mPager.setInternalPageChangeListener(null);
|
||||
mPager.setOnAdapterChangeListener(null);
|
||||
mPager = null;
|
||||
}
|
||||
|
||||
void updateText(int currentItem, PagerAdapter adapter) {
|
||||
final int itemCount = adapter != null ? adapter.getCount() : 0;
|
||||
mUpdatingText = true;
|
||||
|
||||
CharSequence text = null;
|
||||
if (currentItem >= 1 && adapter != null) {
|
||||
text = adapter.getPageTitle(currentItem - 1);
|
||||
}
|
||||
mPrevText.setText(text);
|
||||
|
||||
mCurrText.setText(adapter != null ? adapter.getPageTitle(currentItem) : null);
|
||||
|
||||
text = null;
|
||||
if (currentItem + 1 < itemCount && adapter != null) {
|
||||
text = adapter.getPageTitle(currentItem + 1);
|
||||
}
|
||||
mNextText.setText(text);
|
||||
|
||||
// Measure everything
|
||||
final int width = getWidth() - getPaddingLeft() - getPaddingRight();
|
||||
final int childHeight = getHeight() - getPaddingTop() - getPaddingBottom();
|
||||
final int childWidthSpec = MeasureSpec.makeMeasureSpec((int) (width * 0.8f),
|
||||
MeasureSpec.AT_MOST);
|
||||
final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY);
|
||||
mPrevText.measure(childWidthSpec, childHeightSpec);
|
||||
mCurrText.measure(childWidthSpec, childHeightSpec);
|
||||
mNextText.measure(childWidthSpec, childHeightSpec);
|
||||
|
||||
mLastKnownCurrentPage = currentItem;
|
||||
|
||||
if (!mUpdatingPositions) {
|
||||
updateTextPositions(currentItem, mLastKnownPositionOffset);
|
||||
}
|
||||
|
||||
mUpdatingText = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
if (!mUpdatingText) {
|
||||
super.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
void updateAdapter(PagerAdapter oldAdapter, PagerAdapter newAdapter) {
|
||||
if (oldAdapter != null) {
|
||||
oldAdapter.unregisterDataSetObserver(mPageListener);
|
||||
}
|
||||
if (newAdapter != null) {
|
||||
newAdapter.registerDataSetObserver(mPageListener);
|
||||
}
|
||||
if (mPager != null) {
|
||||
mLastKnownCurrentPage = -1;
|
||||
mLastKnownPositionOffset = -1;
|
||||
updateText(mPager.getCurrentItem(), newAdapter);
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
void updateTextPositions(int position, float positionOffset) {
|
||||
if (position != mLastKnownCurrentPage) {
|
||||
updateText(position, mPager.getAdapter());
|
||||
} else if (positionOffset == mLastKnownPositionOffset) {
|
||||
return;
|
||||
}
|
||||
|
||||
mUpdatingPositions = true;
|
||||
|
||||
final int prevWidth = mPrevText.getMeasuredWidth();
|
||||
final int currWidth = mCurrText.getMeasuredWidth();
|
||||
final int nextWidth = mNextText.getMeasuredWidth();
|
||||
final int halfCurrWidth = currWidth / 2;
|
||||
|
||||
final int stripWidth = getWidth();
|
||||
final int paddingLeft = getPaddingLeft();
|
||||
final int paddingRight = getPaddingRight();
|
||||
final int paddingTop = getPaddingTop();
|
||||
final int textPaddedLeft = paddingLeft + halfCurrWidth;
|
||||
final int textPaddedRight = paddingRight + halfCurrWidth;
|
||||
final int contentWidth = stripWidth - textPaddedLeft - textPaddedRight;
|
||||
|
||||
float currOffset = positionOffset + 0.5f;
|
||||
if (currOffset > 1.f) {
|
||||
currOffset -= 1.f;
|
||||
}
|
||||
final int currCenter = stripWidth - textPaddedRight - (int) (contentWidth * currOffset);
|
||||
final int currLeft = currCenter - currWidth / 2;
|
||||
final int currRight = currLeft + currWidth;
|
||||
|
||||
mCurrText.layout(currLeft, paddingTop, currRight,
|
||||
paddingTop + mCurrText.getMeasuredHeight());
|
||||
|
||||
final int prevLeft = Math.min(paddingLeft, currLeft - mScaledTextSpacing - prevWidth);
|
||||
mPrevText.layout(prevLeft, paddingTop, prevLeft + prevWidth,
|
||||
paddingTop + mPrevText.getMeasuredHeight());
|
||||
|
||||
final int nextLeft = Math.max(stripWidth - paddingRight - nextWidth,
|
||||
currRight + mScaledTextSpacing);
|
||||
mNextText.layout(nextLeft, paddingTop, nextLeft + nextWidth,
|
||||
paddingTop + mNextText.getMeasuredHeight());
|
||||
|
||||
mLastKnownPositionOffset = positionOffset;
|
||||
mUpdatingPositions = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
if (widthMode != MeasureSpec.EXACTLY) {
|
||||
throw new IllegalStateException("Must measure with an exact width");
|
||||
}
|
||||
|
||||
int childHeight = heightSize;
|
||||
int minHeight = 0;
|
||||
int padding = 0;
|
||||
final Drawable bg = getBackground();
|
||||
if (bg != null) {
|
||||
minHeight = bg.getIntrinsicHeight();
|
||||
}
|
||||
padding = getPaddingTop() + getPaddingBottom();
|
||||
childHeight -= padding;
|
||||
|
||||
final int childWidthSpec = MeasureSpec.makeMeasureSpec((int) (widthSize * 0.8f),
|
||||
MeasureSpec.AT_MOST);
|
||||
final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight, heightMode);
|
||||
|
||||
mPrevText.measure(childWidthSpec, childHeightSpec);
|
||||
mCurrText.measure(childWidthSpec, childHeightSpec);
|
||||
mNextText.measure(childWidthSpec, childHeightSpec);
|
||||
|
||||
if (heightMode == MeasureSpec.EXACTLY) {
|
||||
setMeasuredDimension(widthSize, heightSize);
|
||||
} else {
|
||||
int textHeight = mCurrText.getMeasuredHeight();
|
||||
setMeasuredDimension(widthSize, Math.max(minHeight, textHeight + padding));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
if (mPager != null) {
|
||||
updateTextPositions(mPager.getCurrentItem(), 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
private class PageListener extends DataSetObserver implements ViewPager.OnPageChangeListener,
|
||||
ViewPager.OnAdapterChangeListener {
|
||||
private int mScrollState;
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
if (positionOffset > 0.5f) {
|
||||
// Consider ourselves to be on the next page when we're 50% of the way there.
|
||||
position++;
|
||||
}
|
||||
updateTextPositions(position, positionOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
|
||||
// Only update the text here if we're not dragging or settling.
|
||||
updateText(mPager.getCurrentItem(), mPager.getAdapter());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
mScrollState = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdapterChanged(PagerAdapter oldAdapter, PagerAdapter newAdapter) {
|
||||
updateAdapter(oldAdapter, newAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChanged() {
|
||||
updateText(mPager.getCurrentItem(), mPager.getAdapter());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.support.v4.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Helper for accessing features in {@link android.widget.SearchView}
|
||||
* introduced after API level 4 in a backwards compatible fashion.
|
||||
*/
|
||||
public class SearchViewCompat {
|
||||
|
||||
interface SearchViewCompatImpl {
|
||||
View newSearchView(Context context);
|
||||
Object newOnQueryTextListener(OnQueryTextListenerCompat listener);
|
||||
void setOnQueryTextListener(Object searchView, Object listener);
|
||||
}
|
||||
|
||||
static class SearchViewCompatStubImpl implements SearchViewCompatImpl {
|
||||
|
||||
@Override
|
||||
public View newSearchView(Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object newOnQueryTextListener(OnQueryTextListenerCompat listener) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnQueryTextListener(Object searchView, Object listener) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class SearchViewCompatHoneycombImpl extends SearchViewCompatStubImpl {
|
||||
|
||||
@Override
|
||||
public View newSearchView(Context context) {
|
||||
return SearchViewCompatHoneycomb.newSearchView(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object newOnQueryTextListener(final OnQueryTextListenerCompat listener) {
|
||||
return SearchViewCompatHoneycomb.newOnQueryTextListener(
|
||||
new SearchViewCompatHoneycomb.OnQueryTextListenerCompatBridge() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return listener.onQueryTextSubmit(query);
|
||||
}
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
return listener.onQueryTextChange(newText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnQueryTextListener(Object searchView, Object listener) {
|
||||
SearchViewCompatHoneycomb.setOnQueryTextListener(searchView, listener);
|
||||
}
|
||||
}
|
||||
|
||||
private static final SearchViewCompatImpl IMPL;
|
||||
|
||||
static {
|
||||
if (Build.VERSION.SDK_INT >= 11) { // Honeycomb
|
||||
IMPL = new SearchViewCompatHoneycombImpl();
|
||||
} else {
|
||||
IMPL = new SearchViewCompatStubImpl();
|
||||
}
|
||||
}
|
||||
|
||||
private SearchViewCompat(Context context) {
|
||||
/* Hide constructor */
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SearchView.
|
||||
*
|
||||
* @param context The Context the view is running in.
|
||||
* @return A SearchView instance if the class is present on the current
|
||||
* platform, null otherwise.
|
||||
*/
|
||||
public static View newSearchView(Context context) {
|
||||
return IMPL.newSearchView(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a listener for user actions within the SearchView.
|
||||
*
|
||||
* @param searchView The SearchView in which to register the listener.
|
||||
* @param listener the listener object that receives callbacks when the user performs
|
||||
* actions in the SearchView such as clicking on buttons or typing a query.
|
||||
*/
|
||||
public static void setOnQueryTextListener(View searchView, OnQueryTextListenerCompat listener) {
|
||||
IMPL.setOnQueryTextListener(searchView, listener.mListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callbacks for changes to the query text.
|
||||
*/
|
||||
public static abstract class OnQueryTextListenerCompat {
|
||||
final Object mListener;
|
||||
|
||||
public OnQueryTextListenerCompat() {
|
||||
mListener = IMPL.newOnQueryTextListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user submits the query. This could be due to a key press on the
|
||||
* keyboard or due to pressing a submit button.
|
||||
* The listener can override the standard behavior by returning true
|
||||
* to indicate that it has handled the submit request. Otherwise return false to
|
||||
* let the SearchView handle the submission by launching any associated intent.
|
||||
*
|
||||
* @param query the query text that is to be submitted
|
||||
*
|
||||
* @return true if the query has been handled by the listener, false to let the
|
||||
* SearchView perform the default action.
|
||||
*/
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the query text is changed by the user.
|
||||
*
|
||||
* @param newText the new content of the query text field.
|
||||
*
|
||||
* @return false if the SearchView should perform the default action of showing any
|
||||
* suggestions if available, true if the action was handled by the listener.
|
||||
*/
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 android.support.v4.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.SearchView;
|
||||
import android.widget.SearchView.OnQueryTextListener;
|
||||
|
||||
/**
|
||||
* Implementation of SearchView compatibility that can call Honeycomb APIs.
|
||||
*/
|
||||
class SearchViewCompatHoneycomb {
|
||||
|
||||
interface OnQueryTextListenerCompatBridge {
|
||||
public boolean onQueryTextSubmit(String query);
|
||||
public boolean onQueryTextChange(String newText);
|
||||
}
|
||||
|
||||
public static View newSearchView(Context context) {
|
||||
return new SearchView(context);
|
||||
}
|
||||
|
||||
public static Object newOnQueryTextListener(final OnQueryTextListenerCompatBridge listener) {
|
||||
return new OnQueryTextListener() {
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return listener.onQueryTextSubmit(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
return listener.onQueryTextChange(newText);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void setOnQueryTextListener(Object searchView, Object listener) {
|
||||
((SearchView) searchView).setOnQueryTextListener((OnQueryTextListener) listener);
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.actionbarsherlock.internal.view;
|
||||
|
||||
public interface View_HasStateListenerSupport {
|
||||
void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener);
|
||||
void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener);
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.actionbarsherlock.internal.view;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
public interface View_OnAttachStateChangeListener {
|
||||
void onViewAttachedToWindow(View v);
|
||||
void onViewDetachedFromWindow(View v);
|
||||
}
|
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.actionbarsherlock.internal.view.menu;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.support.v4.view.Menu;
|
||||
import android.support.v4.view.MenuItem;
|
||||
import android.support.v4.view.SubMenu;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class ActionMenu implements Menu {
|
||||
private Context mContext;
|
||||
|
||||
private boolean mIsQwerty;
|
||||
|
||||
private ArrayList<ActionMenuItem> mItems;
|
||||
|
||||
public ActionMenu(Context context) {
|
||||
mContext = context;
|
||||
mItems = new ArrayList<ActionMenuItem>();
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
public MenuItem add(CharSequence title) {
|
||||
return add(0, 0, 0, title);
|
||||
}
|
||||
|
||||
public MenuItem add(int titleRes) {
|
||||
return add(0, 0, 0, titleRes);
|
||||
}
|
||||
|
||||
public MenuItem add(int groupId, int itemId, int order, int titleRes) {
|
||||
return add(groupId, itemId, order, mContext.getResources().getString(titleRes));
|
||||
}
|
||||
|
||||
public MenuItem add(int groupId, int itemId, int order, CharSequence title) {
|
||||
ActionMenuItem item = new ActionMenuItem(getContext(),
|
||||
groupId, itemId, 0, order, title);
|
||||
mItems.add(order, item);
|
||||
return item;
|
||||
}
|
||||
|
||||
public int addIntentOptions(int groupId, int itemId, int order,
|
||||
ComponentName caller, Intent[] specifics, Intent intent, int flags,
|
||||
android.view.MenuItem[] outSpecificItems) {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
final List<ResolveInfo> lri =
|
||||
pm.queryIntentActivityOptions(caller, specifics, intent, 0);
|
||||
final int N = lri != null ? lri.size() : 0;
|
||||
|
||||
if ((flags & FLAG_APPEND_TO_GROUP) == 0) {
|
||||
removeGroup(groupId);
|
||||
}
|
||||
|
||||
for (int i=0; i<N; i++) {
|
||||
final ResolveInfo ri = lri.get(i);
|
||||
Intent rintent = new Intent(
|
||||
ri.specificIndex < 0 ? intent : specifics[ri.specificIndex]);
|
||||
rintent.setComponent(new ComponentName(
|
||||
ri.activityInfo.applicationInfo.packageName,
|
||||
ri.activityInfo.name));
|
||||
final MenuItem item = add(groupId, itemId, order, ri.loadLabel(pm))
|
||||
.setIcon(ri.loadIcon(pm))
|
||||
.setIntent(rintent);
|
||||
if (outSpecificItems != null && ri.specificIndex >= 0) {
|
||||
outSpecificItems[ri.specificIndex] = item;
|
||||
}
|
||||
}
|
||||
|
||||
return N;
|
||||
}
|
||||
|
||||
public SubMenu addSubMenu(CharSequence title) {
|
||||
// TODO Implement submenus
|
||||
return null;
|
||||
}
|
||||
|
||||
public SubMenu addSubMenu(int titleRes) {
|
||||
// TODO Implement submenus
|
||||
return null;
|
||||
}
|
||||
|
||||
public SubMenu addSubMenu(int groupId, int itemId, int order,
|
||||
CharSequence title) {
|
||||
// TODO Implement submenus
|
||||
return null;
|
||||
}
|
||||
|
||||
public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) {
|
||||
// TODO Implement submenus
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mItems.clear();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
private int findItemIndex(int id) {
|
||||
final ArrayList<ActionMenuItem> items = mItems;
|
||||
final int itemCount = items.size();
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
if (items.get(i).getItemId() == id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public MenuItem findItem(int id) {
|
||||
return mItems.get(findItemIndex(id));
|
||||
}
|
||||
|
||||
public MenuItem getItem(int index) {
|
||||
return mItems.get(index);
|
||||
}
|
||||
|
||||
public boolean hasVisibleItems() {
|
||||
final ArrayList<ActionMenuItem> items = mItems;
|
||||
final int itemCount = items.size();
|
||||
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
if (items.get(i).isVisible()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private ActionMenuItem findItemWithShortcut(int keyCode, KeyEvent event) {
|
||||
// TODO Make this smarter.
|
||||
final boolean qwerty = mIsQwerty;
|
||||
final ArrayList<ActionMenuItem> items = mItems;
|
||||
final int itemCount = items.size();
|
||||
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
ActionMenuItem item = items.get(i);
|
||||
final char shortcut = qwerty ? item.getAlphabeticShortcut() :
|
||||
item.getNumericShortcut();
|
||||
if (keyCode == shortcut) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isShortcutKey(int keyCode, KeyEvent event) {
|
||||
return findItemWithShortcut(keyCode, event) != null;
|
||||
}
|
||||
|
||||
public boolean performIdentifierAction(int id, int flags) {
|
||||
final int index = findItemIndex(id);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mItems.get(index).invoke();
|
||||
}
|
||||
|
||||
public boolean performShortcut(int keyCode, KeyEvent event, int flags) {
|
||||
ActionMenuItem item = findItemWithShortcut(keyCode, event);
|
||||
if (item == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return item.invoke();
|
||||
}
|
||||
|
||||
public void removeGroup(int groupId) {
|
||||
final ArrayList<ActionMenuItem> items = mItems;
|
||||
int itemCount = items.size();
|
||||
int i = 0;
|
||||
while (i < itemCount) {
|
||||
if (items.get(i).getGroupId() == groupId) {
|
||||
items.remove(i);
|
||||
itemCount--;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeItem(int id) {
|
||||
mItems.remove(findItemIndex(id));
|
||||
}
|
||||
|
||||
public void setGroupCheckable(int group, boolean checkable,
|
||||
boolean exclusive) {
|
||||
final ArrayList<ActionMenuItem> items = mItems;
|
||||
final int itemCount = items.size();
|
||||
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
ActionMenuItem item = items.get(i);
|
||||
if (item.getGroupId() == group) {
|
||||
item.setCheckable(checkable);
|
||||
item.setExclusiveCheckable(exclusive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setGroupEnabled(int group, boolean enabled) {
|
||||
final ArrayList<ActionMenuItem> items = mItems;
|
||||
final int itemCount = items.size();
|
||||
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
ActionMenuItem item = items.get(i);
|
||||
if (item.getGroupId() == group) {
|
||||
item.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setGroupVisible(int group, boolean visible) {
|
||||
final ArrayList<ActionMenuItem> items = mItems;
|
||||
final int itemCount = items.size();
|
||||
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
ActionMenuItem item = items.get(i);
|
||||
if (item.getGroupId() == group) {
|
||||
item.setVisible(visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setQwertyMode(boolean isQwerty) {
|
||||
mIsQwerty = isQwerty;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return mItems.size();
|
||||
}
|
||||
}
|
@ -1,149 +1,245 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.actionbarsherlock.internal.view.menu;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.actionbarsherlock.R;
|
||||
import com.actionbarsherlock.internal.view.View_HasStateListenerSupport;
|
||||
import com.actionbarsherlock.internal.view.View_OnAttachStateChangeListener;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class ActionMenuItemView extends LinearLayout
|
||||
implements MenuView.ItemView, View.OnClickListener, View.OnLongClickListener,
|
||||
ActionMenuView.ActionMenuChildView, View_HasStateListenerSupport {
|
||||
//UNUSED private static final String TAG = "ActionMenuItemView";
|
||||
|
||||
private MenuItemImpl mItemData;
|
||||
private CharSequence mTitle;
|
||||
private MenuBuilder.ItemInvoker mItemInvoker;
|
||||
|
||||
private ImageButton mImageButton;
|
||||
private Button mTextButton;
|
||||
private boolean mAllowTextWithIcon;
|
||||
//UNUSED private boolean mShowTextAllCaps;
|
||||
private boolean mExpandedFormat;
|
||||
|
||||
public class ActionMenuItemView extends RelativeLayout implements MenuView.ItemView, View.OnClickListener {
|
||||
private ImageView mImageButton;
|
||||
private TextView mTextButton;
|
||||
private FrameLayout mCustomView;
|
||||
private MenuItemImpl mMenuItem;
|
||||
private WeakReference<ImageView> mDivider;
|
||||
private final Set<View_OnAttachStateChangeListener> mListeners = new HashSet<View_OnAttachStateChangeListener>();
|
||||
|
||||
public ActionMenuItemView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ActionMenuItemView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.actionButtonStyle);
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setOnClickListener(this);
|
||||
//TODO super(context, attrs, defStyle);
|
||||
super(context, attrs);
|
||||
final Resources res = context.getResources();
|
||||
mAllowTextWithIcon = res.getBoolean(
|
||||
R.bool.abs__config_allowActionMenuItemTextWithIcon);
|
||||
//UNUSED mShowTextAllCaps = res.getBoolean(R.bool.abs__config_actionMenuItemAllCaps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) {
|
||||
mListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
for (View_OnAttachStateChangeListener listener : mListeners) {
|
||||
listener.onViewAttachedToWindow(this);
|
||||
}
|
||||
}
|
||||
|
||||
mImageButton = (ImageView) findViewById(R.id.abs__item_icon);
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
for (View_OnAttachStateChangeListener listener : mListeners) {
|
||||
listener.onViewDetachedFromWindow(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishInflate() {
|
||||
|
||||
mImageButton = (ImageButton) findViewById(R.id.abs__imageButton);
|
||||
mTextButton = (Button) findViewById(R.id.abs__textButton);
|
||||
mImageButton.setOnClickListener(this);
|
||||
mTextButton = (TextView) findViewById(R.id.abs__item_text);
|
||||
mTextButton.setOnClickListener(this);
|
||||
mCustomView = (FrameLayout) findViewById(R.id.abs__item_custom);
|
||||
mCustomView.setOnClickListener(this);
|
||||
mImageButton.setOnLongClickListener(this);
|
||||
setOnClickListener(this);
|
||||
setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
public MenuItemImpl getItemData() {
|
||||
return mItemData;
|
||||
}
|
||||
|
||||
public void initialize(MenuItemImpl itemData, int menuType) {
|
||||
mItemData = itemData;
|
||||
|
||||
setIcon(itemData.getIcon());
|
||||
setTitle(itemData.getTitleForItemView(this)); // Title only takes effect if there is no icon
|
||||
setId(itemData.getItemId());
|
||||
|
||||
setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
|
||||
setEnabled(itemData.isEnabled());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
mImageButton.setEnabled(enabled);
|
||||
mTextButton.setEnabled(enabled);
|
||||
mCustomView.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public void setDivider(ImageView divider) {
|
||||
mDivider = new WeakReference<ImageView>(divider);
|
||||
//Ensure we are not displaying the divider when we are not visible
|
||||
setDividerVisibility(getVisibility());
|
||||
public void onClick(View v) {
|
||||
if (mItemInvoker != null) {
|
||||
mItemInvoker.invokeItem(mItemData);
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
final int visibility = visible ? View.VISIBLE : View.GONE;
|
||||
setDividerVisibility(visibility);
|
||||
setVisibility(visibility);
|
||||
public void setItemInvoker(MenuBuilder.ItemInvoker invoker) {
|
||||
mItemInvoker = invoker;
|
||||
}
|
||||
|
||||
private void setDividerVisibility(int visibility) {
|
||||
if ((mDivider != null) && (mDivider.get() != null)) {
|
||||
mDivider.get().setVisibility(visibility);
|
||||
}
|
||||
public boolean prefersCondensedTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void reloadDisplay() {
|
||||
final boolean hasCustomView = mCustomView.getChildCount() > 0;
|
||||
final boolean hasText = mMenuItem.showsActionItemText() && !"".equals(mTextButton.getText());
|
||||
|
||||
if (hasCustomView) {
|
||||
mCustomView.setVisibility(View.VISIBLE);
|
||||
mImageButton.setVisibility(View.GONE);
|
||||
mTextButton.setVisibility(View.GONE);
|
||||
} else {
|
||||
mCustomView.setVisibility(View.GONE);
|
||||
mImageButton.setVisibility(View.VISIBLE);
|
||||
mTextButton.setVisibility(hasText ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
public void setCheckable(boolean checkable) {
|
||||
// TODO Support checkable action items
|
||||
}
|
||||
|
||||
public void setIcon(Drawable icon) {
|
||||
mImageButton.setImageDrawable(icon);
|
||||
public void setChecked(boolean checked) {
|
||||
// TODO Support checkable action items
|
||||
}
|
||||
|
||||
public void setTitle(CharSequence title) {
|
||||
mTextButton.setText(title);
|
||||
reloadDisplay();
|
||||
public void setExpandedFormat(boolean expandedFormat) {
|
||||
if (mExpandedFormat != expandedFormat) {
|
||||
mExpandedFormat = expandedFormat;
|
||||
if (mItemData != null) {
|
||||
mItemData.actionFormatChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(MenuItemImpl itemData, int menuType) {
|
||||
mMenuItem = itemData;
|
||||
setId(itemData.getItemId());
|
||||
setIcon(itemData.getIcon());
|
||||
setTitle(itemData.getTitle());
|
||||
setEnabled(itemData.isEnabled());
|
||||
setActionView(itemData.getActionView());
|
||||
setVisible(itemData.isVisible());
|
||||
}
|
||||
private void updateTextButtonVisibility() {
|
||||
boolean visible = !TextUtils.isEmpty(mTextButton.getText());
|
||||
visible &= mImageButton.getDrawable() == null ||
|
||||
(mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat));
|
||||
|
||||
@Override
|
||||
public MenuItemImpl getItemData() {
|
||||
return mMenuItem;
|
||||
mTextButton.setVisibility(visible ? VISIBLE : GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCheckable(boolean checkable) {
|
||||
// No-op
|
||||
public void setIcon(Drawable icon) {
|
||||
mImageButton.setImageDrawable(icon);
|
||||
if (icon != null) {
|
||||
mImageButton.setVisibility(VISIBLE);
|
||||
} else {
|
||||
mImageButton.setVisibility(GONE);
|
||||
}
|
||||
|
||||
updateTextButtonVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(boolean checked) {
|
||||
// No-op
|
||||
public boolean hasText() {
|
||||
return mTextButton.getVisibility() != GONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShortcut(boolean showShortcut, char shortcutKey) {
|
||||
// No-op
|
||||
// Action buttons don't show text for shortcut keys.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActionView(View actionView) {
|
||||
mCustomView.removeAllViews();
|
||||
if (actionView != null) {
|
||||
mCustomView.addView(actionView);
|
||||
}
|
||||
reloadDisplay();
|
||||
}
|
||||
public void setTitle(CharSequence title) {
|
||||
mTitle = title;
|
||||
|
||||
@Override
|
||||
public boolean prefersCondensedTitle() {
|
||||
return true;
|
||||
mTextButton.setText(mTitle);
|
||||
|
||||
setContentDescription(mTitle);
|
||||
updateTextButtonVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showsIcon() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean needsDividerBefore() {
|
||||
return hasText() && mItemData.getIcon() == null;
|
||||
}
|
||||
|
||||
public boolean needsDividerAfter() {
|
||||
return hasText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mMenuItem != null) {
|
||||
mMenuItem.invoke();
|
||||
public boolean onLongClick(View v) {
|
||||
if (hasText()) {
|
||||
// Don't show the cheat sheet for items that already show text.
|
||||
return false;
|
||||
}
|
||||
|
||||
final int[] screenPos = new int[2];
|
||||
final Rect displayFrame = new Rect();
|
||||
getLocationOnScreen(screenPos);
|
||||
getWindowVisibleDisplayFrame(displayFrame);
|
||||
|
||||
final Context context = getContext();
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
final int midy = screenPos[1] + height / 2;
|
||||
final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
|
||||
|
||||
Toast cheatSheet = Toast.makeText(context, mItemData.getTitle(), Toast.LENGTH_SHORT);
|
||||
if (midy < displayFrame.height()) {
|
||||
// Show along the top; follow action buttons
|
||||
cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT,
|
||||
screenWidth - screenPos[0] - width / 2, height);
|
||||
} else {
|
||||
// Show along the bottom center
|
||||
cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
|
||||
}
|
||||
cheatSheet.show();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,448 @@
|
||||
/*
|
||||
* 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.actionbarsherlock.internal.view.menu;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.view.MenuItem;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.View;
|
||||
import android.view.View.MeasureSpec;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.actionbarsherlock.R;
|
||||
|
||||
/**
|
||||
* MenuPresenter for building action menus as seen in the action bar and action modes.
|
||||
*/
|
||||
public class ActionMenuPresenter extends BaseMenuPresenter {
|
||||
//UNUSED private static final String TAG = "ActionMenuPresenter";
|
||||
|
||||
private int mWidthLimit;
|
||||
private int mActionItemWidthLimit;
|
||||
private int mMaxItems;
|
||||
private boolean mMaxItemsSet;
|
||||
private boolean mStrictWidthLimit;
|
||||
private boolean mWidthLimitSet;
|
||||
|
||||
private int mMinCellSize;
|
||||
|
||||
private AlertDialog mDialog;
|
||||
|
||||
// Group IDs that have been added as actions - used temporarily, allocated here for reuse.
|
||||
private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray();
|
||||
|
||||
private View mScrapActionButtonView;
|
||||
int mOpenSubMenuId;
|
||||
|
||||
public ActionMenuPresenter(Context context) {
|
||||
super(context, R.layout.abs__action_menu_layout,
|
||||
R.layout.abs__action_menu_item_layout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initForMenu(Context context, MenuBuilder menu) {
|
||||
super.initForMenu(context, menu);
|
||||
|
||||
final Resources res = context.getResources();
|
||||
|
||||
if (!mWidthLimitSet) {
|
||||
mWidthLimit = res.getDisplayMetrics().widthPixels / 2;
|
||||
}
|
||||
|
||||
// Measure for initial configuration
|
||||
if (!mMaxItemsSet) {
|
||||
mMaxItems = res.getInteger(R.integer.abs__max_action_buttons);
|
||||
}
|
||||
|
||||
mActionItemWidthLimit = mWidthLimit;
|
||||
|
||||
mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density);
|
||||
|
||||
// Drop a scrap view as it may no longer reflect the proper context/config.
|
||||
mScrapActionButtonView = null;
|
||||
}
|
||||
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
if (!mMaxItemsSet) {
|
||||
mMaxItems = mContext.getResources().getInteger(
|
||||
R.integer.abs__max_action_buttons);
|
||||
if (mMenu != null) {
|
||||
mMenu.onItemsChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setWidthLimit(int width, boolean strict) {
|
||||
mWidthLimit = width;
|
||||
mStrictWidthLimit = strict;
|
||||
mWidthLimitSet = true;
|
||||
}
|
||||
|
||||
public void setItemLimit(int itemCount) {
|
||||
mMaxItems = itemCount;
|
||||
mMaxItemsSet = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuView getMenuView(ViewGroup root) {
|
||||
MenuView result = super.getMenuView(root);
|
||||
((ActionMenuView) result).setPresenter(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) {
|
||||
View actionView = item.getActionView();
|
||||
if (actionView == null) {
|
||||
if (!(convertView instanceof ActionMenuItemView)) {
|
||||
convertView = null;
|
||||
}
|
||||
actionView = super.getItemView(item, convertView, parent);
|
||||
}
|
||||
actionView.setVisibility(View.VISIBLE);
|
||||
|
||||
final ActionMenuView menuParent = (ActionMenuView) parent;
|
||||
final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
|
||||
if (!menuParent.checkLayoutParams(lp)) {
|
||||
actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
|
||||
}
|
||||
return actionView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) {
|
||||
itemView.initialize(item, 0);
|
||||
|
||||
final ActionMenuView menuView = (ActionMenuView) mMenuView;
|
||||
ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
|
||||
actionItemView.setItemInvoker(menuView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
|
||||
return item.isActionButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filterLeftoverView(ViewGroup parent, int childIndex) {
|
||||
return super.filterLeftoverView(parent, childIndex);
|
||||
}
|
||||
|
||||
public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
|
||||
if (!subMenu.hasVisibleItems()) return false;
|
||||
|
||||
SubMenuBuilder topSubMenu = subMenu;
|
||||
while (topSubMenu.getParentMenu() != mMenu) {
|
||||
topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu();
|
||||
}
|
||||
View anchor = findViewForItem(topSubMenu.getItem());
|
||||
if (anchor == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOpenSubMenuId = subMenu.getItem().getItemId();
|
||||
|
||||
final List<MenuItemImpl> items = subMenu.getVisibleItems();
|
||||
final int itemsSize = items.size();
|
||||
final CharSequence[] itemText = new CharSequence[itemsSize];
|
||||
for (int i = 0; i < itemsSize; i++) {
|
||||
itemText[i] = items.get(i).getTitle();
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext)
|
||||
.setTitle(subMenu.getItem().getTitle())
|
||||
.setIcon(subMenu.getItem().getIcon())
|
||||
.setCancelable(true)
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
mDialog = null;
|
||||
}
|
||||
});
|
||||
|
||||
final boolean isExclusive = ((MenuItemImpl)subMenu.getItem(0)).isExclusiveCheckable();
|
||||
final boolean isCheckable = ((MenuItemImpl)subMenu.getItem(0)).isCheckable();
|
||||
if (isExclusive) {
|
||||
int selected = -1;
|
||||
for (int i = 0; i < itemsSize; i++) {
|
||||
if (items.get(i).isChecked()) {
|
||||
selected = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
builder.setSingleChoiceItems(itemText, selected, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
items.get(which).invoke();
|
||||
//dialog.dismiss();
|
||||
mDialog = null;
|
||||
}
|
||||
});
|
||||
} else if (isCheckable) {
|
||||
boolean[] selected = new boolean[itemsSize];
|
||||
for (int i = 0; i < itemsSize; i++) {
|
||||
selected[i] = items.get(i).isChecked();
|
||||
}
|
||||
builder.setMultiChoiceItems(itemText, selected, new DialogInterface.OnMultiChoiceClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
|
||||
items.get(which).setChecked(isChecked);
|
||||
//dialog.dismiss();
|
||||
mDialog = null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
builder.setItems(itemText, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
items.get(which).invoke();
|
||||
//dialog.dismiss();
|
||||
mDialog = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mDialog = builder.show();
|
||||
super.onSubMenuSelected(subMenu);
|
||||
return true;
|
||||
}
|
||||
|
||||
private View findViewForItem(MenuItem item) {
|
||||
final ViewGroup parent = (ViewGroup) mMenuView;
|
||||
if (parent == null) return null;
|
||||
|
||||
final int count = parent.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = parent.getChildAt(i);
|
||||
if (child instanceof MenuView.ItemView &&
|
||||
((MenuView.ItemView) child).getItemData() == item) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss all popup menus - overflow and submenus.
|
||||
* @return true if popups were dismissed, false otherwise. (This can be because none were open.)
|
||||
*/
|
||||
public boolean dismissPopupMenus() {
|
||||
return hideSubMenus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss all submenu popups.
|
||||
*
|
||||
* @return true if popups were dismissed, false otherwise. (This can be because none were open.)
|
||||
*/
|
||||
public boolean hideSubMenus() {
|
||||
if (mDialog != null) {
|
||||
try {
|
||||
mDialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
//Must have been dismissed or cancelled already
|
||||
}
|
||||
mDialog = null;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean flagActionItems() {
|
||||
final ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
|
||||
final int itemsSize = visibleItems.size();
|
||||
int maxActions = mMaxItems;
|
||||
int widthLimit = mActionItemWidthLimit;
|
||||
final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
|
||||
final ViewGroup parent = (ViewGroup) mMenuView;
|
||||
|
||||
int requiredItems = 0;
|
||||
//int requestedItems = 0;
|
||||
int firstActionWidth = 0;
|
||||
for (int i = 0; i < itemsSize; i++) {
|
||||
MenuItemImpl item = visibleItems.get(i);
|
||||
if (item.requiresActionButton()) {
|
||||
requiredItems++;
|
||||
}/* else if (item.requestsActionButton()) {
|
||||
requestedItems++;
|
||||
}*/
|
||||
}
|
||||
maxActions -= requiredItems;
|
||||
|
||||
final SparseBooleanArray seenGroups = mActionButtonGroups;
|
||||
seenGroups.clear();
|
||||
|
||||
int cellSize = 0;
|
||||
int cellsRemaining = 0;
|
||||
if (mStrictWidthLimit) {
|
||||
cellsRemaining = widthLimit / mMinCellSize;
|
||||
final int cellSizeRemaining = widthLimit % mMinCellSize;
|
||||
cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining;
|
||||
}
|
||||
|
||||
// Flag as many more requested items as will fit.
|
||||
for (int i = 0; i < itemsSize; i++) {
|
||||
MenuItemImpl item = visibleItems.get(i);
|
||||
|
||||
if (item.requiresActionButton()) {
|
||||
View v = getItemView(item, mScrapActionButtonView, parent);
|
||||
if (mScrapActionButtonView == null) {
|
||||
mScrapActionButtonView = v;
|
||||
}
|
||||
if (mStrictWidthLimit) {
|
||||
cellsRemaining -= ActionMenuView.measureChildForCells(v,
|
||||
cellSize, cellsRemaining, querySpec, 0);
|
||||
} else {
|
||||
v.measure(querySpec, querySpec);
|
||||
}
|
||||
final int measuredWidth = v.getMeasuredWidth();
|
||||
widthLimit -= measuredWidth;
|
||||
if (firstActionWidth == 0) {
|
||||
firstActionWidth = measuredWidth;
|
||||
}
|
||||
final int groupId = item.getGroupId();
|
||||
if (groupId != 0) {
|
||||
seenGroups.put(groupId, true);
|
||||
}
|
||||
item.setIsActionButton(true);
|
||||
} else if (item.requestsActionButton()) {
|
||||
// Items in a group with other items that already have an action slot
|
||||
// can break the max actions rule, but not the width limit.
|
||||
final int groupId = item.getGroupId();
|
||||
final boolean inGroup = seenGroups.get(groupId);
|
||||
boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 &&
|
||||
(!mStrictWidthLimit || cellsRemaining > 0);
|
||||
|
||||
if (isAction) {
|
||||
View v = getItemView(item, mScrapActionButtonView, parent);
|
||||
if (mScrapActionButtonView == null) {
|
||||
mScrapActionButtonView = v;
|
||||
}
|
||||
if (mStrictWidthLimit) {
|
||||
final int cells = ActionMenuView.measureChildForCells(v,
|
||||
cellSize, cellsRemaining, querySpec, 0);
|
||||
cellsRemaining -= cells;
|
||||
if (cells == 0) {
|
||||
isAction = false;
|
||||
}
|
||||
} else {
|
||||
v.measure(querySpec, querySpec);
|
||||
}
|
||||
final int measuredWidth = v.getMeasuredWidth();
|
||||
widthLimit -= measuredWidth;
|
||||
if (firstActionWidth == 0) {
|
||||
firstActionWidth = measuredWidth;
|
||||
}
|
||||
|
||||
if (mStrictWidthLimit) {
|
||||
isAction &= widthLimit >= 0;
|
||||
} else {
|
||||
// Did this push the entire first item past the limit?
|
||||
isAction &= widthLimit + firstActionWidth > 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (isAction && groupId != 0) {
|
||||
seenGroups.put(groupId, true);
|
||||
} else if (inGroup) {
|
||||
// We broke the width limit. Demote the whole group, they all overflow now.
|
||||
seenGroups.put(groupId, false);
|
||||
for (int j = 0; j < i; j++) {
|
||||
MenuItemImpl areYouMyGroupie = visibleItems.get(j);
|
||||
if (areYouMyGroupie.getGroupId() == groupId) {
|
||||
// Give back the action slot
|
||||
if (areYouMyGroupie.isActionButton()) maxActions++;
|
||||
areYouMyGroupie.setIsActionButton(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isAction) maxActions--;
|
||||
|
||||
item.setIsActionButton(isAction);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
|
||||
dismissPopupMenus();
|
||||
super.onCloseMenu(menu, allMenusAreClosing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState() {
|
||||
SavedState state = new SavedState();
|
||||
state.openSubMenuId = mOpenSubMenuId;
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Parcelable state) {
|
||||
SavedState saved = (SavedState) state;
|
||||
if (saved.openSubMenuId > 0) {
|
||||
MenuItem item = mMenu.findItem(saved.openSubMenuId);
|
||||
if (item != null) {
|
||||
SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu();
|
||||
onSubMenuSelected(subMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class SavedState implements Parcelable {
|
||||
public int openSubMenuId;
|
||||
|
||||
SavedState() {
|
||||
}
|
||||
|
||||
SavedState(Parcel in) {
|
||||
openSubMenuId = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(openSubMenuId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static final Parcelable.Creator<SavedState> CREATOR
|
||||
= new Parcelable.Creator<SavedState>() {
|
||||
public SavedState createFromParcel(Parcel in) {
|
||||
return new SavedState(in);
|
||||
}
|
||||
|
||||
public SavedState[] newArray(int size) {
|
||||
return new SavedState[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,551 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.actionbarsherlock.internal.view.menu;
|
||||
|
||||
import com.actionbarsherlock.internal.widget.IcsLinearLayout;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class ActionMenuView extends IcsLinearLayout implements MenuBuilder.ItemInvoker, MenuView {
|
||||
//UNUSED private static final String TAG = "ActionMenuView";
|
||||
|
||||
static final int MIN_CELL_SIZE = 56; // dips
|
||||
static final int GENERATED_ITEM_PADDING = 4; // dips
|
||||
|
||||
private MenuBuilder mMenu;
|
||||
|
||||
private boolean mReserveOverflow;
|
||||
private ActionMenuPresenter mPresenter;
|
||||
private boolean mFormatItems;
|
||||
private int mFormatItemsWidth;
|
||||
private int mMinCellSize;
|
||||
private int mGeneratedItemPadding;
|
||||
//UNUSED private int mMeasuredExtraWidth;
|
||||
|
||||
public ActionMenuView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ActionMenuView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setBaselineAligned(false);
|
||||
final float density = context.getResources().getDisplayMetrics().density;
|
||||
mMinCellSize = (int) (MIN_CELL_SIZE * density);
|
||||
mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density);
|
||||
}
|
||||
|
||||
public void setPresenter(ActionMenuPresenter presenter) {
|
||||
mPresenter = presenter;
|
||||
}
|
||||
|
||||
public boolean isExpandedFormat() {
|
||||
return mFormatItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
//TODO figure out a way to call this pre-2.2
|
||||
}
|
||||
mPresenter.updateMenuView(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// If we've been given an exact size to match, apply special formatting during layout.
|
||||
final boolean wasFormatted = mFormatItems;
|
||||
mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
|
||||
|
||||
if (wasFormatted != mFormatItems) {
|
||||
mFormatItemsWidth = 0; // Reset this when switching modes
|
||||
}
|
||||
|
||||
// Special formatting can change whether items can fit as action buttons.
|
||||
// Kick the menu and update presenters when this changes.
|
||||
final int widthSize = MeasureSpec.getMode(widthMeasureSpec);
|
||||
if (mFormatItems && mMenu != null && widthSize != mFormatItemsWidth) {
|
||||
mFormatItemsWidth = widthSize;
|
||||
mMenu.onItemsChanged(true);
|
||||
}
|
||||
|
||||
if (mFormatItems) {
|
||||
onMeasureExactFormat(widthMeasureSpec, heightMeasureSpec);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// We already know the width mode is EXACTLY if we're here.
|
||||
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
final int widthPadding = getPaddingLeft() + getPaddingRight();
|
||||
final int heightPadding = getPaddingTop() + getPaddingBottom();
|
||||
|
||||
widthSize -= widthPadding;
|
||||
|
||||
// Divide the view into cells.
|
||||
final int cellCount = widthSize / mMinCellSize;
|
||||
final int cellSizeRemaining = widthSize % mMinCellSize;
|
||||
|
||||
if (cellCount == 0) {
|
||||
// Give up, nothing fits.
|
||||
setMeasuredDimension(widthSize, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
final int cellSize = mMinCellSize + cellSizeRemaining / cellCount;
|
||||
|
||||
int cellsRemaining = cellCount;
|
||||
int maxChildHeight = 0;
|
||||
int maxCellsUsed = 0;
|
||||
int expandableItemCount = 0;
|
||||
int visibleItemCount = 0;
|
||||
boolean hasOverflow = false;
|
||||
|
||||
// This is used as a bitfield to locate the smallest items present. Assumes childCount < 64.
|
||||
long smallestItemsAt = 0;
|
||||
|
||||
final int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() == GONE) continue;
|
||||
|
||||
final boolean isGeneratedItem = child instanceof ActionMenuItemView;
|
||||
visibleItemCount++;
|
||||
|
||||
if (isGeneratedItem) {
|
||||
// Reset padding for generated menu item views; it may change below
|
||||
// and views are recycled.
|
||||
child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0);
|
||||
}
|
||||
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
lp.expanded = false;
|
||||
lp.extraPixels = 0;
|
||||
lp.cellsUsed = 0;
|
||||
lp.expandable = false;
|
||||
lp.leftMargin = 0;
|
||||
lp.rightMargin = 0;
|
||||
lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText();
|
||||
|
||||
// Overflow always gets 1 cell. No more, no less.
|
||||
final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining;
|
||||
|
||||
final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable,
|
||||
heightMeasureSpec, heightPadding);
|
||||
|
||||
maxCellsUsed = Math.max(maxCellsUsed, cellsUsed);
|
||||
if (lp.expandable) expandableItemCount++;
|
||||
if (lp.isOverflowButton) hasOverflow = true;
|
||||
|
||||
cellsRemaining -= cellsUsed;
|
||||
maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
|
||||
if (cellsUsed == 1) smallestItemsAt |= (1 << i);
|
||||
}
|
||||
|
||||
// When we have overflow and a single expanded (text) item, we want to try centering it
|
||||
// visually in the available space even though overflow consumes some of it.
|
||||
final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2;
|
||||
|
||||
// Divide space for remaining cells if we have items that can expand.
|
||||
// Try distributing whole leftover cells to smaller items first.
|
||||
|
||||
boolean needsExpansion = false;
|
||||
while (expandableItemCount > 0 && cellsRemaining > 0) {
|
||||
int minCells = Integer.MAX_VALUE;
|
||||
long minCellsAt = 0; // Bit locations are indices of relevant child views
|
||||
int minCellsItemCount = 0;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View child = getChildAt(i);
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
|
||||
// Don't try to expand items that shouldn't.
|
||||
if (!lp.expandable) continue;
|
||||
|
||||
// Mark indices of children that can receive an extra cell.
|
||||
if (lp.cellsUsed < minCells) {
|
||||
minCells = lp.cellsUsed;
|
||||
minCellsAt = 1 << i;
|
||||
minCellsItemCount = 1;
|
||||
} else if (lp.cellsUsed == minCells) {
|
||||
minCellsAt |= 1 << i;
|
||||
minCellsItemCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Items that get expanded will always be in the set of smallest items when we're done.
|
||||
smallestItemsAt |= minCellsAt;
|
||||
|
||||
if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop.
|
||||
|
||||
// We have enough cells, all minimum size items will be incremented.
|
||||
minCells++;
|
||||
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View child = getChildAt(i);
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
if ((minCellsAt & (1 << i)) == 0) {
|
||||
// If this item is already at our small item count, mark it for later.
|
||||
if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) {
|
||||
// Add padding to this item such that it centers.
|
||||
child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0);
|
||||
}
|
||||
lp.cellsUsed++;
|
||||
lp.expanded = true;
|
||||
cellsRemaining--;
|
||||
}
|
||||
|
||||
needsExpansion = true;
|
||||
}
|
||||
|
||||
// Divide any space left that wouldn't divide along cell boundaries
|
||||
// evenly among the smallest items
|
||||
|
||||
final boolean singleItem = !hasOverflow && visibleItemCount == 1;
|
||||
if (cellsRemaining > 0 && smallestItemsAt != 0 &&
|
||||
(cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) {
|
||||
float expandCount = Long.bitCount(smallestItemsAt);
|
||||
|
||||
if (!singleItem) {
|
||||
// The items at the far edges may only expand by half in order to pin to either side.
|
||||
if ((smallestItemsAt & 1) != 0) {
|
||||
LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams();
|
||||
if (!lp.preventEdgeOffset) expandCount -= 0.5f;
|
||||
}
|
||||
if ((smallestItemsAt & (1 << (childCount - 1))) != 0) {
|
||||
LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams());
|
||||
if (!lp.preventEdgeOffset) expandCount -= 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
final int extraPixels = expandCount > 0 ?
|
||||
(int) (cellsRemaining * cellSize / expandCount) : 0;
|
||||
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
if ((smallestItemsAt & (1 << i)) == 0) continue;
|
||||
|
||||
final View child = getChildAt(i);
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
if (child instanceof ActionMenuItemView) {
|
||||
// If this is one of our views, expand and measure at the larger size.
|
||||
lp.extraPixels = extraPixels;
|
||||
lp.expanded = true;
|
||||
if (i == 0 && !lp.preventEdgeOffset) {
|
||||
// First item gets part of its new padding pushed out of sight.
|
||||
// The last item will get this implicitly from layout.
|
||||
lp.leftMargin = -extraPixels / 2;
|
||||
}
|
||||
needsExpansion = true;
|
||||
} else if (lp.isOverflowButton) {
|
||||
lp.extraPixels = extraPixels;
|
||||
lp.expanded = true;
|
||||
lp.rightMargin = -extraPixels / 2;
|
||||
needsExpansion = true;
|
||||
} else {
|
||||
// If we don't know what it is, give it some margins instead
|
||||
// and let it center within its space. We still want to pin
|
||||
// against the edges.
|
||||
if (i != 0) {
|
||||
lp.leftMargin = extraPixels / 2;
|
||||
}
|
||||
if (i != childCount - 1) {
|
||||
lp.rightMargin = extraPixels / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cellsRemaining = 0;
|
||||
}
|
||||
|
||||
// Remeasure any items that have had extra space allocated to them.
|
||||
if (needsExpansion) {
|
||||
int heightSpec = MeasureSpec.makeMeasureSpec(heightSize - heightPadding, heightMode);
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View child = getChildAt(i);
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
|
||||
if (!lp.expanded) continue;
|
||||
|
||||
final int width = lp.cellsUsed * cellSize + lp.extraPixels;
|
||||
child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), heightSpec);
|
||||
}
|
||||
}
|
||||
|
||||
if (heightMode != MeasureSpec.EXACTLY) {
|
||||
heightSize = maxChildHeight;
|
||||
}
|
||||
|
||||
setMeasuredDimension(widthSize, heightSize);
|
||||
//UNUSED mMeasuredExtraWidth = cellsRemaining * cellSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Measure a child view to fit within cell-based formatting. The child's width
|
||||
* will be measured to a whole multiple of cellSize.
|
||||
*
|
||||
* <p>Sets the expandable and cellsUsed fields of LayoutParams.
|
||||
*
|
||||
* @param child Child to measure
|
||||
* @param cellSize Size of one cell
|
||||
* @param cellsRemaining Number of cells remaining that this view can expand to fill
|
||||
* @param parentHeightMeasureSpec MeasureSpec used by the parent view
|
||||
* @param parentHeightPadding Padding present in the parent view
|
||||
* @return Number of cells this child was measured to occupy
|
||||
*/
|
||||
static int measureChildForCells(View child, int cellSize, int cellsRemaining,
|
||||
int parentHeightMeasureSpec, int parentHeightPadding) {
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
|
||||
final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) -
|
||||
parentHeightPadding;
|
||||
final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec);
|
||||
final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode);
|
||||
|
||||
int cellsUsed = 0;
|
||||
if (cellsRemaining > 0) {
|
||||
final int childWidthSpec = MeasureSpec.makeMeasureSpec(
|
||||
cellSize * cellsRemaining, MeasureSpec.AT_MOST);
|
||||
child.measure(childWidthSpec, childHeightSpec);
|
||||
|
||||
final int measuredWidth = child.getMeasuredWidth();
|
||||
cellsUsed = measuredWidth / cellSize;
|
||||
if (measuredWidth % cellSize != 0) cellsUsed++;
|
||||
}
|
||||
|
||||
final ActionMenuItemView itemView = child instanceof ActionMenuItemView ?
|
||||
(ActionMenuItemView) child : null;
|
||||
final boolean expandable = !lp.isOverflowButton && itemView != null && itemView.hasText();
|
||||
lp.expandable = expandable;
|
||||
|
||||
lp.cellsUsed = cellsUsed;
|
||||
final int targetWidth = cellsUsed * cellSize;
|
||||
child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY),
|
||||
childHeightSpec);
|
||||
return cellsUsed;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
if (!mFormatItems) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
return;
|
||||
}
|
||||
|
||||
final int childCount = getChildCount();
|
||||
final int midVertical = (top + bottom) / 2;
|
||||
final int dividerWidth = getDividerWidth();
|
||||
int overflowWidth = 0;
|
||||
//UNUSED int nonOverflowWidth = 0;
|
||||
int nonOverflowCount = 0;
|
||||
int widthRemaining = right - left - getPaddingRight() - getPaddingLeft();
|
||||
boolean hasOverflow = false;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View v = getChildAt(i);
|
||||
if (v.getVisibility() == GONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LayoutParams p = (LayoutParams) v.getLayoutParams();
|
||||
if (p.isOverflowButton) {
|
||||
overflowWidth = v.getMeasuredWidth();
|
||||
if (hasDividerBeforeChildAt(i)) {
|
||||
overflowWidth += dividerWidth;
|
||||
}
|
||||
|
||||
int height = v.getMeasuredHeight();
|
||||
int r = getWidth() - getPaddingRight() - p.rightMargin;
|
||||
int l = r - overflowWidth;
|
||||
int t = midVertical - (height / 2);
|
||||
int b = t + height;
|
||||
v.layout(l, t, r, b);
|
||||
|
||||
widthRemaining -= overflowWidth;
|
||||
hasOverflow = true;
|
||||
} else {
|
||||
final int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin;
|
||||
//UNUSED nonOverflowWidth += size;
|
||||
widthRemaining -= size;
|
||||
if (hasDividerBeforeChildAt(i)) {
|
||||
//UNUSED nonOverflowWidth += dividerWidth;
|
||||
}
|
||||
nonOverflowCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (childCount == 1 && !hasOverflow) {
|
||||
// Center a single child
|
||||
final View v = getChildAt(0);
|
||||
final int width = v.getMeasuredWidth();
|
||||
final int height = v.getMeasuredHeight();
|
||||
final int midHorizontal = (right - left) / 2;
|
||||
final int l = midHorizontal - width / 2;
|
||||
final int t = midVertical - height / 2;
|
||||
v.layout(l, t, l + width, t + height);
|
||||
return;
|
||||
}
|
||||
|
||||
final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1);
|
||||
final int spacerSize = Math.max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0);
|
||||
|
||||
int startLeft = getPaddingLeft();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
final View v = getChildAt(i);
|
||||
final LayoutParams lp = (LayoutParams) v.getLayoutParams();
|
||||
if (v.getVisibility() == GONE || lp.isOverflowButton) {
|
||||
continue;
|
||||
}
|
||||
|
||||
startLeft += lp.leftMargin;
|
||||
int width = v.getMeasuredWidth();
|
||||
int height = v.getMeasuredHeight();
|
||||
int t = midVertical - height / 2;
|
||||
v.layout(startLeft, t, startLeft + width, t + height);
|
||||
startLeft += width + lp.rightMargin + spacerSize;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mPresenter.dismissPopupMenus();
|
||||
}
|
||||
|
||||
public boolean isOverflowReserved() {
|
||||
return mReserveOverflow;
|
||||
}
|
||||
|
||||
public void setOverflowReserved(boolean reserveOverflow) {
|
||||
mReserveOverflow = reserveOverflow;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutParams generateDefaultLayoutParams() {
|
||||
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
|
||||
LayoutParams.WRAP_CONTENT);
|
||||
params.gravity = Gravity.CENTER_VERTICAL;
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutParams generateLayoutParams(AttributeSet attrs) {
|
||||
return new LayoutParams(getContext(), attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
|
||||
if (p instanceof LayoutParams) {
|
||||
LayoutParams result = new LayoutParams((LayoutParams) p);
|
||||
if (result.gravity <= Gravity.NO_GRAVITY) {
|
||||
result.gravity = Gravity.CENTER_VERTICAL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return generateDefaultLayoutParams();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
|
||||
return p != null && p instanceof LayoutParams;
|
||||
}
|
||||
|
||||
public LayoutParams generateOverflowButtonLayoutParams() {
|
||||
LayoutParams result = generateDefaultLayoutParams();
|
||||
result.isOverflowButton = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean invokeItem(MenuItemImpl item) {
|
||||
return mMenu.performItemAction(item, 0);
|
||||
}
|
||||
|
||||
public int getWindowAnimations() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void initialize(MenuBuilder menu) {
|
||||
mMenu = menu;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasDividerBeforeChildAt(int childIndex) {
|
||||
final View childBefore = getChildAt(childIndex - 1);
|
||||
final View child = getChildAt(childIndex);
|
||||
boolean result = false;
|
||||
if (childIndex < getChildCount() && childBefore instanceof ActionMenuChildView) {
|
||||
result |= ((ActionMenuChildView) childBefore).needsDividerAfter();
|
||||
}
|
||||
if (childIndex > 0 && child instanceof ActionMenuChildView) {
|
||||
result |= ((ActionMenuChildView) child).needsDividerBefore();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public interface ActionMenuChildView {
|
||||
public boolean needsDividerBefore();
|
||||
public boolean needsDividerAfter();
|
||||
}
|
||||
|
||||
public static class LayoutParams extends IcsLinearLayout.LayoutParams {
|
||||
public boolean isOverflowButton;
|
||||
public int cellsUsed;
|
||||
public int extraPixels;
|
||||
public boolean expandable;
|
||||
public boolean preventEdgeOffset;
|
||||
|
||||
public boolean expanded;
|
||||
|
||||
public LayoutParams(Context c, AttributeSet attrs) {
|
||||
super(c, attrs);
|
||||
}
|
||||
|
||||
public LayoutParams(LayoutParams other) {
|
||||
super((IcsLinearLayout.LayoutParams) other);
|
||||
isOverflowButton = other.isOverflowButton;
|
||||
}
|
||||
|
||||
public LayoutParams(int width, int height) {
|
||||
super(width, height);
|
||||
isOverflowButton = false;
|
||||
}
|
||||
|
||||
public LayoutParams(int width, int height, boolean isOverflowButton) {
|
||||
super(width, height);
|
||||
this.isOverflowButton = isOverflowButton;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* 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.actionbarsherlock.internal.view.menu;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Base class for MenuPresenters that have a consistent container view and item
|
||||
* views. Behaves similarly to an AdapterView in that existing item views will
|
||||
* be reused if possible when items change.
|
||||
*/
|
||||
public abstract class BaseMenuPresenter implements MenuPresenter {
|
||||
protected Context mSystemContext;
|
||||
protected Context mContext;
|
||||
protected MenuBuilder mMenu;
|
||||
protected LayoutInflater mSystemInflater;
|
||||
protected LayoutInflater mInflater;
|
||||
private Callback mCallback;
|
||||
|
||||
private int mMenuLayoutRes;
|
||||
private int mItemLayoutRes;
|
||||
|
||||
protected MenuView mMenuView;
|
||||
|
||||
private int mId;
|
||||
|
||||
/**
|
||||
* Construct a new BaseMenuPresenter.
|
||||
*
|
||||
* @param context Context for generating system-supplied views
|
||||
* @param menuLayoutRes Layout resource ID for the menu container view
|
||||
* @param itemLayoutRes Layout resource ID for a single item view
|
||||
*/
|
||||
public BaseMenuPresenter(Context context, int menuLayoutRes, int itemLayoutRes) {
|
||||
mSystemContext = context;
|
||||
mSystemInflater = LayoutInflater.from(context);
|
||||
mMenuLayoutRes = menuLayoutRes;
|
||||
mItemLayoutRes = itemLayoutRes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initForMenu(Context context, MenuBuilder menu) {
|
||||
mContext = context;
|
||||
mInflater = LayoutInflater.from(mContext);
|
||||
mMenu = menu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuView getMenuView(ViewGroup root) {
|
||||
if (mMenuView == null) {
|
||||
mMenuView = (MenuView) mSystemInflater.inflate(mMenuLayoutRes, root, false);
|
||||
mMenuView.initialize(mMenu);
|
||||
updateMenuView(true);
|
||||
}
|
||||
|
||||
return mMenuView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reuses item views when it can
|
||||
*/
|
||||
public void updateMenuView(boolean cleared) {
|
||||
final ViewGroup parent = (ViewGroup) mMenuView;
|
||||
if (parent == null) return;
|
||||
|
||||
int childIndex = 0;
|
||||
if (mMenu != null) {
|
||||
mMenu.flagActionItems();
|
||||
ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
|
||||
final int itemCount = visibleItems.size();
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
MenuItemImpl item = visibleItems.get(i);
|
||||
if (shouldIncludeItem(childIndex, item)) {
|
||||
final View convertView = parent.getChildAt(childIndex);
|
||||
final View itemView = getItemView(item, convertView, parent);
|
||||
if (itemView != convertView) {
|
||||
addItemView(itemView, childIndex);
|
||||
}
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove leftover views.
|
||||
while (childIndex < parent.getChildCount()) {
|
||||
if (!filterLeftoverView(parent, childIndex)) {
|
||||
childIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item view at the given index.
|
||||
*
|
||||
* @param itemView View to add
|
||||
* @param childIndex Index within the parent to insert at
|
||||
*/
|
||||
protected void addItemView(View itemView, int childIndex) {
|
||||
final ViewGroup currentParent = (ViewGroup) itemView.getParent();
|
||||
if (currentParent != null) {
|
||||
currentParent.removeView(itemView);
|
||||
}
|
||||
((ViewGroup) mMenuView).addView(itemView, childIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the child view at index and remove it if appropriate.
|
||||
* @param parent Parent to filter from
|
||||
* @param childIndex Index to filter
|
||||
* @return true if the child view at index was removed
|
||||
*/
|
||||
protected boolean filterLeftoverView(ViewGroup parent, int childIndex) {
|
||||
parent.removeViewAt(childIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setCallback(Callback cb) {
|
||||
mCallback = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new item view that can be re-bound to other item data later.
|
||||
*
|
||||
* @return The new item view
|
||||
*/
|
||||
public MenuView.ItemView createItemView(ViewGroup parent) {
|
||||
return (MenuView.ItemView) mSystemInflater.inflate(mItemLayoutRes, parent, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare an item view for use. See AdapterView for the basic idea at work here.
|
||||
* This may require creating a new item view, but well-behaved implementations will
|
||||
* re-use the view passed as convertView if present. The returned view will be populated
|
||||
* with data from the item parameter.
|
||||
*
|
||||
* @param item Item to present
|
||||
* @param convertView Existing view to reuse
|
||||
* @param parent Intended parent view - use for inflation.
|
||||
* @return View that presents the requested menu item
|
||||
*/
|
||||
public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) {
|
||||
MenuView.ItemView itemView;
|
||||
if (convertView instanceof MenuView.ItemView) {
|
||||
itemView = (MenuView.ItemView) convertView;
|
||||
} else {
|
||||
itemView = createItemView(parent);
|
||||
}
|
||||
bindItemView(item, itemView);
|
||||
return (View) itemView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind item data to an existing item view.
|
||||
*
|
||||
* @param item Item to bind
|
||||
* @param itemView View to populate with item data
|
||||
*/
|
||||
public abstract void bindItemView(MenuItemImpl item, MenuView.ItemView itemView);
|
||||
|
||||
/**
|
||||
* Filter item by child index and item data.
|
||||
*
|
||||
* @param childIndex Intended presentation index of this item
|
||||
* @param item Item to present
|
||||
* @return true if this item should be included in this menu presentation; false otherwise
|
||||
*/
|
||||
public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
|
||||
if (mCallback != null) {
|
||||
mCallback.onCloseMenu(menu, allMenusAreClosing);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onSubMenuSelected(SubMenuBuilder menu) {
|
||||
if (mCallback != null) {
|
||||
return mCallback.onOpenSubMenu(menu);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean flagActionItems() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
mId = id;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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.actionbarsherlock.internal.view.menu;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Parcelable;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* A MenuPresenter is responsible for building views for a Menu object.
|
||||
* It takes over some responsibility from the old style monolithic MenuBuilder class.
|
||||
*/
|
||||
public interface MenuPresenter {
|
||||
/**
|
||||
* Called by menu implementation to notify another component of open/close events.
|
||||
*/
|
||||
public interface Callback {
|
||||
/**
|
||||
* Called when a menu is closing.
|
||||
* @param menu
|
||||
* @param allMenusAreClosing
|
||||
*/
|
||||
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing);
|
||||
|
||||
/**
|
||||
* Called when a submenu opens. Useful for notifying the application
|
||||
* of menu state so that it does not attempt to hide the action bar
|
||||
* while a submenu is open or similar.
|
||||
*
|
||||
* @param subMenu Submenu currently being opened
|
||||
* @return true if the Callback will handle presenting the submenu, false if
|
||||
* the presenter should attempt to do so.
|
||||
*/
|
||||
public boolean onOpenSubMenu(MenuBuilder subMenu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this presenter for the given context and menu.
|
||||
* This method is called by MenuBuilder when a presenter is
|
||||
* added. See {@link MenuBuilder#addMenuPresenter(MenuPresenter)}
|
||||
*
|
||||
* @param context Context for this presenter; used for view creation and resource management
|
||||
* @param menu Menu to host
|
||||
*/
|
||||
public void initForMenu(Context context, MenuBuilder menu);
|
||||
|
||||
/**
|
||||
* Retrieve a MenuView to display the menu specified in
|
||||
* {@link #initForMenu(Context, Menu)}.
|
||||
*
|
||||
* @param root Intended parent of the MenuView.
|
||||
* @return A freshly created MenuView.
|
||||
*/
|
||||
public MenuView getMenuView(ViewGroup root);
|
||||
|
||||
/**
|
||||
* Update the menu UI in response to a change. Called by
|
||||
* MenuBuilder during the normal course of operation.
|
||||
*
|
||||
* @param cleared true if the menu was entirely cleared
|
||||
*/
|
||||
public void updateMenuView(boolean cleared);
|
||||
|
||||
/**
|
||||
* Set a callback object that will be notified of menu events
|
||||
* related to this specific presentation.
|
||||
* @param cb Callback that will be notified of future events
|
||||
*/
|
||||
public void setCallback(Callback cb);
|
||||
|
||||
/**
|
||||
* Called by Menu implementations to indicate that a submenu item
|
||||
* has been selected. An active Callback should be notified, and
|
||||
* if applicable the presenter should present the submenu.
|
||||
*
|
||||
* @param subMenu SubMenu being opened
|
||||
* @return true if the the event was handled, false otherwise.
|
||||
*/
|
||||
public boolean onSubMenuSelected(SubMenuBuilder subMenu);
|
||||
|
||||
/**
|
||||
* Called by Menu implementations to indicate that a menu or submenu is
|
||||
* closing. Presenter implementations should close the representation
|
||||
* of the menu indicated as necessary and notify a registered callback.
|
||||
*
|
||||
* @param menu Menu or submenu that is closing.
|
||||
* @param allMenusAreClosing True if all associated menus are closing.
|
||||
*/
|
||||
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing);
|
||||
|
||||
/**
|
||||
* Called by Menu implementations to flag items that will be shown as actions.
|
||||
* @return true if this presenter changed the action status of any items.
|
||||
*/
|
||||
public boolean flagActionItems();
|
||||
|
||||
/**
|
||||
* Called when a menu item with a collapsable action view should expand its action view.
|
||||
*
|
||||
* @param menu Menu containing the item to be expanded
|
||||
* @param item Item to be expanded
|
||||
* @return true if this presenter expanded the action view, false otherwise.
|
||||
*/
|
||||
public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item);
|
||||
|
||||
/**
|
||||
* Called when a menu item with a collapsable action view should collapse its action view.
|
||||
*
|
||||
* @param menu Menu containing the item to be collapsed
|
||||
* @param item Item to be collapsed
|
||||
* @return true if this presenter collapsed the action view, false otherwise.
|
||||
*/
|
||||
public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item);
|
||||
|
||||
/**
|
||||
* Returns an ID for determining how to save/restore instance state.
|
||||
* @return a valid ID value.
|
||||
*/
|
||||
public int getId();
|
||||
|
||||
/**
|
||||
* Returns a Parcelable describing the current state of the presenter.
|
||||
* It will be passed to the {@link #onRestoreInstanceState(Parcelable)}
|
||||
* method of the presenter sharing the same ID later.
|
||||
* @return The saved instance state
|
||||
*/
|
||||
public Parcelable onSaveInstanceState();
|
||||
|
||||
/**
|
||||
* Supplies the previously saved instance state to be restored.
|
||||
* @param state The previously saved instance state
|
||||
*/
|
||||
public void onRestoreInstanceState(Parcelable state);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue