操作栏:老版本Android的最佳实践

15

我希望在我的应用程序顶部有一个菜单栏——就像Facebook、Google+或Twitter一样:

这是Twitter应用程序的屏幕截图,显示了该栏:它在每个活动中显示,在左侧有公司标志(可点击),右侧有1-3个菜单项(可点击图片)。

enter image description here

它也可以在GDCatalog应用程序中看到:

enter image description here

因此,对于该操作栏,有几个要求:

  • 它必须在较旧的Android平台上运行,例如API级别8。
  • 它必须在每个活动中都可用,而不必一次又一次地重复代码。
  • 它必须适应屏幕大小,以使其占据整个宽度。

如何最佳实践地实现这样的操作栏?

GreenDroid将其做成了这样(使用合并):

<?xml version="1.0" encoding="utf-8"?>

<!--
/*
** Copyright (C) 2010 Cyril Mottier (http://www.cyrilmottier.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.
*/
-->

<merge
    xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageButton
        xmlns:android="http://schemas.android.com/apk/res/android"
        style="?attr/gdActionBarItemStyle"
        android:id="@+id/gd_action_bar_item"
        android:layout_height="fill_parent"
        android:scaleType="center" />

    <ImageView
        android:layout_width="?attr/gdActionBarDividerWidth"
        android:layout_height="fill_parent"
        android:background="?attr/gdActionBarDividerDrawable" />

    <TextView
        style="?attr/gdActionBarTitleStyle"
        android:id="@+id/gd_action_bar_title"
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:layout_weight="1.0"
        android:gravity="left|center_vertical"
        android:singleLine="true"
        android:textColor="?attr/gdActionBarTitleColor"
        android:textSize="16sp"
        android:textStyle="bold"
        android:paddingRight="10dp"
        android:paddingLeft="10dp" />

</merge>
这是一个好的解决方案吗?它也适用于旧平台吗?这里还缺少哪些编码部分?
我知道我们可以在这里找到一些关于操作栏的问题。但尽管如此,我仍然无法找到实现菜单栏在(几乎)所有API级别上工作的最佳且最简单的方法。也许Google的解决方案是最好的?
提前非常感谢!

最好和最简单的是主观的。为什么不试试一些东西,当你有具体问题时再回来。 - Cheryl Simon
1
“最佳实践”从来不是主观的,它总是多个开发者中表现出来的最佳解决方案。如果我询问每个开发者他或她的首选解决方案,我们就可以看到什么是最佳解决方案。当然,我不想知道某个人喜欢哪个解决方案,我们都想知道原因和论据。我有一个具体的问题:我不知道该如何实现那个操作栏。;) - caw
5个回答

14

你可能想要查看 ActionBarSherlock。源代码可以在 这里 找到。它将为您提供如何使用片段的思路,让您对如何继续有一些了解。

Google创建了一个android兼容库,用于在低版本(如1.5及以上)上使用他们为Honeycomb创建的某些新API。它可以在android sdk文件夹中找到,例如E:\Program Files\Android\android-sdk-windows\android-compatibility\v4\android-support-v4.jar。如果您没有此jar文件,您需要使用avd管理器下载它。


谢谢您的建议!不幸的是,为了启用ActionBarSherlock,您必须声明所有活动都扩展FragmentActivity。但我的活动已经扩展了ListActivity。由于我无法扩展两个类,所以我不能使用它,对吧? - caw
有一个列表片段可以实现这个功能。你可能需要学习一些关于片段的教程。这是在Honeycomb中引入的新概念。 - blessanm86
好的,感谢您提供这个附加信息。但是Fragment只有在API级别11及以上才可用,不是吗?我如何在Android 2.2或2.3上使用它? - caw
1
要使用ActionBarSherlock,您需要将所有的ListActivity更改为包含ListFragments的FragmentActivity。从长远来看,这可能是件好事,因为它会使您在平板设备上为应用程序制作布局变得更加容易。ActionBarSherlock包括整个Android兼容库以及ActionBar功能,这意味着您可以在任何版本的Android上使用Fragments和Loaders,甚至是1.6(API版本4)的旧版本。这非常棒。 - LouieGeetoo
非常感谢您的评论,LouieGeetoo。我该如何声明我的活动以扩展包含ListFragment的FragmentActivity? - caw
我也要试一下。 - gumuruh

2
我所做的是添加了一个名为titlebar.xml的xml布局文件,大致如下:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" style="@style/FullWidth">
    <RelativeLayout style="@style/FullWidth">
        <ImageView style="@style/WrapContent" android:src="@drawable/mylogo" android:layout_centerVertical="true" android:id="@+id/imageViewIcon" />
        <TextView style="@style/Title" android:layout_toRightOf="@+id/imageViewIcon" android:layout_toLeftOf="@+id/buttonSomeButton" android:id="@+id/textViewAppName"  android:text="@string/appName"/>
        <TextView style="@style/SubTitle" android:text="@string/empty" android:layout_marginLeft="3dip" android:layout_toRightOf="@+id/imageViewIcon" android:layout_toLeftOf="@+id/buttonSomeButton" android:layout_below="@+id/textViewAppName" android:id="@+id/textViewSubtitle" />
        <Button style="@style/NormalButton" android:id="@+id/buttonSomeButton" android:drawableRight="@drawable/button_image" android:layout_centerVertical="true" android:layout_alignParentTop="true" android:layout_alignParentRight="true" />
    </RelativeLayout>
</merge>

然后我创建了一个扩展LinearLayout的控件,称为TitleBar.java,它看起来像这样:

package com.sample.ui;

public class TitleBar extends LinearLayout {
    public TitleBar(Context context, AttributeSet attrs) {
        super(context, attrs);    
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.titlebar, this);
    }
}

你可以在这个类中连接所有按钮。如果需要有自定义的按钮处理器,你可以在该类中创建设置方法。它将所有内容都保持在一个单一的控件之内。
要在任何想包含此标题栏的XML文件中使用它,可以这样做:
<com.sample.ui.TitleBar style="@style/FullWidth" />

这对我的需求很好,且与2.1及以上版本兼容。我尚未在低于2.1的版本进行测试,但我不认为它不能在早期版本上运行。


非常感谢 :) 您的布局 XML 文件是否包括 RelativeLayout,而您的 TitleBar.java 扩展 LinearLayout 是否正确? FullWidth 样式文件中有什么内容? - caw
实际上,我的Titlebar布局使用的是RelativeLayout,但它可以使用任何布局。这只是在我的情况下很方便,因为我想要一个带有标题和子标题的图像,所有内容都对齐。至于样式,实际上我只是使用了一个快捷方式:<style name="FullWidth"> <item name="android:layout_height">wrap_content</item> <item name="android:layout_width">fill_parent</item> </style> 我还有类似的FillParent和WrapContent样式。这些是我经常使用并且厌倦了一遍又一遍输入的三种基本样式。它们是我其他许多样式的父级。 - brianestey

2

谷歌在最新的Android Support Library(18)中增加了对旧版Android中ActionBars的支持。您需要使用ActionBarActivity并包含android.support.v7.appcompat支持库。它提供了API 7(2.1)的支持。


谢谢!你有什么理由从ActionBarSherlock切换到这个新的支持库吗? - caw
ActionBarSherlock在支持库的ActionBar之外还具有额外的功能。ActionBar由Google支持。此时此刻,如果你有一个可用的东西,为什么要去换呢。 - Dorrin

2

我个人偏好使用AndroidBarSherlock。它是一个优秀的包,性能非常好。如果你想避免使用fragments,你也可以使用Android-ActionBar。唯一需要注意的是,你需要将actionbar添加到每个布局中。


非常感谢!这个库也非常有趣和有用。 - caw

1
创建一个 XML 布局文件,例如“top_bar.xml”,包含在每个活动的布局中? 因此,每个活动的布局文件中都需要一个线性布局(垂直方向)作为父级,然后添加以下内容:
<include layout="@layout/custom_action_bar" android:id="@+id/action_bar" />

然后,您需要在这些活动的源文件中为自定义操作栏中的所有项目添加onclick监听器。

而“custom_action_bar.xml”布局文件可能如下所示:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/APP_ICON" />
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ff0000" android:text="APP_TITLE">
</merge>

这不是一个简单的解决方案,但可能适用于所有 Android 平台版本,对吧?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接