您的位置:首页 > 移动开发 > Android开发

[置顶] Android带你实现门票布局效果

2016-07-27 22:15 381 查看
今天带给大家一个门票布局的效果。直接看图吧:



上图展示了一个门票列表的界面,可以发现每个Item的四个角都是凹下去的。并且图片左边上下两个角也是凹下去的。我们该如何实现这种效果呢?

有朋友可能会说UI肯定会给一个这样的背景图片的。嗯,使用这样的图片肯定没问题,缺点就是加在多了占据内存而已。可是Photo的左上和左下也是要这样的圆角哇。该怎么办呢?

基于这种需求,我们可以变换一种方式来实现。让UI给我们每个角的半径,我们自己来画出来就OK了。



我们今天要实现的效果是不使用任何图片,完全自定义布局和图片来实现这样的效果。

实现思路:

(1)自定义一个布局,继承自LinearLayout,使用Paint根据半径在四个角画四个圆,背景为白色。

(2)自定义图片控件,继承自ImageView,同样使用Paint根据半径在左上角和左下角画圆,背景为白色。

思路很清楚,就是利用了画圆的效果在视觉上给人一种凹角的感觉。下面看核心代码:

自定义LinearLayout:

/**
* View的大小发生改变时并且在onFinishInflate方法后被回调
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//获取布局的宽高
this.layoutWidth = w;
this.layoutHeight = h;

}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

canvas.drawCircle(0,0,radius,paint);
canvas.drawCircle(0,layoutHeight,radius,paint);
canvas.drawCircle(layoutWidth,0,radius,paint);
canvas.drawCircle(layoutWidth,layoutHeight,radius,paint);
}

自定义IamegView:

/**
* View的大小发生改变时并且在onFinishInflate方法后被回调
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//获取布局的宽高
this.layoutWidth = w;
this.layoutHeight = h;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(0,0,radius,paint);
canvas.drawCircle(0, layoutHeight, radius, paint);
}


圆的半径我们通过自定义属性来实现:

<declare-styleable name="TLayout">
<attr name="radius" format="dimension" />
</declare-styleable>


然后在构造函数中获取即可:

public TLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.TLayout,defStyleAttr,0);
int num = ta.getIndexCount();
for (int i = 0; i < num; i++) {
int attr = ta.getIndex(i);
switch (attr) {
case R.styleable.TLayout_radius:
radius = ta.getDimensionPixelSize(attr,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,5,getResources().getDisplayMetrics()));
break;
default:
break;
}
}
ta.recycle();
initPaint();
}

上面代码使用了for循环的方式来获取自定义的属性值,这种方式适合属性多的场景,如果自定义属性值比较少,那么可以使用下面这个方法来获取:

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TLayout, defStyleAttr, 0);
radius = ta.getDimensionPixelSize(R.styleable.TLayout_radius,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,5,getResources().getDisplayMetrics()));
ta.recycle();


ok,来看下效果图:



好啦,今天的介绍就到这里啦,有问题的朋友给我留言。

源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: