上篇文章,我们整理了网易云信的快速集成过程.有兴趣的小伙伴可以移步到:ios集成网易云信IM功能遇到的坑 .简单的实现一对一聊天界面或者查看最近联系人列表.我们只需直接调用NIMKit里面的NIMSessionViewController 和 NIMSessionListViewController这两个类方法.就能实现功能.但是简单的聊天可能满足不了我们项目需要.比如要实现电商平台中,我们浏览商品.突然觉得商品还不错.去找客服聊天.那么这时候我们希望把浏览的商品也给推送过去.好让客服知道我们在看什么.并且,自定义消息设置成可点击的,方便可以点击查看商品详情.

今天我就给大家整理下怎么实现自定义消息发送.

其实具体也可以参考官方demo中实现发送大表情效果过程.毕竟大表情图片其实也是一种自定义消息发送的表现形式.

那么,发送自定义消息,我大概整理了下,觉得可以分为四部分,这样实现起来逻辑会觉得比较清晰.如下:

1.实现自定义消息model类.承接数据部分.

2.实现自定义消息view 类,承接自定义UI部分.

3.实现自定义布局配置类.

4.消息解析器(解析消息,辨别消息类型!)

最后一步,就是在入口类中注册拉起解析器和自定义布局.这样,系统才能识别消息类型,并实现自定义布局.

那!第一步,我们实现自定义消息model类,承接数据部分.

创建一个类,继承与NSObject.并实现NIMKit  <NIMCustomAttachment,NTESCustomAttachmentInfo>两个协议方法.

.h类中:

#import <Foundation/Foundation.h>

#import "NIMKit.h"

#import "NTESCustomAttachmentDefines.h"

@interface NTESSendShopGoodsAttachment :NSObject<NIMCustomAttachment,NTESCustomAttachmentInfo>

//添加自定义消息元素

@property(nonatomic,copy)NSString*headerImage;

@property(nonatomic,copy)NSString*nameLabel;

@property(nonatomic,copy)NSString*priceLabel;

//数据源承接类

@property(nonatomic,strong)NSDictionary*messageDic;

@end

.m类中:

#import "NTESSendShopGoodsAttachment.h"

@implementation NTESSendShopGoodsAttachment

//对数据源进行类型分配.

- (NSString *)encodeAttachment

{

NSDictionary *dictContent =@{CM_GOODS_IMG:self.headerImage,CM_GOODS_NAME:self.nameLabel,CM_GOODS_PRICE:self.priceLabel};

NSDictionary *dict =@{CMType :@(CustomMessageSendShopGoods),

CMData :dictContent};

NSData *data = [NSJSONSerializationdataWithJSONObject:dict

options:0

error:nil];

NSString *content =nil;

if (data) {

content = [[NSStringalloc] initWithData:data

encoding:NSUTF8StringEncoding];

}

return content;

}

//实例化元素(懒加载...)

-(NSString *)headerImage{

if (!_headerImage) {

_headerImage =nil;

}

return_headerImage;

}

-(NSString *)nameLabel{

if (!_nameLabel) {

_nameLabel =nil;

}

return_nameLabel;

}

-(NSString *)priceLabel

{

if (!_priceLabel) {

_priceLabel =nil;

}

return_priceLabel;

}

//数据源setter方法实现

-(void)setMessageDic:(NSDictionary *)messageDic

{

_messageDic =messageDic;

//给元素赋值

self.headerImage =[_messageDic[@"picture"]substringFromIndex:3];

self.nameLabel =_messageDic[@"name"];

self.priceLabel =_messageDic[@"price"];

}

//设置自定义消息Bounds

- (CGSize)contentSize:(NIMMessage *)message cellWidth:(CGFloat)width{

returnCGSizeMake(200,70);

}

- (UIEdgeInsets)contentViewInsets:(NIMMessage *)message

{

if (message.session.sessionType == NIMSessionTypeChatroom)

{

CGFloat bubbleMarginTopForImage  =15.f;

CGFloat bubbleMarginLeftForImage =12.f;

return UIEdgeInsetsMake(bubbleMarginTopForImage,bubbleMarginLeftForImage,0,0);

}

else

{

CGFloat bubbleMarginForImage    =3.f;

CGFloat bubbleArrowWidthForImage =5.f;

if (message.isOutgoingMsg) {

return UIEdgeInsetsMake(bubbleMarginForImage,bubbleMarginForImage,bubbleMarginForImage,bubbleMarginForImage + bubbleArrowWidthForImage);

}else{

return UIEdgeInsetsMake(bubbleMarginForImage,bubbleMarginForImage + bubbleArrowWidthForImage, bubbleMarginForImage,bubbleMarginForImage);

}

}

}

//指向自定义view类

- (NSString *)cellContent:(NIMMessage *)message{

return@"NTESSessionSendShopGoodsContentView";

}

   那!我们现在创建自定义view类.自定义view类继承与父类: NIMSessionMessageContentView
   .h文件:

#import "NIMSessionMessageContentView.h"

//用于点击事件触发标识符!!!

extern NSString *const SendCustomWithGoodsClick;

@interface NTESSessionSendShopGoodsContentView :NIMSessionMessageContentView

//自定义展示商品信息控件

@property(nonatomic,strong)UIImageView *headerImg;

@property(nonatomic,strong)UILabel*nameLa;

@property(nonatomic,strong)UILabel*priceLa;

@end

  .m文件:

#import "NTESSessionSendShopGoodsContentView.h"

#import "NTESSendShopGoodsAttachment.h"

#import "UIView+SL.h"

#import "UIImage+Image.h"

NSString *const SendCustomWithGoodsClick =@"SendCustomWithGoodsClick";

@interface NTESSessionSendShopGoodsContentView()

//添加手势

@property (nonatomic,strong)UITapGestureRecognizer*top;

@end

@implementation NTESSessionSendShopGoodsContentView

- (instancetype)initSessionMessageContentView{

self = [superinitSessionMessageContentView];

if (self) {

self.opaque =YES;

//点击自定义消息cell,添加手势

self.top = [[UITapGestureRecognizeralloc] initWithTarget:selfaction:@selector(tapGesture:)];

[selfaddGestureRecognizer:self.top];

self.headerImg =[[UIImageViewalloc]initWithFrame:CGRectZero];

[selfaddSubview:self.headerImg];

self.nameLa =[[UILabel  alloc]initWithFrame:CGRectZero];

_nameLa.font =[UIFontsystemFontOfSize:13];

_nameLa.numberOfLines =0;

[selfaddSubview:self.nameLa];

self.priceLa =[[UILabelalloc]initWithFrame:CGRectZero];

_priceLa.font =[UIFontsystemFontOfSize:12];

_priceLa.textColor =[UIColororangeColor];

[selfaddSubview:self.priceLa];

}

returnself;

}

#pragma mark - 点击手势

- (void)tapGesture:(UITapGestureRecognizer *)recognizer {

if ([self.delegaterespondsToSelector:@selector(onCatchEvent:)]) {

NIMKitEvent *event = [[NIMKitEventalloc] init];

//添加自定义消息标识符

event.eventName =SendCustomWithGoodsClick;

event.messageModel =self.model;

event.data =self;

[self.delegateonCatchEvent:event];

}

}

//赋值

- (void)refresh:(NIMMessageModel *)data{

[superrefresh:data];

NIMCustomObject *customObject = (NIMCustomObject*)data.message.messageObject;

id attachment = customObject.attachment;

if ([attachmentisKindOfClass:[NTESSendShopGoodsAttachmentclass]]) {

self.nameLa.text =[attachmentnameLabel ];

IMAGE_URL(self.headerImg,[attachment headerImage],@"header.jpg");

self.priceLa.text =[attachmentpriceLabel];

}

}

//自定义view元素控件坐标设置

- (UIImage *)chatBubbleImageForState:(UIControlState)state outgoing:(BOOL)outgoing{

self.headerImg.frame =CGRectMake(7,8,54,54);

self.nameLa.frame =CGRectMake(70,5,125,40);

self.priceLa.frame =CGRectMake(70,50,70,15);

//背景颜色

return [UIImageimageWithColor:[UIColorwhiteColor]];

}

@end

自定义cell布局类继承父类: NIMCellLayoutConfig
.h文件:

#import "NIMCellLayoutConfig.h"

#import "NIMKit.h"

@interface NTESCellLayoutConfig :NIMCellLayoutConfig<NIMCellLayoutConfig>

@end

#import "NTESCellLayoutConfig.h"

#import "NTESSessionCustomContentConfig.h"

@interface NTESCellLayoutConfig ()

@property (nonatomic,strong)   NSArray    *types;

@property (nonatomic,strong)   NTESSessionCustomContentConfig  *sessionCustomconfig;

@end

.m文件:

@implementation NTESCellLayoutConfig

- (instancetype)init

{

if (self = [superinit])

{

//添加消息类型!我们写在了第一个

_types = @[

@"NTESSendShopGoodsAttachment",

@"NTESSnapchatAttachment",

@"NTESChartletAttachment",

@"NTESWhiteboardAttachment"

];

_sessionCustomconfig = [[NTESSessionCustomContentConfigalloc] init];

}

returnself;

}

#pragma mark - NIMCellLayoutConfig

- (CGSize)contentSize:(NIMMessageModel *)model cellWidth:(CGFloat)width{

NIMMessage *message = model.message;

//检查是不是当前支持的自定义消息类型

if ([selfisSupportedCustomMessage:message]) {

return [_sessionCustomconfigcontentSize:width message:message];

}

//检查是不是聊天室文本消息

if ([selfisChatroomTextMessage:message]) {

// return [_chatroomTextConfig contentSize:width message:message];

}

//如果没有特殊需求,就走默认处理流程

return [supercontentSize:model

cellWidth:width];

}

- (NSString *)cellContent:(NIMMessageModel *)model{

NIMMessage *message = model.message;

//检查是不是当前支持的自定义消息类型

if ([selfisSupportedCustomMessage:message]) {

return [_sessionCustomconfigcellContent:message];

}

//检查是不是聊天室文本消息

if ([selfisChatroomTextMessage:message]) {

//  return [_chatroomTextConfig cellContent:message];

}

//如果没有特殊需求,就走默认处理流程

return [supercellContent:model];

}

- (UIEdgeInsets)contentViewInsets:(NIMMessageModel *)model

{

NIMMessage *message = model.message;

//检查是不是当前支持的自定义消息类型

if ([selfisSupportedCustomMessage:message]) {

return [_sessionCustomconfigcontentViewInsets:message];

}

//检查是不是聊天室文本消息

if ([selfisChatroomTextMessage:message]) {

//  return [_chatroomTextConfig contentViewInsets:message];

}

//如果没有特殊需求,就走默认处理流程

return [supercontentViewInsets:model];

}

- (UIEdgeInsets)cellInsets:(NIMMessageModel *)model

{

NIMMessage *message = model.message;

//检查是不是聊天室消息

if (message.session.sessionType ==NIMSessionTypeChatroom) {

returnUIEdgeInsetsZero;

}

//如果没有特殊需求,就走默认处理流程

return [supercellInsets:model];

}

- (BOOL)shouldShowAvatar:(NIMMessageModel *)model

{

if ([selfisSupportedChatroomMessage:model.message]) {

returnNO;

}

return [supershouldShowAvatar:model];

}

- (BOOL)shouldShowLeft:(NIMMessageModel *)model{

if ([selfisSupportedChatroomMessage:model.message]) {

returnYES;

}

return [supershouldShowLeft:model];

}

- (BOOL)shouldShowNickName:(NIMMessageModel *)model{

if ([selfisSupportedChatroomMessage:model.message]) {

returnYES;

}

return [supershouldShowNickName:model];

}

- (CGFloat)nickNameMargin:(NIMMessageModel *)model{

if ([selfisSupportedChatroomMessage:model.message]) {

NSDictionary *ext = model.message.remoteExt;

NIMChatroomMemberType type = [ext[@"type"]integerValue];

switch (type) {

caseNIMChatroomMemberTypeManager:

caseNIMChatroomMemberTypeCreator:

return50.f;

default:

break;

}

return15.f;

}

return [supernickNameMargin:model];

}

- (NSArray *)customViews:(NIMMessageModel *)model

{

if ([selfisSupportedChatroomMessage:model.message]) {

NSDictionary *ext = model.message.remoteExt;

NIMChatroomMemberType type = [ext[@"type"]integerValue];

NSString *imageName;

switch (type) {

caseNIMChatroomMemberTypeManager:

imageName = @"chatroom_role_manager";

break;

caseNIMChatroomMemberTypeCreator:

imageName = @"chatroom_role_master";

break;

default:

break;

}

UIImageView *imageView;

if (imageName.length) {

UIImage *image = [UIImageimageNamed:imageName];

imageView = [[UIImageViewalloc] initWithImage:image];

CGFloat leftMargin =15.f;

CGFloat topMatgin  =0.f;

CGRect frame = imageView.frame;

frame.origin =CGPointMake(leftMargin, topMatgin);

imageView.frame = frame;

}

return imageView ?@[imageView] :nil;

}

return [supercustomViews:model];

}

#pragma mark - misc

- (BOOL)isSupportedCustomMessage:(NIMMessage *)message

{

NIMCustomObject *object = message.messageObject;

return [objectisKindOfClass:[NIMCustomObjectclass]] &&

[_typesindexOfObject:NSStringFromClass([object.attachmentclass])] != NSNotFound;

}

- (BOOL)isSupportedChatroomMessage:(NIMMessage *)message

{

return message.session.sessionType == NIMSessionTypeChatroom &&

(message.messageType ==NIMMessageTypeText || [selfisSupportedCustomMessage:message]);

}

- (BOOL)isChatroomTextMessage:(NIMMessage *)message

{

return message.session.sessionType == NIMSessionTypeChatroom &&

message.messageObject ==NIMMessageTypeText;

}

以及自定义消息配置类:
.h文件:

#import "NIMBaseSessionContentConfig.h"

@interface NTESSessionCustomContentConfig :NSObject<NIMSessionContentConfig>

@end

.m文件:

#import "NTESSessionCustomContentConfig.h"

#import "NTESCustomAttachmentDefines.h"

@interface NTESSessionCustomContentConfig()

@end

@implementation NTESSessionCustomContentConfig

- (CGSize)contentSize:(CGFloat)cellWidth message:(NIMMessage *)message

{

NIMCustomObject *object = message.messageObject;

NSAssert([object isKindOfClass:[NIMCustomObject class]],@"message must be custom");

id<NTESCustomAttachmentInfo> info = (id<NTESCustomAttachmentInfo>)object.attachment;

return [infocontentSize:message cellWidth:cellWidth];

}

- (NSString *)cellContent:(NIMMessage *)message

{

NIMCustomObject *object = message.messageObject;

NSAssert([object isKindOfClass:[NIMCustomObject class]],@"message must be custom");

id<NTESCustomAttachmentInfo> info = (id<NTESCustomAttachmentInfo>)object.attachment;

return [infocellContent:message];

}

- (UIEdgeInsets)contentViewInsets:(NIMMessage *)message

{

NIMCustomObject *object = message.messageObject;

NSAssert([object isKindOfClass:[NIMCustomObject class]],@"message must be custom");

id<NTESCustomAttachmentInfo> info = (id<NTESCustomAttachmentInfo>)object.attachment;

return [infocontentViewInsets:message];

}

@end

好了,到这里,自定义view和model类以及自定义cell布局类都设置完成了.

接下来我们实现自定义消息解析处理类:
.h文件:

#import <Foundation/Foundation.h>

#import "NIMKit.h"

@interface NTESCustomAttachmentDecoder :NSObject<NIMCustomAttachmentCoding>

@end

.m文件:

#import "NTESCustomAttachmentDecoder.h"

#import "NTESCustomAttachmentDefines.h"

#import "NSDictionary+SLJSON.h"

#import "NTESSendShopGoodsAttachment.h"

#import "NTESChartletAttachment.h"

@implementation NTESCustomAttachmentDecoder

- (id<NIMCustomAttachment>)decodeAttachment:(NSString *)content

{

id<NIMCustomAttachment> attachment =nil;

NSData *data = [contentdataUsingEncoding:NSUTF8StringEncoding];

if (data) {

NSDictionary *dict = [NSJSONSerializationJSONObjectWithData:data

options:0

error:nil];

if ([dictisKindOfClass:[NSDictionaryclass]])

{

NSInteger type     = [dictjsonInteger:CMType];

NSDictionary *data = [dictjsonDict:CMData];

switch (type) {

caseCustomMessageTypeChartlet:

{

attachment = [[NTESChartletAttachmentalloc] init];

((NTESChartletAttachment *)attachment).chartletCatalog = [datajsonString:CMCatalog];

((NTESChartletAttachment *)attachment).chartletId      = [datajsonString:CMChartlet];

}

break;

caseCustomMessageSendShopGoods:

{

attachment = [[NTESSendShopGoodsAttachmentalloc] init];

((NTESSendShopGoodsAttachment *)attachment).headerImage = [datajsonString:CM_GOODS_IMG];

((NTESSendShopGoodsAttachment *)attachment).nameLabel = [datajsonString:CM_GOODS_NAME];

((NTESSendShopGoodsAttachment *)attachment).priceLabel = [datajsonString:CM_GOODS_PRICE];                }

default:

break;

}

attachment = [selfcheckAttachment:attachment] ? attachment :nil;

}

}

return attachment;

}

- (BOOL)checkAttachment:(id<NIMCustomAttachment>)attachment{

BOOL check =NO;

if ([attachmentisKindOfClass:[NTESSendShopGoodsAttachmentclass]]) {

NSString *headerImg = ((NTESSendShopGoodsAttachment *)attachment).headerImage;

NSString *shopNameLa = ((NTESSendShopGoodsAttachment *)attachment).nameLabel;

NSString *priceLa = ((NTESSendShopGoodsAttachment *)attachment).priceLabel;

check = shopNameLa.length&&priceLa.length&&headerImg.length ?YES : NO;

}elseif ([attachment isKindOfClass:[NTESChartletAttachmentclass]]) {

NSString *chartletCatalog = ((NTESChartletAttachment *)attachment).chartletCatalog;

NSString *chartletId      =((NTESChartletAttachment *)attachment).chartletId;

check = chartletCatalog.length&&chartletId.length ?YES : NO;

}

return check;

}

@end

以上四部分处理我们都做完了.现在去入口类注册解析器和自定义cell配置:
    // 注册自定义消息的解析器

[NIMCustomObjectregisterCustomDecoder:[NTESCustomAttachmentDecodernew]];

//注册 NIMKit自定义排版配置

[[NIMKitsharedKit] registerLayoutConfig:[NTESCellLayoutConfignew]];

在需要发送商品自定义消息的地方:

//自定义消息

-(void)sendManager:(UIButton *)btn

{

//隐藏topView

static int a =80;

[UIViewanimateWithDuration:0.5animations:^{

CGRect rect =self.topView.frame;

rect.origin.y -=a;

self.topView.frame =rect;

} completion:^(BOOL finished) {

[self.topViewremoveFromSuperview];

}];

//发送自定义消息

self.attachment = [[NTESSendShopGoodsAttachmentalloc] init];

_attachment.messageDic =self.messageDict;

NIMMessage *message               = [[NIMMessagealloc] init];

NIMCustomObject *customObject     = [[NIMCustomObjectalloc] init];

customObject.attachment           =_attachment;

message.messageObject             = customObject;

[selfsendMessage:message];

}

在cell点击事件中,我们添加自定义消息类型判断(方法中文字为黑色部分).通过点击手势,进入其他界面.

#pragma mark ---------------- cell点击事件 ------------------

- (NSDictionary *)cellActions

{

staticNSDictionary *actions = nil;

staticdispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

actions = @{@(NIMMessageTypeImage) :   @"showImage:",

@(NIMMessageTypeVideo) :   @"showVideo:",

@(NIMMessageTypeLocation) :@"showLocation:",

@(NIMMessageTypeFile)  :   @"showFile:",

@(NIMMessageTypeCustom):   @"showCustom:"};

});

return actions;

}

-(BOOL)onTapCell:(NIMKitEvent *)event

{

BOOL handle =[superonTapCell:event];

NSString *eventName = event.eventName;

if ([eventNameisEqualToString:NIMKitEventNameTapAudio])

{

//音频

[self.interactormediaAudioPressed:event.messageModel];

handle = YES;

}

elseif([eventNameisEqualToString:NIMKitEventNameTapContent]){

BOOL handle =NO;

NIMMessage *message = event.messageModel.message;

NSDictionary *actions = [selfcellActions];

NSString *value = actions[@(message.messageType)];

if (value) {

SEL selector =NSSelectorFromString(value);

NSLog(@"value ---- %@,%d",value,(selector && [selfrespondsToSelector:selector]));

if (selector && [selfrespondsToSelector:selector]) {

SuppressPerformSelectorLeakWarning([self performSelector:selector withObject:message]);

handle = YES;

}

}

}

elseif([eventNameisEqualToString:NIMKitEventNameTapLabelLink])

{

NSString *link = event.data;

[self.viewmakeToast:[NSStringstringWithFormat:@"tap link : %@",link]

duration:2

position:CSToastPositionCenter];

handle = YES;

}elseif ([eventName isEqualToString:SendCustomWithGoodsClick]){

        //自定义商品注入

NIMCustomObject * customObject =(NIMCustomObject *)event.messageModel.message.messageObject;
        id attachment =customObject.attachment;
        NSString * goodsId =[attachment goodsAttaId];
        //自定义商品注入
        JKNewGoodsDetailVC * goodVC =[[JKNewGoodsDetailVC alloc]init];
        //添加商品id
        goodVC.goodsId = [goodsId intValue];
        [self.navigationController pushViewController:goodVC animated:YES];

        handle =YES;

    }

//    if (!handle) {

//        NSAssert(0, @"invalid event ----哈哈哈!垃圾...崩溃了");

//    }

return handle;

}

到此为止,我们的代码算是写完了!运行我们的模拟器!效果如下:
代码还不太完整.不过整体步骤和思路很清晰了.大家可以做个参考.如果有地方不明白.可以私聊我咨询.或者加入One Team:234713941 技术交流群

集成网易云信实现自定义消息(类似淘宝聊天发送商品信息)相关推荐

  1. Android 类似淘宝的多商品订单评价

    前言 近期在做一个商城类项目,需要实现对一个订单里的多个商品分别评价的功能(类似于淘宝的评价),花费了一点时间把效果做了出来,并在这里分享出来也权当做了记录,图个日后使用方便. 效果图 设计原理 设计 ...

  2. 使用Python获取国际版淘宝AliExpress的商品信息

    AliExpress全球速卖通,又称国际版淘宝,是一款面向海外的购物网站. 之前有获取过Amazon的信息,偶然间发现了这个网站,所以今天看看这个国际版淘宝上面有没有我想要的东西. 不知道这上面能不能 ...

  3. 淘宝开放平台Api的小试牛刀(获取淘宝客推广商品信息)

    最近在学习淘宝开放平台,属于初学小菜鸟,有一点点小成就给大家分享一下. 要做这个东西,第一步你必须注册为淘宝开发方平台的开发人员.地址:http://open.taobao.com/index.htm ...

  4. 如何抓取淘宝上的商品信息和详情页信息

    来源于微擎里的人人商城里的插件, 采用接口: 第一个接口未获取基本信息接口,id为淘宝商品ID http://hws.m.taobao.com/cache/wdetail/5.0/?id=' .$id ...

  5. python爬虫 爬取淘宝搜索页面商品信息数据

    主要使用的库: requests:爬虫请求并获取源码 re:使用正则表达式提取数据 json:使用JSON提取数据 pandas:使用pandans存储数据 以下是源代码: #!coding=utf- ...

  6. 【爬虫】爬取淘宝网的商品信息

    文章目录 一.思路 1.根据关键词搜索 2.数据提取 3.数据保存 二.结果 三.源代码 一.思路 首先,从命令行参数列表中,提取出要爬取商品的关键词,根据关键词拼接URL,请求相应的URL,然后利用 ...

  7. 网易云信-新增自定义消息(iOS版)

    https://www.jianshu.com/p/2bfb1c4e9f21 前言 公司业务需要,PC端,移动端都用到了第三方 网易云信 IM来实现在线客服咨询. 在这当中难免遇到一些需求是网易云信没 ...

  8. nginx简介(轻量级开源高并发web服务器:大陆使用者百度、京东、新浪、网易、腾讯、淘宝等)(并发量5w)(一般网站apache够用了,而且稳定)...

    nginx简介(轻量级开源高并发web服务器:大陆使用者百度.京东.新浪.网易.腾讯.淘宝等)(并发量5w)(一般网站apache够用了,而且稳定) 一.总结 1.在连接高并发的情况下,Nginx是A ...

  9. 写一个类似淘宝的ios app需要用到哪些技术?

    写一个类似淘宝的ios app需要用到哪些技术? 让我想起了有人私信我,说不缺钱,做个类似知乎的东西,包括加运营,需要多少钱. 扯淡结束,正好最近看了一点这方面的东西,也许对题主来说有点帮助. 手机淘 ...

最新文章

  1. JavaScript有哪三部分组成?
  2. php设计模式的六大原则(六):迪米特法则
  3. 检查Red Hat JBoss BRMS部署架构的规则和事件(第二部分)
  4. Bugku杂项-convert
  5. android按钮控件常见问题,Android的基本控件和Activity的应用总结
  6. html 手机分辨率,移动端各种分辨率手机屏幕----适配方法集锦
  7. Windows Phone 8.1 多媒体(3):音乐
  8. Autofs自动挂在实现
  9. html浮动之后怎么隐藏,div浮动之后排在一行,在把浮动去掉,把div用display设置成inline-block之后就不能排在一行了。...
  10. Subtext--为skin准备相关文件加载
  11. vue-tv-focusable
  12. axio并发请求示例
  13. oss图片无法在网站中显示
  14. 半自动安装jieba分词库
  15. 【转】26张PPT让你告别拖延症
  16. [刷题]leetcode\283_移动零
  17. stack overflow -最好的编程技术论坛!
  18. Win10系统电脑关机时提示“内存不能为read”的解决方法
  19. 编译kernel外部模块
  20. 方舟端游进服务器无限闪退,【求助】方舟一进服务器 过一会儿 闪退 弹白框求解...

热门文章

  1. 手机访问网站提示拒绝访问_保持访问者参与和访问您网站的6条提示
  2. pytorch训练MNIST
  3. 分享几张塞尔达荒野之息精彩壁纸
  4. 【四川农信】主力军银行里的智慧运维力量-嘉为案例
  5. 李开复给学生第七封信:21世纪最需要7种人才
  6. 关于帧间距 IFG技术的讨论
  7. linux安装软件系列之npm安装
  8. ieda 热部署_Idea配置热部署的详细教程
  9. Python \033[95m print打印设置字体颜色
  10. sml完整形式_DVD的完整形式是什么?