3

我有兴趣创建一个 ListView,其中每一行都标记为在 GMail 中为 3.0+ 完成的方式。这创建了左右 ListFragment 的良好分离。

其他示例还包括 2.3.4 上的 Google 日历,例如颜色标记位于 ListView 左侧。

GMail 列表视图

查看两个列表之间的灰色垂直分隔线。一个人如何实现这样的目标?一个奖励也是交替宽度,但我想这只是一个较小的布局变化。

我知道我可能会做一些事情,比如在其中插入一个 ImageView,然后用我想要的颜色填充它,但在我看来,这是一个丑陋的 hack。

另一个问题是,如果有一种通用的方式来组合两个 ListView 片段,就像 GMail 或 Mail 应用程序那样。

跨两个片段的 GMail ListView

4

3 回答 3

1

请告诉我我是否正确理解了这个问题......您想将某些行标记为选中,并且选中的行在视觉上看起来是缩进的(具有不同的颜色和边距)?

这里有2个技巧:

1 - 使用 StateListDrawable 作为行背景:

如果是这样,我将创建一个列表行布局文件并将“背景”属性设置为 StateListDrawable(可以是 XML)。这将允许该行切换选定和未选定的视觉状态。

StateListDrawable 的“drawable”属性将是一个 9-patch PNG,一个用于未选择状态,不包括边距,一个用于选定状态...选定的一个将在 PNG 本身内定义一个边距,通过指定内容区域/底部黑线不完全延伸到 PNG 的左侧,留下一个区域,即您的未缩放边距。

为了方便人们发现这一点,Radley Marx 刚刚在 9 补丁上发布了一篇出色的帖子:http ://radleymarx.com/blog/simple-guide-to-9-patch/

对于 ListViews,有时您想要关闭“listSelector”(这是一个单独的实体,呈现在列表上方或后面),而是使用“duplicateParentState”属性来允许行本身显示选择(没有列表需要选择器)。这可以提供更多的创作自由,尤其是当您希望在某些行或几种看起来都不同的行上具有可变宽度的边距时。完全取决于设计。

2 - 为每一行使用边距:

如果您决定需要多种类型的颜色指示器等,您可能必须使用不同的方法,提供一个边距属性(可能不会立即起作用)...这与 LayoutParams 的使用方式有关布局系统。我试图记住确切的细节,但我认为这是由于不同类型的 LayoutParam 子类,以及 MarginLayoutParam(或其子类)的属性,例如 marginLeft 可能会被 ListView 的布局代码忽略。您应该使用 AbsListView.LayoutParams 的实例,其中不包含边距选项。一种方法是将您的行嵌套在一个容器视图(子类)中,它允许在其 LayoutParams* 中留出边距。我确定我最终没有做这种无关的嵌套,但我

你提到放置一个 ImageView 并用颜色填充它。您可以查看几种替代方案...最高效的可能是定义自己的 ListRow 类并使用 onDraw() 自己实际绘制行内容, canvas.draw_xyz() 绘制小颜色选项卡,并为其余部分绘制文本等,而不是在复合布局中构建行。第二种使用布局的方法是使用较轻的 <View layout_height="match_parent" layout_width="4dip" background="#ffff0000" /> 例如。

*Android 布局中的一条黄金法则:复杂的 UI 层次结构会影响性能,尤其是 ListView 之类的东西。通常可以通过使用其他东西来避免这种情况:RelativeLayout、drawableTop(etc)、9-patch 图像,而不是添加更多视图。

如果我误解了并且以上内容太基本了,请您提供更多详细信息,也许是一张图表,表明您需要复制的确切部分。

于 2011-05-20T17:39:21.777 回答
1

如果您想要速度,那么我会选择的选项是RelativeLayout为行容器 View 使用自定义 View 类(例如 extend )并覆盖该dispatchDraw(Canvas canvas)方法。

dispatchDraw方法在 View 绘制了自己的内容之后和绘制其子项之前super.dispatchDraw调用 - 当您调用时,子项将被绘制。

用它来做类似的事情

private boolean mDrawMarker = false;

public void setShouldDrawMarker(boolean drawMarker) {
    mDrawMarker = drawMarker;
}
public boolean getShouldDrawMarker() {
    return mDrawMarker;
}

@Override
public void dispatchDraw(Canvas canvas) {
    // draw the children of our view 
    super.dispatchDraw(canvas);

    // draw our marker on top of the children if needed
    if (mDrawMarker) {
        // e.g. canvas.drawRect(...) or canvas.drawBitmap(...)
    }
}

这样您就可以避免向层次结构添加任何额外的视图,这意味着您不会在布局或测量阶段受到任何惩罚。如果绘制一个矩形而不是每次都创建一个新矩形,请记住重复使用Paint和对象。Rect同样,如果您使用位图,您应该在您的视图的所有实例中共享相同的位图实例,而不是每次都从您的资源中加载一个新实例(这并不意味着将它们放在static字段中)

对于项目的缩进,因为在这种情况下,列表似乎没有重叠,你可以(在我的脑海中):

  • 在行容器上设置左边距(不完全确定这会起作用)
  • 将行容器包装在 a 中LinearLayout并在其上设置左侧填充(如果上述方法不起作用)
  • 使用自定义视图类(如果设置左边距不起作用)
  • 使用@commonsware 建议并使用两个视图 - 一个在左侧,背景颜色为灰色,另一个在右侧,带有标记颜色 - 如果你想要缩进/不,只需将左侧的视图设置为可见/消失 -缩进

至于第二个示例中视图的重叠,我将遵循@commonsware 的答案。

于 2011-05-20T17:49:18.117 回答
0

一个人如何实现这样的目标?

在袖口,我会使用View具有所需背景颜色的 a,当你想要它时可见,当你不需要它时不可见。

一个奖励也是交替宽度,但我想这只是一个较小的布局变化。

我不知道您所说的“交替宽度”是什么意思。我认为水平方向有两个Views具有所需背景颜色LinearLayout,只有一个可见。

我知道我可能会做一些事情,比如在其中插入一个 ImageView,然后用我想要的颜色填充它,但在我看来,这是一个丑陋的 hack。

嗯,ImageView比需要的重一点。否则,我不明白为什么这是一个黑客行为。将它们视为只是恰好又高又瘦、灰色且并不总是需要的图标。

另一个问题是,如果有一种通用的方式来组合两个 ListView 片段,就像 GMail 或 Mail 应用程序那样。

使用 a RelativeLayout,因此右侧的片段可以漂浮在左侧的片段上。

于 2011-05-20T17:01:10.277 回答