新的Google Now和Google+卡片界面

60

Google Now和Google+(Android)都采用类似卡片的界面。

输入图像描述

我在想是否有人知道如何在Android上复制这种界面。

它们都有非常有趣的动画来展示新的卡片;任何想法都很棒。


1
只是想澄清一下 - 我更关心卡片视图的外观和感觉。基本上,我需要它像ListView一样运行,即我可以动态地用卡片填充屏幕,但我希望列表的每一行看起来像一张卡片。如果有其他布局可供调整,那就太好了。 - HBG
在观看了YouTube上的视频后,我认为这类似于一个带有两个视图的列表视图,一个用于关闭的卡片,另一个用于打开的卡片。还有两个视图之间的动画... 我认为我们不需要重新发明所有API来获得类似的结果。 - pommedeterresautee
6个回答

53

我已经发布了一个教程,介绍如何复制/创建 Google Cards 风格的布局,在这里可以找到。

关键步骤:

  1. 创建自定义布局
  2. 为绘制子元素添加观察者
  3. 交替卡片动画

以下是代码片段:

@Override
public void onGlobalLayout() {
    getViewTreeObserver().removeGlobalOnLayoutListener(this);

    final int heightPx = getContext().getResources().getDisplayMetrics().heightPixels;

    boolean inversed = false;
    final int childCount = getChildCount();

    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);

        int[] location = new int[2];

        child.getLocationOnScreen(location);

        if (location[1] > heightPx) {
            break;
        }

        if (!inversed) {
            child.startAnimation(AnimationUtils.loadAnimation(getContext(),
                    R.anim.slide_up_left));
        } else {
            child.startAnimation(AnimationUtils.loadAnimation(getContext(),
                    R.anim.slide_up_right));
        }

        inversed = !inversed;
    }

}

2
不错!认为下面的链接会很有帮助。https://github.com/nadavfima/cardsui-for-android http://nhaarman.github.io/ListViewAnimations/ - AnhSirk Dasarp
@Sharddul 我需要动态地将视图放入 <com.shardul.nowlayout.NowLayout> </---> 中,而不是教程中的那些TextView。如何实现?我尝试使用addView(view),但是:( - AnhSirk Dasarp
你能为slide_up_right附加动画代码吗? - Zen

21

请查看http://ryanharter.com/blog/2013/01/31/how-to-make-an-android-card-list/

示例副本:

/res/drawable/bg_card.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle"
            android:dither="true">

            <corners android:radius="2dp"/>

            <solid android:color="#ccc" />

        </shape>
    </item>

    <item android:bottom="2dp">
        <shape android:shape="rectangle"
            android:dither="true">

            <corners android:radius="2dp" />

            <solid android:color="@android:color/white" />

            <padding android:bottom="8dp"
                android:left="8dp"
                android:right="8dp"
                android:top="8dp" />
        </shape>
    </item>
</layer-list>

将其用作您布局的背景:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="12dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        android:layout_marginLeft="6dp"
        android:layout_marginRight="6dp"
        android:layout_marginTop="4dp"
        android:layout_marginBottom="4dp"
        android:background="@drawable/bg_card">

        <!-- Card Contents go here -->

    </LinearLayout>

</FrameLayout>

1
你可能需要在第一个矩形项中添加填充字段。 - lalitm
谢谢。示例已修复。 - userM1433372

16

==== 2014年9月29日更新开始 ====

使用来自Google兼容性库的CardView(适用于Android 2.1+):

<!-- A CardView that contains a TextView -->
<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="200dp"
    android:layout_height="200dp"
    card_view:cardCornerRadius="4dp">

    <TextView
        android:id="@+id/info_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.v7.widget.CardView>

请参阅https://developer.android.com/preview/material/ui-widgets.html

==== 更新结束 ====

有(至少)两个选择:

或者

请参阅https://github.com/afollestad/Cards-UI/wiki/2.-Intro-Tutorial以获取简单介绍。 enter image description here


非常棒的工作,我希望它支持 Android 11 之后的所有版本。 - Harshit
Cardslib很棒,但最低SDK版本14对我来说不可行。Cardsui的最低版本也是15,但在我看来它不如Cardslib好。 - frostymarvelous

10

仅出于好奇,使用这种实现方式会使滚动在使用大量数据集的应用程序中变慢,因为它不像ListView那样回收视图吗? - João Melo
也许你应该阅读博客文章,不要错过性能提示部分... 感谢您的评论。 - confucius
喜欢它,但缺乏回收机制让我无法接受。 - frostymarvelous

7
卡片的外观不应该太难。您只需要一个没有分割线的ListView,并且您的ListView项应该有边距。
像这样:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_margin="16dp"
    android:layout_height="wrap_content"
    android:background="@android:color/background_light">

     <TextView
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:paddingTop="16dp"
             android:paddingRight="16dp"
             android:paddingLeft="16dp"
             android:text="Title"
             android:textSize="18dp"
             android:textColor="@android:color/primary_text_holo_light"
             />

     <TextView
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:paddingRight="16dp"
             android:paddingLeft="16dp"
             android:text="Subtitle"
             android:textSize="14dp"
             android:textColor="@android:color/primary_text_holo_light"
             />

     <ImageView android:layout_marginTop="16dp" 
              android:layout_marginBottom="16dp" 
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:background="@drawable/background"/> 
</LinearLayout>

2
根据主贴的评论,我认为这更多关于卡片的动画效果以及列表的构建方式,而不是布局内容本身。 - pommedeterresautee
谢谢你的回答。我已经成功复制了外观 - 现在我只想让整体感觉也跟上! - HBG

4
我有相同的需求,并已开始进行调查。我一直在查看apktool输出,这些输出是我从com.google.android.googlequicksearchbox apk获取的(没有源代码只有res xmls)。
这个布局(at_place_card.xml)用于显示位置信息。它有三行文本和两个操作按钮(详细信息和签到)在右侧,左侧有一张图片。
不幸的是,我无法从apk中获取任何样式信息,因此字体大小、尺寸和颜色只是猜测。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:orientation="horizontal" android:background="@drawable/card_background" android:layout_width="fill_parent" android:layout_height="wrap_content"
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:thegoogle="http://schemas.android.com/apk/res/com.google.android.googlequicksearchbox">
    <LinearLayout android:orientation="vertical" android:layout_width="0.0dip" android:layout_height="fill_parent" android:baselineAligned="false" android:layout_weight="1.0">
        <FrameLayout android:layout_width="fill_parent" android:layout_height="wrap_content">
            <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" style="@style/CardTextBlock">
                <TextView android:id="@id/entry_title" android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/CardTitle" />
                <TextView android:id="@id/open_hours" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/CardText" />
                <TextView android:textColor="@color/card_light_text" android:id="@id/known_for_terms" android:paddingBottom="4.0dip" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="4" style="@style/CardText" />
            </LinearLayout>
            <ImageButton android:layout_gravity="top|right|center" android:id="@id/card_menu_button" android:layout_width="@dimen/card_action_button_height" android:layout_height="@dimen/card_action_button_height" android:contentDescription="@string/accessibility_menu_button" style="@style/CardMenuButton" />
        </FrameLayout>
        <Space android:layout_width="fill_parent" android:layout_height="0.0dip" android:layout_weight="1.0" />
        <Button android:id="@id/details_button" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="@dimen/card_action_button_height" android:text="@string/more_details" android:drawableLeft="@drawable/ic_action_pin" style="@style/CardActionButtonWithIcon" />
        <Button android:id="@id/checkin_button" android:layout_width="fill_parent" android:layout_height="@dimen/card_action_button_height" android:text="@string/check_in" android:drawableLeft="@drawable/ic_action_check_in" style="@style/CardActionButtonWithIcon" />
    </LinearLayout>
    <com.google.android.velvet.ui.CrossfadingWebImageView android:id="@id/place_photo" android:visibility="gone" android:layout_width="0.0dip" android:layout_height="fill_parent" android:scaleType="centerCrop" android:adjustViewBounds="true" android:baselineAligned="false" android:minHeight="@dimen/at_place_card_content_height" android:layout_weight="1.0" android:contentDescription="@string/at_place_card_image_desc" thegoogle:crossfadeDuration="@integer/image_crossfade_duration" />
</LinearLayout>

更新:现在我已经获得了一些样式信息。如果您感兴趣,这里有一个包含我目前拥有的一些资源文件的zip文件(从Google Now中提取)。 https://dl.dropbox.com/u/4379928/android/googlenow2.zip

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