谈谈Android中的Divider是个什么东东 下载

谈谈Android中的Divider
在Android应用开发中会经常碰到一个叫divider的东西,就是两个View之间的分割线。最近工作中注意到这个divider并分析了一下,竟然发现内有乾坤,惊为天人&
ListView的divider
1. 定制divider的边距
ListView的divider默认是左右两头到底的,如何简单的设置一个边距呢?
利用inset或者layer-list都可以简单的实现,代码如下:
&?xml version=&1.0& encoding=&utf-8&?&
xmlns:android=&/apk/res/android&
android:insetLeft=&16dp& &
android:shape=&rectangle& &
android:color=&#f00& /&
&?xml version=&1.0& encoding=&utf-8&?&
xmlns:android=&/apk/res/android&&
android:left=&16dp&&
android:shape=&rectangle&&
android:color=&#f00& /&
其中inset除了左边距insetLeft, 还有insetTop、insetRight、insetBottom, 效果图:
2. 最后一项的divider
很多同学可能发现了,ListView最后一项的divider有时候有,有时候又没有。
我画个图大家就都能理解了:
上面是数据不足的显示效果,如果数据满屏的话,都是看不多最后的divider的。
真相是,当ListView高度是不算最后一项divider的,所以只有在match_parent的情况下,ListView的高度是有余的,才能画出最后的那个divider。
ps:网上很多资料,把最后一项的divider和footerDividersEnabled混在一起了,这个是不对的,两个从逻辑上是独立的,类似的还有一个headerDividersEnabled,headerDividersEnabled和footerDividersEnabled不会影响到默认情况下最后的divider的绘制,他们是给header和footer专用的,特此说明。
RecyclerView的Divider叫做ItemDecoration,RecyclerView.ItemDecoration本身是一个抽象类,官方没有提供默认实现。
官方的Support7Demos例子中有个DividerItemDecoration, 我们可以直接参考一下,位置在sdk的这里:
extras/android/support/samples/Support7Demos/src/&/&/decorator/DividerItemDecoration.java
但是这个DividerItemDecoration有三个问题:
只支持系统默认样式,不支持自定义Drawable类型的divider
里面的算法对于无高宽的Drawable(比如上面用到的InsetDrawable)是画不出东西的
水平列表的Divider绘制方法drawHorizontal()的right计算有误,导致垂直Divider会绘制不出来,应该改为:final int right = left + mDivider.getIntrinsicWidth();;
针对这几个问题,我修复并增强了一下:
import android.content.C
import android.content.res.TypedA
import android.graphics.C
import android.graphics.R
import android.graphics.drawable.D
import android.support.v4.view.ViewC
import android.support.v7.widget.LinearLayoutM
import android.support.v7.widget.RecyclerV
import android.view.V
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mD
private int mW
private int mH
private int mO
public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
orientation
dividerDrawable
public DividerItemDecoration(Context context, int orientation, Drawable dividerDrawable) {
mDivider = dividerD
setOrientation(orientation);
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException(&invalid orientation&);
mOrientation =
public void setWidth(int width) {
this.mWidth =
public void setHeight(int height) {
this.mHeight =
public void onDraw(Canvas c, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
drawHorizontal(c, parent);
public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i & childC i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin +
Math.round(ViewCompat.getTranslationY(child));
final int bottom = top + getDividerHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i & childC i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin +
Math.round(ViewCompat.getTranslationX(child));
final int right = left + getDividerWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, getDividerHeight());
outRect.set(0, 0, getDividerWidth(), 0);
private int getDividerWidth() {
return mWidth & 0 ? mWidth : mDivider.getIntrinsicWidth();
private int getDividerHeight() {
return mHeight & 0 ? mHeight : mDivider.getIntrinsicHeight();
使用如下:
dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST, getResources().getDrawable(R.drawable.ic_launcher));
dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST, new ColorDrawable(Color.parseColor(&#ff00ff&)));
dividerItemDecoration.setHeight(1);
dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL_LIST, new ColorDrawable(Color.parseColor(&#ff00ff&)));
dividerItemDecoration.setWidth(1);
dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL_LIST, getResources().getDrawable(R.drawable.list_divider));
dividerItemDecoration.setWidth(DisplayLess.$dp2px(16) + 1);
手动的Divider
有的时候没有系统控件的原生支持,只能手动在两个view加一个divider,比如,设置界面每项之间的divider,水平平均分隔的几个view之间加一个竖的divider等等。
无论横的竖的,都非常简单,定一个View,设置一个background就可以了,正常情况下没什么好说的。
下面我们来考虑一种常见设置界面,这种设置界面的分割线是有左边距的,比如微信的设置界面,我相信绝大部分人的布局代码都是这样实现的:
xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&match_parent&&
android:id=&@+id/group_container&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_alignParentTop=&true&
android:layout_marginTop=&48dp&
android:background=&#fff&
android:orientation=&vertical&&
android:id=&@+id/account_container&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:background=&@drawable/list_item_bg&
android:clickable=&true&&
android:id=&@+id/account_title&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_alignParentLeft=&true&
android:layout_centerVertical=&true&
android:layout_margin=&16dp&
android:text=&First Item&
android:textColor=&#f00&
android:textSize=&16sp& /&
android:layout_width=&match_parent&
android:layout_height=&1px&
android:layout_marginLeft=&16dp&
android:background=&#f00& /&
android:id=&@+id/phone_container&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:background=&@drawable/list_item_bg&
android:clickable=&true&&
android:id=&@+id/phone_title&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_alignParentLeft=&true&
android:layout_centerVertical=&true&
android:layout_margin=&16dp&
android:text=&Second Item&
android:textColor=&#f00&
android:textSize=&16sp& /&
效果图如下,顺便我们也看看它的Overdraw状态:
通过分析Overdraw的层次,我们发现为了一个小小的边距,设置了整个groud_container的背景,从而导致了一次Overdraw。
能不能优化掉这个Overdraw?答案是肯定的。
背景肯定要去掉,但是这个左边距的View就不能这么简单的写了,需要自定义一个View,它要支持能把左边距的空出的16dp的线用list_item_normal的颜色值绘制一遍,这样才能看的出左边距。
这个View具体代码如下:
import android.content.C
import android.content.res.TypedA
import android.graphics.C
import android.graphics.C
import android.graphics.P
import android.util.AttributeS
import android.util.TypedV
import android.view.V
import com.jayfeng.lesscode.core.R;
public class SpaceDividerView extends View {
private int mSpaceLeft = 0;
private int mSpaceTop = 0;
private int mSpaceRight = 0;
private int mSpaceBottom = 0;
private int mSpaceColor = Color.TRANSPARENT;
private Paint mPaint = new Paint();
public SpaceDividerView(Context context) {
this(context, null);
public SpaceDividerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
public SpaceDividerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpaceDividerView, defStyleAttr, 0);
mSpaceLeft = a.getDimensionPixelSize(R.styleable.SpaceDividerView_spaceLeft,
(int) TypedValue.PLEX_UNIT_DIP, 0, getResources().getDisplayMetrics()));
mSpaceTop = a.getDimensionPixelSize(R.styleable.SpaceDividerView_spaceTop,
(int) TypedValue.PLEX_UNIT_DIP, 0, getResources().getDisplayMetrics()));
mSpaceRight = a.getDimensionPixelSize(R.styleable.SpaceDividerView_spaceRight,
(int) TypedValue.PLEX_UNIT_DIP, 0, getResources().getDisplayMetrics()));
mSpaceBottom = a.getDimensionPixelSize(R.styleable.SpaceDividerView_spaceBottom,
(int) TypedValue.PLEX_UNIT_DIP, 0, getResources().getDisplayMetrics()));
mSpaceColor = a.getColor(R.styleable.SpaceDividerView_spaceColor, Color.TRANSPARENT);
a.recycle();
mPaint.setColor(mSpaceColor);
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mSpaceLeft & 0) {
canvas.drawRect(0, 0, mSpaceLeft, getMeasuredHeight(), mPaint);
if (mSpaceTop & 0) {
canvas.drawRect(0, 0, getMeasuredWidth(), mSpaceTop, mPaint);
if (mSpaceRight & 0) {
canvas.drawRect(getMeasuredWidth() - mSpaceRight, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
if (mSpaceBottom & 0) {
canvas.drawRect(0, getMeasuredHeight() - mSpaceBottom, getMeasuredWidth(), getMeasuredHeight(), mPaint);
用这个SpaceDividerView我们重写一下上面的布局代码:
xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&match_parent&
xmlns:app=&/apk/res-auto&&
android:id=&@+id/group_container&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_alignParentTop=&true&
android:layout_marginTop=&48dp&
android:orientation=&vertical&&
android:id=&@+id/account_container&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:background=&@drawable/list_item_bg&
android:clickable=&true&&
android:id=&@+id/account_title&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_alignParentLeft=&true&
android:layout_centerVertical=&true&
android:layout_margin=&16dp&
android:text=&First Item&
android:textColor=&#f00&
android:textSize=&16sp& /&
android:layout_width=&match_parent&
android:layout_height=&1px&
android:background=&#f00&
app:spaceLeft=&16dp&
app:spaceColor=&@color/list_item_normal&/&
android:id=&@+id/phone_container&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:background=&@drawable/list_item_bg&
android:clickable=&true&&
android:id=&@+id/phone_title&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_alignParentLeft=&true&
android:layout_centerVertical=&true&
android:layout_margin=&16dp&
android:text=&Second Item&
android:textColor=&#f00&
android:textSize=&16sp& /&
效果图和Overdraw状态如下:
界面中group_container那块由之前的绿色变成了蓝色,说明减少了一次Overdraw。
上述情况下,SpaceDividerView解耦了背景色,优化了Overdraw,而且这个SpaceDividerView也是支持4个方向的,使用起来特别方便。
阴影divider
阴影分割线的特点是重叠在下面的view之上的,它的目的是一种分割线的立体效果。
使用RelativeLayout并控制上边距离可以实现:
xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&match_parent&&
android:layout_width=&match_parent&
android:layout_height=&match_parent&
android:layout_alignParentTop=&true&
android:layout_marginTop=&@dimen/header_height&
android:orientation=&vertical&&
android:id=&@+id/header&
layout=&@layout/include_header& /&
虽然再简单不过了,还是稍微分析一下,header包括内容48dp和阴影8dp,那么marginTop就是48dp了。
官方微信更多精彩,扫码关注 或微信搜索:ujiuye
官方微博更多精彩,扫码关注 或微博搜索:优就业
注:本站稿件未经许可不得转载,转载请保留出处及源文件地址。
(责任编辑:zhangjs)
关键词阅读
免费声明:本站所提供真题均来源于网友提供或网络搜集,由本站编辑整理,仅供个人研究、交流学习使用,不涉及商业盈利目的。如涉及版权问题,请联系本站管理员予以更改或删除。
优就业官方微信扫描二维码,即可与小U亲密互动
优就业官方QQ号
咨询电话(09:00-22:00)400-650-7353
IT培训友情链接
|||||||||||||||||||||||||||||||||||||
(点击一键加群)2014年6月 移动开发大版内专家分月排行榜第一2014年3月 移动开发大版内专家分月排行榜第一
2014年11月 移动开发大版内专家分月排行榜第二2014年4月 移动开发大版内专家分月排行榜第二2014年2月 移动开发大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。给ListView设置分割线,只需设置如下两个属性:
android:divider="#000" //设置分割线显示颜色
android:dividerHeight="1px" //此处非0,否则无效
&ListView android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#FFF"
android:dividerHeight="1px"
android:layout_margin="10dip"/&
阅读(...) 评论()【android】巧用android:divider属性设置LinearLayout中元素之间的间隔 - CSDN博客
【android】巧用android:divider属性设置LinearLayout中元素之间的间隔
如上图,要想实现3个button线性排列并且使它们的大小相同、间隔相等、而且整体填充满整个linearlayout,我们一般的做法是在每两个button之间放一个固定宽度的view,然后设置button的宽度为0、layout_weight为1。这样虽能实现功能,可是总感觉不方便,特别是button多的时候。
今天介绍另一种简单、优雅的方法,就是利用android:divider属性。
1、首先新建一个固有的width/height的Drawable:
spacer_medium.xml
2.然后设置LinearLayout的android:divider=&@drawable/spacer_medium&,并设置android:showDividers=&middle&,这样就完美解决了linearLayout的元素之间的间隔问题。
&LinearLayout
android:layout_marginLeft=&12dp&
android:layout_marginRight=&12dp&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:orientation=&horizontal&
android:divider=&@drawable/spacer_medium&
android:background=&#&
android:showDividers=&middle&&
android:layout_width=&0dp&
android:layout_height=&wrap_content&
android:layout_weight=&1&
android:text=&button&/&
android:layout_width=&0dp&
android:layout_height=&wrap_content&
android:layout_weight=&1&
android:text=&button&/&
android:layout_width=&0dp&
android:layout_height=&wrap_content&
android:layout_weight=&1&
android:text=&button&/&
&/LinearLayout&
参考:http://blog.csdn.net/startupmount/article/details/
本文已收录于以下专栏:
相关文章推荐
第一种方法:
可以放置一个ImageView组件,然后将其北京设为分隔线的颜色或图形。
分隔线View的定义代码如下:
&ImageView
android:layout_wi...
在做Android 项目中经常会使用 margin 来设置 view之间的间距非常的简单也很方便 并且还可以 通过layoutparams动态的来设置 但是在动态设置并不是值得提倡的
今天学到来一个...
如何在LinearLayout中添加分割线,就像下面这张图一样。
推荐方法:
LinearLayout有两个属性
1、android:divider=&@drawable&
drawable可以...
距离上次发博客好像已经至少有两个月的时间了,不禁感叹时间过得真快,也是因为项目一直在忙,所以没来发博客,今天有闲情就来一发。好了,废话不多说,今天讲的是fragment复用的问题,提到碎片,相信大家都...
今天我们讲下如何从网络解析Json数据并通过Fragment填充到ViewPager中。
再次明确一点:对于使用Fragment来填充ViewPager的实现,我们自定义的Fragment所继承的F...
在使用ViewPager的时候遇到一个错误java.lang.IllegalStateException: The specified child already has a parent. You ...
这个属性可以在LinearLayout的每个子布局直间添加一个“drawable”作为分割线,这个drawable必须有设定好的高度或者宽度,因此不能之间设置为“@color/….”
这个属性要和an...
由于这两天在做listView的东西,所以整理出来一些我个人认为比较特别的属性,通过设置这样的属性可以做出更加美观的列表
首先是stackFromBottom属性,这只该属性之后你做好的列表...
上次给大家介绍了如何使用意图在Activity之间传递数据,这次讲解一下如何使用静态变量来传递数据,
原理其实很简单,就是在接收端的Avtivity里面设置static的变量,在发送端这边改变静态变...
他的最新文章
讲师:何宇健
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 什么东东 安又琪下载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信