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;
|
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.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageButton;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.actionbarsherlock.R;
|
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 final Set<View_OnAttachStateChangeListener> mListeners = new HashSet<View_OnAttachStateChangeListener>();
|
||||||
private ImageView mImageButton;
|
|
||||||
private TextView mTextButton;
|
|
||||||
private FrameLayout mCustomView;
|
|
||||||
private MenuItemImpl mMenuItem;
|
|
||||||
private WeakReference<ImageView> mDivider;
|
|
||||||
|
|
||||||
public ActionMenuItemView(Context context) {
|
public ActionMenuItemView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionMenuItemView(Context context, AttributeSet attrs) {
|
public ActionMenuItemView(Context context, AttributeSet attrs) {
|
||||||
this(context, attrs, R.attr.actionButtonStyle);
|
this(context, attrs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
|
public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
//TODO super(context, attrs, defStyle);
|
||||||
setOnClickListener(this);
|
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
|
@Override
|
||||||
protected void onFinishInflate() {
|
public void addOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) {
|
||||||
super.onFinishInflate();
|
mListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeOnAttachStateChangeListener(View_OnAttachStateChangeListener listener) {
|
||||||
|
mListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
for (View_OnAttachStateChangeListener listener : mListeners) {
|
||||||
|
listener.onViewAttachedToWindow(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
for (View_OnAttachStateChangeListener listener : mListeners) {
|
||||||
|
listener.onViewDetachedFromWindow(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mImageButton = (ImageView) findViewById(R.id.abs__item_icon);
|
@Override
|
||||||
|
public void onFinishInflate() {
|
||||||
|
|
||||||
|
mImageButton = (ImageButton) findViewById(R.id.abs__imageButton);
|
||||||
|
mTextButton = (Button) findViewById(R.id.abs__textButton);
|
||||||
mImageButton.setOnClickListener(this);
|
mImageButton.setOnClickListener(this);
|
||||||
mTextButton = (TextView) findViewById(R.id.abs__item_text);
|
|
||||||
mTextButton.setOnClickListener(this);
|
mTextButton.setOnClickListener(this);
|
||||||
mCustomView = (FrameLayout) findViewById(R.id.abs__item_custom);
|
mImageButton.setOnLongClickListener(this);
|
||||||
mCustomView.setOnClickListener(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) {
|
public void setEnabled(boolean enabled) {
|
||||||
super.setEnabled(enabled);
|
super.setEnabled(enabled);
|
||||||
mImageButton.setEnabled(enabled);
|
mImageButton.setEnabled(enabled);
|
||||||
mTextButton.setEnabled(enabled);
|
mTextButton.setEnabled(enabled);
|
||||||
mCustomView.setEnabled(enabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDivider(ImageView divider) {
|
public void onClick(View v) {
|
||||||
mDivider = new WeakReference<ImageView>(divider);
|
if (mItemInvoker != null) {
|
||||||
//Ensure we are not displaying the divider when we are not visible
|
mItemInvoker.invokeItem(mItemData);
|
||||||
setDividerVisibility(getVisibility());
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVisible(boolean visible) {
|
public void setItemInvoker(MenuBuilder.ItemInvoker invoker) {
|
||||||
final int visibility = visible ? View.VISIBLE : View.GONE;
|
mItemInvoker = invoker;
|
||||||
setDividerVisibility(visibility);
|
|
||||||
setVisibility(visibility);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDividerVisibility(int visibility) {
|
public boolean prefersCondensedTitle() {
|
||||||
if ((mDivider != null) && (mDivider.get() != null)) {
|
return true;
|
||||||
mDivider.get().setVisibility(visibility);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCheckable(boolean checkable) {
|
||||||
|
// TODO Support checkable action items
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reloadDisplay() {
|
public void setChecked(boolean checked) {
|
||||||
final boolean hasCustomView = mCustomView.getChildCount() > 0;
|
// TODO Support checkable action items
|
||||||
final boolean hasText = mMenuItem.showsActionItemText() && !"".equals(mTextButton.getText());
|
}
|
||||||
|
|
||||||
if (hasCustomView) {
|
public void setExpandedFormat(boolean expandedFormat) {
|
||||||
mCustomView.setVisibility(View.VISIBLE);
|
if (mExpandedFormat != expandedFormat) {
|
||||||
mImageButton.setVisibility(View.GONE);
|
mExpandedFormat = expandedFormat;
|
||||||
mTextButton.setVisibility(View.GONE);
|
if (mItemData != null) {
|
||||||
} else {
|
mItemData.actionFormatChanged();
|
||||||
mCustomView.setVisibility(View.GONE);
|
|
||||||
mImageButton.setVisibility(View.VISIBLE);
|
|
||||||
mTextButton.setVisibility(hasText ? View.VISIBLE : View.GONE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIcon(Drawable icon) {
|
|
||||||
mImageButton.setImageDrawable(icon);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTitle(CharSequence title) {
|
private void updateTextButtonVisibility() {
|
||||||
mTextButton.setText(title);
|
boolean visible = !TextUtils.isEmpty(mTextButton.getText());
|
||||||
reloadDisplay();
|
visible &= mImageButton.getDrawable() == null ||
|
||||||
}
|
(mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat));
|
||||||
|
|
||||||
@Override
|
mTextButton.setVisibility(visible ? VISIBLE : GONE);
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setIcon(Drawable icon) {
|
||||||
public MenuItemImpl getItemData() {
|
mImageButton.setImageDrawable(icon);
|
||||||
return mMenuItem;
|
if (icon != null) {
|
||||||
|
mImageButton.setVisibility(VISIBLE);
|
||||||
|
} else {
|
||||||
|
mImageButton.setVisibility(GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
updateTextButtonVisibility();
|
||||||
public void setCheckable(boolean checkable) {
|
|
||||||
// No-op
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public boolean hasText() {
|
||||||
public void setChecked(boolean checked) {
|
return mTextButton.getVisibility() != GONE;
|
||||||
// No-op
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setShortcut(boolean showShortcut, char shortcutKey) {
|
public void setShortcut(boolean showShortcut, char shortcutKey) {
|
||||||
// No-op
|
// Action buttons don't show text for shortcut keys.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void setTitle(CharSequence title) {
|
||||||
public void setActionView(View actionView) {
|
mTitle = title;
|
||||||
mCustomView.removeAllViews();
|
|
||||||
if (actionView != null) {
|
|
||||||
mCustomView.addView(actionView);
|
|
||||||
}
|
|
||||||
reloadDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
mTextButton.setText(mTitle);
|
||||||
public boolean prefersCondensedTitle() {
|
|
||||||
return true;
|
setContentDescription(mTitle);
|
||||||
|
updateTextButtonVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showsIcon() {
|
public boolean showsIcon() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean needsDividerBefore() {
|
||||||
|
return hasText() && mItemData.getIcon() == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean needsDividerAfter() {
|
||||||
|
return hasText();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public boolean onLongClick(View v) {
|
||||||
if (mMenuItem != null) {
|
if (hasText()) {
|
||||||
mMenuItem.invoke();
|
// 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