android仿QQ右上角显示im 未读消息数个数,求助

(iOS)实现QQ未读消息数量弹性按钮动画 - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了26030字,被3646人关注,获得了1206个喜欢
(iOS)实现QQ未读消息数量弹性按钮动画
好久没有更新过博客了,最近公司比较忙,老项目需要换Swift重写,用了一周左右的时间学习了下Swift,目前正在改写旧项目,个人对Swift爱不释手,感觉取代OC就这一两年内的事,不过老的iOS开发者也不需要担心,会OC转Swift真的像切菜一样简单,只需要熟悉下语法就可以,函数和OC的基本差不多,基本看个4,5个小时就可以直接上手Swift开发项目,中间不熟悉的写法只需要百度下即可,相信朋友们都会喜欢上Swift的,唠叨的有点跑题了,废话不多说,直接上代码!
由于公司项目的需求,想要达到和手机QQ未读信息一样的动画效果,周末试着写了一下,效果基本实现了,不过还有些Bug正在修改中,代码用OC写的,如果需要Swift代码的朋友可以发个私信给我,等我完善玩Swift代码发给你,先发一下效果图给大家参考下
先说一下大体的思路吧,控件是继承Button写的,并且在button的下面添加一个小的圆,给button添加拖拽手势,根据俩个圆的中心点算出拉动的距离,拖动的距离越大小圆的半径越小(勾股定理)
这个动画最大的难点在画俩个画出俩个圆之间的不规则的矩形,通过下面的这个公式可以计算出俩个圆的直径上的四个点和中间的2个点的贝塞尔控制点的point,参照下面图片
根据俩个圆的中心点算出6个点的坐标
传入俩个圆的中心点,计算出6个点的坐标,用UIBezierPath画出6个点,代码如下
- (UIBezierPath *)pathWithBigCirCleView:(UIView *)bigCirCleView
smallCirCleView:(UIView *)smallCirCleView
CGPoint bigCenter = bigCirCleView.
CGFloat x2 = bigCenter.x;
CGFloat y2 = bigCenter.y;
CGFloat r2 = bigCirCleView.bounds.size.width / 2;
CGPoint smallCenter = smallCirCleView.
CGFloat x1 = smallCenter.x;
CGFloat y1 = smallCenter.y;
CGFloat r1 = smallCirCleView.bounds.size.width / 2;
// 获取圆心距离
CGFloat d = [self pointToPoitnDistanceWithPoint:self.samllCircleView.center potintB:self.center];
CGFloat sinθ = (x2 - x1) /
CGFloat cosθ = (y2 - y1) /
// 坐标系基于父控件
CGPoint pointA = CGPointMake(x1 - r1 * cosθ , y1 + r1 * sinθ);
CGPoint pointB = CGPointMake(x1 + r1 * cosθ , y1 - r1 * sinθ);
CGPoint pointC = CGPointMake(x2 + r2 * cosθ , y2 - r2 * sinθ);
CGPoint pointD = CGPointMake(x2 - r2 * cosθ , y2 + r2 * sinθ);
CGPoint pointO = CGPointMake(pointA.x + d / 2 * sinθ , pointA.y + d / 2 * cosθ);
CGPoint pointP = CGPointMake(pointB.x + d / 2 * sinθ , pointB.y + d / 2 * cosθ);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:pointA];
[path addLineToPoint:pointB];
// 绘制BC曲线
[path addQuadCurveToPoint:pointC controlPoint:pointP];
[path addLineToPoint:pointD];
// 绘制DA曲线
[path addQuadCurveToPoint:pointA controlPoint:pointO];
由于是在button内部实现的代码,所以不可以直接在drawRect中直接绘制,超出范围的会被裁剪掉,需要CAShapeLayer来绘制
self.shapeLayer.path = [self pathWithBigCirCleView:self
smallCirCleView:_samllCircleView].CGP
从写按钮的setHighlighted:方法,在里面实现长按button是大圆左右晃动的效果
- (void)setHighlighted:(BOOL)highlighted
[self.layer removeAnimationForKey:@"shake"];
//长按左右晃动的幅度大小
CGFloat shake = 10;
CAKeyframeAnimation *keyAnim = [CAKeyframeAnimation animation];
keyAnim.keyPath = @"transform.translation.x";
keyAnim.values = @[@(-shake), @(shake), @(-shake)];
keyAnim.removedOnCompletion = NO;
keyAnim.repeatCount = MAXFLOAT;
//左右晃动一次的时间
keyAnim.duration = 0.3;
[self.layer addAnimation:keyAnim forKey:@"shake"];
给按钮本身添加一个点击事件,TouchUpInside时候销毁所有的对象,播放消失动画
设置大圆距离小圆最大的距离,根据手势的staus,在拖拽的函数里判断距离是否超过最大的距离,超过最大距离时候移除shapeLayer隐藏小圆
还有一些细节在此就不一一列举了
我自己大体的思路就是如此
下面是OC的源码,希望小手能顺便点一下右上角的?Star如果朋友们有什么问题可以直接留言,我会看到回复
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
学习从点滴开始 !
(PS: 拒绝部分投稿的文章仅仅是由于专题内已收录相关知识点的文章, 并非是投稿的文章技术含量不够好, 望谅解.)
· 5850人关注
收集进阶知识、编程干货
,每天会更新四篇。对于接收的文章,伯乐在线(@iOS大全)小编会联系您进行转载推广。如果您的投稿没有通过,可...
· 3114人关注
记录iOS开发相关文章和开发技巧。
· 1206人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:后使用快捷导航没有帐号?
只需一步,快速开始
查看: 4101|回复: 6
在线时间464 小时经验值820 最后登录注册时间帖子阅读权限70UID6691495
学士, 积分 820, 距离下一级还需 280 积分
该用户从未签到
G币63 最后登录注册时间
马上注册,结交更多机友,下载更多应用,让你轻松玩转手机。
已有帐号?   下载游戏和软件,请【】进入机锋市场!
如题,好像看见有人可以实现的 求方法
在线时间736 小时经验值905 最后登录注册时间帖子阅读权限70UID6695435
学士, 积分 905, 距离下一级还需 195 积分
TA的每日心情开心 19:05签到天数: 1 天[LV.1]初来乍到
G币-1 最后登录注册时间
想ip那样?不可以吧、、、除非借助插件、、、
在线时间6 小时经验值797 最后登录注册时间帖子阅读权限70UID
学士, 积分 797, 距离下一级还需 303 积分
TA的每日心情奋斗 09:26签到天数: 4 天[LV.2]偶尔看看I
G币933 最后登录注册时间
插件应该可以啊?
在线时间0 小时经验值5 最后登录注册时间帖子阅读权限10UID
幼儿园, 积分 5, 距离下一级还需 10 积分
该用户从未签到
G币0 最后登录注册时间
在线时间0 小时经验值60 最后登录注册时间帖子阅读权限30UID
初中生, 积分 60, 距离下一级还需 40 积分
该用户从未签到
G币0 最后登录注册时间
看过必回,人品超好!
在线时间350 小时经验值1012 最后登录注册时间帖子阅读权限70UID3573961
学士, 积分 1012, 距离下一级还需 88 积分
TA的每日心情衰 11:05签到天数: 9 天[LV.3]偶尔看看II
G币14 最后登录注册时间
我找了很久了 基本没有 只有像iphone一样的横幅通知 你去找找
算了 有什么好签的
Powered byLV3.中级会员/
安卓QQ怎么在桌面图标上显示未读消息条数啊?就是和IOS系统的QQ一样有几个未读消息,就在QQ图标上显示数字几。
在线时间 小时
LV3.中级会员
来自努比亚社区WAP版
在线时间 小时
LV3.中级会员
来自努比亚社区WAP版
板凳!!!!!!
在线时间 小时
LV4.高级会员
没这功能,
在线时间 小时
LV3.中级会员
买苹果去吧
在线时间 小时
LV3.中级会员
不错,支持一下
在线时间 小时
LV3.中级会员
站对站对,楼下跟上
在线时间 小时
LV3.中级会员
来自努比亚社区WAP版
用小米,小米可以
在线时间 小时
LV3.中级会员
来自努比亚社区WAP版
我意思是刷miui rom
在线时间 小时
校园俱乐部部长
去探索未知,去追寻我们坚守的信念,被世间一切美丽瞬间所感动!
版块推荐百宝箱
测光分离、对焦分离、测光锁定、多重曝光等,让手机也能拍出媲美单反级的照片
布拉格S 新品发布会图文直播,报道汇总!
组织或参与牛仔俱乐部线下同城会活动,将有机会获得nubia手机或参与新品发布会。
今日活跃用户
发帖数:48
发帖数:43
400-700-6600
努比亚社区APP下载
400-700-6600
周一到周日 8:30-20:30 (全年无休)android(47)
&三星已做测试OK,其他没有手机没做做对应的测试。Android &wbr&仿QQ桌面icon显示未读信息数量
//Currently, it's working from Android 4.0.&
//But some devices, which are released from the manufacturers, are not working.
public class BadgeUtil {
public enum Platform{
samsung,lg,htc,mi,sony
& & private static final String TAG = &BadgeUtil&;
& & public static void setBadgeCount(Context context, int count,Platform platform) {
& & Intent badgeIntent =
& & if(platform.equals(Platform.samsung)){
& & Log.e(TAG, &samsung....&);
& & badgeIntent = new Intent(&android.intent.action.BADGE_COUNT_UPDATE&);
& & & &badgeIntent.putExtra(&badge_count&, count);
& & & &badgeIntent.putExtra(&badge_count_package_name&, context.getPackageName());
& & & &badgeIntent.putExtra(&badge_count_class_name&, getLauncherClassName(context));
& & if(platform.equals(Platform.mi)){
& & Log.e(TAG, &xiaoMiShortCut....&);
& & badgeIntent = new Intent(&android.intent.action.APPLICATION_MESSAGE_UPDATE&);
badgeIntent.putExtra(&android.intent.extra.update_application_component_name&,getLauncherClassName(context));
& & badgeIntent.putExtra(&android.intent.extra.update_application_message_text&, count);
& & context.sendBroadcast(badgeIntent);
& & if(platform.equals(Platform.sony)){
& & Log.e(TAG, &sony....&);
& & badgeIntent = new Intent();
& & badgeIntent.putExtra(&com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE&, true);
& & badgeIntent.setAction(&com.sonyericsson.home.action.UPDATE_BADGE&);
& & badgeIntent.putExtra(&com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME&, getLauncherClassName(context));
& & badgeIntent.putExtra(&com.sonyericsson.home.intent.extra.badge.MESSAGE&, count);
& & badgeIntent.putExtra(&com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME&, context.getPackageName());
& & if(platform.equals(Platform.htc)){
& & Log.e(TAG, &htc....&);
& & badgeIntent = new Intent(&com.htc.launcher.action.UPDATE_SHORTCUT&);
& & badgeIntent.putExtra(&packagename&, getLauncherClassName(context));
& & badgeIntent.putExtra(&count&, count);
& & if(platform.equals(Platform.lg)){
& & Log.e(TAG, &lg....&);
& & badgeIntent = new Intent(&android.intent.action.BADGE_COUNT_UPDATE&);
& & badgeIntent.putExtra(&badge_count_package_name&, context.getPackageName());
& & badgeIntent.putExtra(&badge_count_class_name&, getLauncherClassName(context));
& & badgeIntent.putExtra(&badge_count&, count);
& & & & context.sendBroadcast(badgeIntent);
& & public static void resetBadgeCount(Context context,Platform platform) {
& & & & setBadgeCount(context, 0,platform);
& & private static String getLauncherClassName(Context context) {
& & & & PackageManager packageManager = context.getPackageManager();
& & & & Intent intent = new Intent(Intent.ACTION_MAIN);
& & & & // To limit the components this Intent will resolve to, by setting an
& & & & // explicit package name.
& & & & intent.setPackage(context.getPackageName());
& & & & intent.addCategory(Intent.CATEGORY_LAUNCHER);
& & & & // All Application must have 1 Activity at least.
& & & & // Launcher activity must be found!
& & & & ResolveInfo info = packageManager
& & & & & & & & .resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
& & & & // get a ResolveInfo containing ACTION_MAIN, CATEGORY_LAUNCHER
& & & & // if there is no Activity which has filtered by CATEGORY_DEFAULT
& & & & if (info == null) {
& & & & & & info = packageManager.resolveActivity(intent, 0);
& & & & Log.e(&getLauncherClassName &, &name = &&#43; info.activityInfo.name);
& & & & return info.activityInfo.
在Activity中设置Button的点击事件:
findViewById(R.id.btn_badge).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(), &厂商:&&#43;Build.MANUFACTURER, 0).show();
count = Integer.valueOf(etNum.getText().toString());
} catch (NumberFormatException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), &请输入整数&, 0).show();
if (Build.MANUFACTURER.equalsIgnoreCase(&Xiaomi&)){
& & &BadgeUtil.setBadgeCount(MainActivity.this, count, BadgeUtil.Platform.mi);
& &}else if(Build.MANUFACTURER.equalsIgnoreCase(&samsung&)){
& & BadgeUtil.setBadgeCount(MainActivity.this, count, BadgeUtil.Platform.samsung);
& &}else if(Build.MANUFACTURER.equalsIgnoreCase(&htc&)){
& & BadgeUtil.setBadgeCount(MainActivity.this, count, BadgeUtil.Platform.htc);
& &}else if(Build.MANUFACTURER.equalsIgnoreCase(&lg&)){
& & BadgeUtil.setBadgeCount(MainActivity.this, count, BadgeUtil.Platform.lg);
& &}else if(Build.MANUFACTURER.equalsIgnoreCase(&sony&)){
& & BadgeUtil.setBadgeCount(MainActivity.this, count, BadgeUtil.Platform.sony);
转自:.cn/s/blog_96amv.html
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:69495次
积分:1056
积分:1056
排名:千里之外
原创:19篇
转载:99篇
(2)(2)(6)(4)(2)(3)(1)(5)(2)(1)(1)(5)(3)(1)(10)(8)(6)(6)(5)(5)(3)(12)(3)(5)(5)(6)(3)(3)(2)(3)

我要回帖

更多关于 未读消息 的文章

 

随机推荐