我做了一个成语接龙的小程序

我是一名安卓程序员,以前没有接触过前端开发,直到有幸接手了公司的小程序项目。小程序学起来还是很快的,对于有编程经验的人,看着示例代码,对照着官方文档,几天就能上手了。

自从接触了小程序,一直想做一个自己的东西,要是每天有点人用就更好了。

有一天和我家宝宝玩成语接龙,突然想到,我可以做一个成语接龙的小程序啊!

产品

琢磨了两天,大概想做成这样:

  • 接龙可以有「所有人可参与」、「指定群成员参与」等类型

  • 不校验是否是成语,否则就无法使用「印贼做父」了

  • 成语的读音,还是要校验一下的

  • 难免会有人乱填,所以每条成语可以赞,也可以踩

  • 在有一定数据量后可以增加排行榜

设计

想法有了,还有两件比较棘手的事:

  • 起个牛逼的名字

  • 求我家宝宝给我画设计图

我想过很多名字,「成语接龙吧」、「接下去」、「接吧」、「接一个」...

宝宝:low 爆了,叫「碰词」,碰也有接的意思,成语也是个词嘛

这么 6 的名字居然有人先想到了,于是最终决定用「碰词er」

随便放两张设计图,美如画啥的就不说了:

下面说一下在开发方面,几个我认为值得一提的地方。

获取用户信息

现在大部分的小程序都是一打开,就弹出用户信息授权框,有的甚至强制需要授权才可使用。我之前做的一个也是需要拿到 unionId 去登录才能使用的,为此我还写过一篇文章说明如何实现。

但显然,微信认为这是一个很不好的体验。在用户没有接触你的小程序之前,凭什么要信任你,把自己的用户信息暴露给你。

为了规范用户信息的获取,官方出了这篇文章:获取用户信息方案介绍(FAQ 里面有两个问题还是我提的)

刚好拿这个小程序来实践一下。

首先,明确什么情况下需要用到用户信息。这里需要用户信息显示在成语旁,所以在创建接龙或者发送成语之前,需要先获取到用户信息。如果你只是进来看看,是不需要你任何授权的,只有点击了创建接龙的按钮,或者发送成语的按钮,才会弹出授权提示框。

我是这样做的。没有用户信息时,设置 button 的 open-type 为 getUserInfo,点击会触发用户信息的获取。要是已经有用户信息了,则是一个普通的跳转按钮:

<view class="create-button">
  <button wx:if="{{hasUserInfo}}" class="button" bindtap="navigateToCreate">
    <image class="img" src="/images/icon_add.png" mode="aspectFit"/>
  </button>
  <button wx:else class="button" open-type="getUserInfo" bindgetuserinfo="getUserInfo">
    <image class="img" src="/images/icon_add.png" mode="aspectFit"/>
  </button>
</view>

当用户确定授权了,可以在 bindgetuserinfo 绑定的方法里,用 e.detail.userInfo 拿到用户信息。

但还有个问题,open-type="getUserInfo" 要到基础库 1.3.0 才能用,最好还是做一下低版本兼容处理。

群能力

目前,小程序已经支持获取到微信群的群 id 和显示群名。

当用户创建的接龙类型是指定群成员参与时,指定的群就是第一个转发到的群。而成员也只有通过这个群的分享进入小程序,才可参与接龙。下面说说这两种情况是如何获取到群 id 的。

在可分享的页面,调用 wx.showShareMenu() 显示转发按钮。添加 onShareAppMessage 方法,并在里面设置分享信息:

onShareAppMessage: function () {
  var that = this
  return {
    title: "一起来玩成语接龙!",
    path: 'pages/xxx/xxx?id=' + this.data.id,
    success(res) {
      that.getShareInfo(res.shareTickets[0])
    }
  }
}

在 getShareInfo 方法里,需要获取到分享信息,现在能获取到的只有群 id:

wx.getShareInfo({
  shareTicket: shareTicket,
  success(res) {
    // 解密获取到 openGId
  }
})

这里和 getUserInfo 一样,拿到的数据是加密的,需要将 res.encryptedData 和 res.iv 传给后台解密。加密方式和 userInfo 是一样的,所以可以用同一个接口解密。解密后的 openGId 就是我们要的群 id。

至于从微信群进入的情况,我们需要对 app.js 的 onLaunch 方法动手。在 onLaunch 方法里可以获取到一个场景值,它区分了各种进入小程序的场景,各种场景值说明可以在这里查到。其中可以看到:

当场景值为 1044 时,我们就可能获取到携带的 shareTicket:

onLaunch: function (ops) {
  if (ops != null && ops.scene == 1044) {
    this.globalData.shareTicket = ops.shareTicket
  }
}

之后再对这个 shareTicket 进行解密,获取 openGId,判断用户是否可参与。

聊天列表

从设计图可以看到,成语列表是置底的,类似微信聊天的效果。但列表都是默认置顶的,如何让它置底呢?

其实很简单,这里利用了 scroll-view 组件的 scroll-into-view 属性:

注意这里有个细节,id 不能以数字开头,但我的 id 就是数字开头的怎么办?前面随便加个字母就好了:

<scroll-view class="scroll" scroll-y="true" scroll-into-view="x{{toView}}">
  <!-- ...... -->
</scroll-view>

item 的 id 前面也记得加个 x。

然后在获得页面数据 setData 之后,将列表定位到底部:

setTimeout(function () {
  that.setData({
    toView: list[list.length - 1].id
  })
}, 300)

这里的延时是不可少的,因为页面渲染需要点时间,不同性能的手机需要的时间还不一样。看过几台手机,300 毫秒应该是比较合适的。

如果要实现滑动到顶部加载更多的话,可以用上 bindscrolltoupper 这个属性:

获取更多后,将 toView 设置为新获取到的列表最后一项的 id。

浮动按钮

首页右下角的按钮美如画,但是它会造成一定的遮挡。

安卓里有一个叫 FloatActionButton 的控件,当列表滚动时,可以向下移动隐藏,我尝试在小程序里实现类似的效果。

我觉得遮挡其实只对列表最底部有影响,所以当列表滚到底部时隐藏就好了,发生滚动再显示。

在不使用 scroll-view 的情况下,页面触底会触发 onReachBottom 方法,滚动会触发 onPageScroll 方法,所以这个功能可以这样实现:

js

onReachBottom: function (event) {
  // 隐藏按钮,避免遮挡
  this.setData({
    showBtn: false
  })
},

onPageScroll: function (event) {
  // 显示创建按钮
  this.setData({
    showCreateBtn: true
  })
}

wxml

<view class="button {{showBtn?'show-button':'hide-button'}}"/>

wxss

.show-button {
  transform: translateY(0);
  transition: 0.3s;
}

.hide-button {
  transform: translateY(180rpx);
  transition: 0.3s;
}

是不是很简单,效果还不错:

但是这里面有两个坑:

  1. 在开发工具上没什么问题,但在真机上,列表到达底部触发 onReachBottom 之后,居然还会触发 onPageScroll。我的做法是在 onReachBottom 之后的三百毫秒内不显示按钮。

  2. 在列表高度不满屏幕高度时,向上滑动列表,也会触发 onReachBottom,但是不会触发 onPageScroll,导致隐藏后就不会再显示了。解决方法是,可以先判断列表是否可滚动,不可滚动的情况下不隐藏按钮。

总结

刚开始,在没有推广的情况下,在我身边的人都不愿意玩的情况下,每天会有一两百个新用户。在上次知晓程序推荐过后,现在居然每天有一两千个新用户!流量费都快给不起了,非常感谢大家的捧场。

最后,感谢我家宝宝做了这么好看的设计图。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,659评论 0 15
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,431评论 25 707
  • 阳光透进窗明几净的客厅里,整个屋子家具都摆放整整齐齐井然有序,地板也是纤尘不染,从这房间的整洁可看出女主人...
    Juliegirl阅读 283评论 0 1
  • 最好的爱情,是发现了更好的自己。 愿我们再遇见,都比现在过得好。 曾经有一个人,很喜欢。 是很单纯的那种喜欢,并不...
    王木木的一碗阅读 605评论 0 1