ListView行标记ala GMail

时间:2011-05-20 16:56:37

标签: android android-layout android-listview android-3.0-honeycomb android-fragments

我有兴趣创建一个ListView,其中每行标记在GMail for 3.0+中的完成方式。这样可以很好地分离左右ListFragment。

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

GMail ListView

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

我知道我可以做一些事情,比如在那里插入一个ImageView,然后用我想要的颜色填充它,但在我看来,这是一个丑陋的黑客。

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

GMail ListView across two fragments

3 个答案:

答案 0 :(得分:1)

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

以下是两种技巧:

1 - 对行背景使用StateListDrawable:

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

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

为了让人们发现这一点,Radley Marx刚刚发布了一篇关于9补丁的优秀文章:http://radleymarx.com/blog/simple-guide-to-9-patch/

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

2 - 为每一行使用保证金:

如果您确定需要多种类型的颜色指示器等,您可能必须使用不同的方法,提供边距属性(可能不会立即工作)...这与LayoutParams的方式有关布局系统使用。我试图记住确切的细节,但我认为这是由于不同类型的LayoutParam子类,以及MarginLayoutParam(或其子类)的属性,例如marginView的布局代码可能会忽略marginLeft。您应该使用AbsListView.LayoutParams的实例,其中不包含边距选项。一种方法是将行嵌套在容器View(子类)中,该容器允许其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图像,而不是添加更多视图。

如果我误解了,上面的内容太基础了,请你提供一些更详细的信息,也许是一张表明你需要复制的确切部分的图表。

答案 1 :(得分:1)

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

dispatchDraw方法在之后被称为,而视图已经绘制了自己的内容,之前绘制了它的子项 - 当您调用{{ 1}}。

使用它来执行类似

的操作
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个对象。同样,如果您使用位图,则应该在View的所有实例中共享相同的Bitmap实例,而不是每次都从资源中加载一个新的实例(这样做意味着将它们放入Rect字段)

对于项目的缩进,因为在这种情况下,列表看起来似乎没有重叠(我的头顶):

  • 在行容器上设置左边距(不完全确定这将起作用)
  • 将行容器包裹在static中并在其上设置左侧填充(如果上述操作不起作用)
  • 使用自定义视图类(如果设置左边距不起作用)
  • 使用@commonsware建议并使用两个视图 - 左边一个带有灰色背景颜色,另一个右边带有标记颜色 - 然后只需要将缩进设置为左边的视图/无压痕

至于第二个例子中视图的重叠,我会按照@commonsware的回答。

答案 2 :(得分:0)

  

如何实现这样的目标?

关闭袖口,我会使用具有所需背景颜色的View,在您需要时可以看到,但在您不需要时则不可见。

  

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

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

  

我知道我可以做一些事情,比如在那里插入一个ImageView,然后用我想要的颜色填充它,但在我看来,这是一个丑陋的黑客。

嗯,ImageView比需要的要重一点。否则,我不明白为什么这是一个黑客。把它们想象成简单的高,薄,灰色,并不总是需要的图标。

  

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

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