国际惯例,先放github:
https://github.com/razerdp/PraiseWidget
放上效果图:
很多时候我们都看到点赞列表这个东东的存在,最典型的就是微信的赞。而最近我司也在做圈,无可避免的涉及到这个赞的控件。本来打算上网找个控件改改就算了,然而。。。也许我的搜索技术太渣,木有找到合适的。
于是懒惰的我,只好勉强唤醒脑里面睡着的那个勤奋的家伙,动手开工了。。。。。
开工之前当然需要了解下需求了,这次我司的需求跟普通的点赞有那么一丢丢的不同,废话不多说,直接上:
- 点赞嘛,当然要可以显示用户名,同时点击用户名可以做对应的操作(比如跳到他的个人主页?)
- 我司需求:要求点赞用户超过XX行,就显示等XX人,而不要完全显示
- 嗯。。。大概就这两点了- -
开工之前想了下关于这个点赞控件的难点:
- 用户点击的实现,以及用户名排序的问题
- 超过行数后显示等XX人
一开始,针对这两个问题感觉最快捷的方法不过于 FlowLayout+TextView,简单又快捷。然而用这个方法就会有一个问题,就是行数的问题,因为我们需要在绘制之前就要做到这些操作,也就是在控件被绘制之前得到行数,再显示,否则我们得到的行数永远都只能为0,因而无法做到第二点。
ps:后来想了一下,既然我们无法在当前控件绘制前得到一些数值,那我们可以直接new当前控件(父)对象,再得到需要的数值,然后把数值应用到当前的控件
pss:也许上面说的有点乱,这里打个比喻,比如说我们要设计一个控件A,而A继承B,通过重载某些方法来实现我们的控件。然而有一些数值需要在B的onDraw()里面得到,但我们需要A在onDraw()前就拿到这个数值,那么我们可以直接new出B对象,把数据塞进去,然后得到需要的数据,再把这个数据用在A身上,达到同样的效果。
回到正题,上面的两个ps都是我想到的笨方法,如果有更好的方法,求告知-V-
当时没想到这些,于是放弃用FlowLayout,而且FlowLayout也有些不方便,于是就换了一种方法:TextView+Span。
Span这个东东可牛逼了,可以说对于文字的操作都可以用到这个神器来实现。而今天的这个控件,正使用该神器实现。
那么下面开工:
首先针对第一点:显示用户名同时可以进行点击跳转。
既然我们选择加工TextView,那么关于显示用户名这个东东就很好解决了,问题在于第二个点击跳转,这里我们使用ClickableSpan解决,ClickableSpan里面只有两个方法,一个onClick,一个updateDrawState,看着方法名,很容易就知道这两个东东是干嘛用的,很明显,我们需要用到onClick来做到点击事件,那么下面就先上ClickableSpan的代码
public class PraiseClick extends ClickableSpan{
private static final int DEFAULT_COLOR=0xff517fae;
private int color;
private int userID;
private String userNick;
private Context mContext;
public PraiseClick(Context context, String userNick, int userID, int color) {
mContext = context;
this.userNick = userNick;
this.userID = userID;
this.color = color;
}
public PraiseClick(Context context, int userID, int color) {
this(context,"",userID,color);
}
public PraiseClick(Context context, int userID) {
this(context,"",userID,0);
}
public PraiseClick(Context context, String userNick, int userID) {
this(context,userNick,userID,0);
}
@Override
public void onClick(View widget) {
Toast.makeText(mContext,"当前用户名是: "+userNick+" 它的ID是: "+userID,Toast.LENGTH_SHORT).show();
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
//去掉下划线
if (color == 0) {
ds.setColor(DEFAULT_COLOR);
} else {
ds.setColor(color);
}
ds.setUnderlineText(false);
}
}
在onClick里面目前为了展示,我只用了个Toast,如果需要别的事件,可以自己重载这里。