# 开发 \| 一个 Android 开发者的小程序开发之旅

- 作者：知晓程序
- 发布时间：2017-08-25 09:18
- 原文：https://www.ifanr.com/minapp/897420

![](https://s3.ifanr.com/wp-content/uploads/2017/07/minapp-dev-final-feature.jpg)

文 \| SouthernBox

我是一名 Android 开发程序员，以前没有接触过前端开发，直到接手了公司的小程序项目，才开始逐渐接触前端领域。

小程序学起来还是很快的。**对于有编程经验的人，看着示例代码，对照着官方文档，几天就能上手了。**

而且，自从接触了小程序，我也一直想做一个自己的东西。在机缘巧合之下，「碰词 er」的小程序就这样诞生了。

下面，我将在知晓程序（微信号 zxcx0101），与大家分享我的小程序开发的点滴。

关注「知晓程序」公众号，在微信后台回复「开发」，获取小程序开发技巧精选文章。

### 「碰词 er」的起源

有一天，和我家宝宝玩成语接龙，突然觉得这个东西挺有意思，也许可以做一个小程序。

有了这个想法，我就琢磨了两天，大概想做成这样：

- 接龙可以有「所有人可参与」、「指定群成员参与」等类型。
- 不校验所填的词是不是成语，否则就无法使用「印贼做父」了。
- 字词前后的读音，还是要校验一下的。
- 不校验成语，难免会有人乱填，所以每条成语可以赞，也可以踩。
- 在有一定数据量后，可以增加排行榜。

除此之外，还有两件比较棘手的事：给小程序起个名字，以及小程序的界面设计。

有关小程序的名字，我想过很多，像什么「成语接龙吧」、「接下去」、「接吧」、「接一个」……

这时候，我家宝宝说：「low 爆了，叫『碰词』，碰也有接的意思，成语也是个词嘛。」

当时一听，我立刻就去注册这个名字，然而，这种名字居然有人先想到了！最后，我决定用「碰词 er」这个名字。

有关于界面设计，随便放两张设计图。美如画啥的，就不说了：

![](https://s3.ifanr.com/wp-content/uploads/2017/08/dev-pengcier-1.jpg)

### 获取用户信息

现在大部分的小程序都是一打开，就弹出用户信息授权框，有的甚至强制需要授权才可使用。

我之前做的一个也是需要拿到 `unionId` 去登录才能使用的，为此我还写过一篇文章说明如何实现。

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

为了规范用户信息的获取，官方发布了一篇《获取用户信息方案介绍》的文章（FAQ 里面有两个问题还是我提的），里面详细地描述了获取用户信息的正确实践。

刚好，我也可以拿这个小程序来实践一下。

首先，**我们需要明确什么情况下需要用到用户信息。**

在这个小程序里，用户信息需要显示在发布的成语旁，所以在创建接龙或者发送成语之前，需要先获取到用户信息。

如果你只是进来看看，是不需要你任何授权的。**只有点击了创建接龙的按钮，或者发送成语的按钮，才会要求授权，弹出授权提示框。**

我是这样做的：没有用户信息时，设置 `button` 组件的 `open-type` 属性为 `getUserInfo`，点击会触发用户信息的获取。

如果小程序里已经有用户信息了，则是一个普通的跳转按钮。

判断逻辑并不复杂，使用 `WXML` 提供的 `wx:if` 特性，就可以做到。

```
<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` 的小程序卡片。

也就是说，**当场景值为 `1044` 时，我们就可能获取到携带的 `shareTicket`。**

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

之后，我们再对这个 `shareTicket` 进行解密，获取 `openGId`，判断用户是否可参与这次接龙。

### 接龙列表页面

从设计图可以看到，新的成语在成语接龙列表的底部，类似微信聊天中，新消息都在屏幕下方的效果。

但是，列表都是默认置顶的，用户进入一个接龙，很有可能需要划很久才能到最新一条接龙。这下该怎么办？

其实很简单，**利用 `scroll-view` 组件的 `scroll-into-view` 属性，就可以轻松定位到最新一条接龙。**

![](https://s3.ifanr.com/wp-content/uploads/2017/08/minapp-dev-pengcier-2.png)

需要注意的是，**ID 值不能以数字开头**。但我的元素 ID 就是数字开头的怎么办？

**那就在原来的元素 ID 前面，随便加个字母就好。**

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

切记，`item` 的 ID 属性前，也要记得加相同的字母。

在获得页面数据并且 `setData` 之后，我们就可以将列表定位到底部：

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

在这里，我设定了一个延时。这是不可少的，**因为页面渲染需要点时间，页面载入就立刻加载数据的体验并不好。**

而且，不同类型、品牌的手机，所需要的渲染时间还不一样。看过几台手机，300 毫秒是比较合适的。

如果要实现滑动到顶部，进行「加载更多」的操作，可以用上 `bindscrolltoupper` 这个属性。当屏幕滑动到顶部时，这个属性所绑定的事件就会被触发。

获取更多数据之后，将 `toView` 设置为新获取到的列表最后一项的 ID。

### 浮动按钮

首页右下角的按钮很漂亮，但是它会对页面造成一定的遮挡。

在 Android 开发里，有一个叫 `FloatActionButton` 的控件，**当列表滚动时，这个控件可以向下移动隐藏**。我尝试在小程序里实现类似的效果。

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

我们都知道，在不使用 `scroll-view` 的情况下，页面触底会触发 `onReachBottom` 方法，滚动会触发 `onPageScroll` 方法。

所以，这个功能可以这样实现：

```
onReachBottom: function (event) {
  // 隐藏按钮，避免遮挡
  this.setData({
    showBtn: false
  })
},
onPageScroll: function (event) {
  // 显示创建按钮
  this.setData({
    showCreateBtn: true
  })
}
```

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

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

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

是不是很简单呢？最后的效果还不错：

![](https://s3.ifanr.com/wp-content/uploads/2017/08/minapp-dev-pengcier-3.gif)

但是这里面有两个坑。

首先，这个实现效果在开发工具上没什么问题。**但在真机上，列表到达底部触发 `onReachBottom` 之后，居然还会同时触发 `onPageScroll`。**

我的做法是，在 `onReachBottom` 之后的三百毫秒内，不显示按钮。

另外，**在列表高度不满屏幕高度时，向上滑动列表，也会触发 `onReachBottom`，但是不会触发 `onPageScroll`**。

这就会导致列表项目过少时，会意外隐藏按钮，而且就不会再显示了。

我的解决方法是，先判断列表是否可被滚动，不可滚动的情况下不隐藏按钮。

### 最后的话

刚开始，在没有推广、我身边的人都不愿意玩的情况下，每天都会有一两百个新用户。

在上次知晓程序推荐过后，现在居然每天有一两千个新用户！流量费都快给不起了，非常感谢大家的捧场。

最后，还是要感谢我家宝宝做了这么好看的设计图。

![](https://s3.ifanr.com/wp-content/uploads/2017/08/minapp-dev-pengcier-4.png)

「碰词 er」小程序使用链接  
<https://minapp.com/miniapp/3952/>

**关注「知晓程序」公众号，在微信后台回复「开发」，获取小程序开发技巧精选文章。**

![zxcx&#95;0208](https://s3.ifanr.com/wp-content/uploads/2017/02/zxcx_0208.png)
