1.9 电影

1、小程序的tab选项卡

1.1 配置项目tab选项卡

app.json
"tabBar": {
    "borderStyle": "white",
    "selectedColor": "#4A6141",
    "color": "#333",
    "backgroundColor": "#fff",
    "position": "bottom",
    "list": [
      {
        "pagePath": "pages/post/post",
        "text": "文字",
        "iconPath": "images/icon/wx_app_news.png",
        "selectedIconPath": "images/icon/wx_app_news@HL.png"
      },
      {
        "pagePath": "pages/movie/movie",
        "text": "光影",
        "iconPath": "images/icon/wx_app_movie.png",
        "selectedIconPath": "images/icon/wx_app_movie@HL.png"
      }
    ]
  }
image.png
tabBar

如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。

image.png
image.png
image.png

image.png
image.png

1.2 使用wx.switchTab方法导航

welcome.js
image.png
image.png

image.png

2、电影页面介绍

电影模块功能总共有以下几个展示模块:
1)电影首页展示正在热映、即将上映和豆瓣top250三种类型的电影
2)每种电影只展示最前面3部
3)每种电影有一个“更多”按钮,点击将打开一个新页面,展示该类型下所有的电影
4)支持电影搜索功能
5)点击任意一部电影都将打开电影详情页面

3、编写豆瓣星星评分组件:stars-tpl模板

3.1 编写stars模板的骨架

stars-tpl.wxml
<template name="starsTpl">
  <view class="stars-container">
    <view class="stars">
      <block wx:for="{{stars}}" wx:for-item="i">
        <image wx:if="{{i===1}}" src="/images/icon/wx_app_star.png"></image>
        <image wx:elif="{{i===0.5}}" src="/images/icon/wx_app_star@half.png"></image>
        <image wx:else="{{i===0}}" src="/images/icon/wx_app_star@none.png"></image>
      </block>
    </view>
    <text class="star-score">{{score}}</text>
  </view>
</template>

3.2 编写stars模板的样式

stars-tpl.wxss
.stars-container {
  display: flex;
  flex-direction: row;
}

.stars {
  display: flex;
  flex-direction: row;
  height: 17rpx;
  margin-right: 24rpx;
  margin-top: 6rpx;
}

.stars image {
  padding-left: 3rpx;
  height: 17rpx;
  width: 17rpx;
}

.star-score{
   color: #4A6141;
}

4、编写movie-tpl模板

4.1 movie-tpl模板的骨架代码

movie-tpl.wxml
<import src="../stars/stars-tpl.wxml" />
<template name="movieTpl">
    <view class="movie-container" catchtap="onMovieTap" data-movie-id="{{movieId}}">
        <image class="movie-img" src="{{coverageUrl}}"></image>
        <text class="movie-title">{{title}}</text>
        <template is="starsTpl" data="{{stars:stars, score: average}}" />
    </view>
</template>

4.2 编写 movie-tpl模板的样式

movie-tpl.wxss
@import "../stars/stars-tpl.wxss";

.movie-container {
  display: flex;
  flex-direction: column;
  padding: 0 22rpx;
}

.movie-img {
  width: 200rpx;
  height: 270rpx;
  padding-bottom: 20rpx;
}

.movie-title{
    margin-bottom: 16rpx;
    font-size: 24rpx;
}

5、编写movie-list-tpl模板

5.1 movie-list-tpl模板的骨架代码

movie-list-tpl.wxml
<import src="../single-movie/movie-tpl.wxml" />
<template name="movieListTpl">
  <view class="movie-list-container">
    <view class="inner-container">
      <view class="movie-head">
        <text class="slogan">{{categoryTitle}}</text>
        <view catchtap="onMoreTap" class="more" data-category="{{categoryTitle}}">
          <text class="more-text">更多</text>
          <image class="more-img" src="/images/icon/wx_app_arrow_right.png"></image>
        </view>
      </view>
      <view class="movies-container">
      <block wx:for="{{movies}}" wx:for-item="movie">
        <template is="movieTpl" data="{{...movie}}"/>
      </block>
      </view>
    </view>
  </view>
</template>

5.2 编写movie-list-tpl 的样式

movie-list-tpl.wxss
@import "../single-movie/movie-tpl.wxss";

.movie-list-container {
  background-color: #fff;
  display: flex;
  flex-direction: column;
}

.inner-container{
    margin: 0  auto 20rpx;
}

.movie-head {
  padding: 30rpx 20rpx 22rpx;
}

.slogan {
  font-size: 24rpx;
}

.more {
  float: right;
}

.more-text {
  vertical-align: middle;
  margin-right: 10rpx;
  color: #4A6141;
}

.more-img {
  width: 9rpx;
  height: 16rpx;
  vertical-align: middle;
}

.movies-container{
    display:flex;
    flex-direction: row;
}

6、电影首页的骨架与样式

6.1 编写电影首页骨架代码

movie.wxml
<import src="movie-list/movie-list-tpl.wxml" />

<view class="container" >
  <view class="movies-template">
    <template is="movieListTpl" data="{{...inTheaters}}" />
  </view>
  <view class="movies-template">
    <template is="movieListTpl" data="{{...comingSoon}}" />
  </view>
  <view class="movies-template">
    <template is="movieListTpl" data="{{...top250}}"/>
  </view>
</view>

6.2 编写电影首页的样式

movie.wxss
@import "movie-list/movie-list-tpl.wxss";

.container {
  background-color: #f2f2f2;
}

.movies-template {
  margin-bottom: 30rpx;
}

7、豆瓣电影API分析

豆瓣API权限有3种:
1)公开
2)高级
3)商务

在项目中主要用到了如下几个豆瓣电影API:
1)获取正在热映的电影
2)获取即将上映的电影
3)获取豆瓣top250电影
4)电影搜索
5)获取电影条目信息

8、电影首页的js编写

8.1 豆瓣API的基地址

app.js
image.png
如果第三方是使用了https的,需要去小程序的后台配置
image.png

8.2 编写movie页面的Page方法

movie.js
var app = getApp();

Page({

  /**
   * 页面的初始数据
   */
  data: {
    inTheaters:{},
    comingSoon:{},
    top250:{}
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var inTheatersUrl = app.globalData.doubanBase + "/v2/movie/in_theaters"+"?start=0&count=3";
    var comingSoonUrl = app.globalData.doubanBase + "/v2/movie/coming_soon" + "?start=0&count=3";
    var top250Url = app.globalData.doubanBase + "/v2/movie/top250" + "?start=0&count=3";

    console.log("inTheatersUrl====" + inTheatersUrl);
    console.log("comingSoonUrl====" + comingSoonUrl);
    console.log("top250Url======" + top250Url);

    this.getMovieListData(inTheatersUrl,"inTheaters","正在热映");
    this.getMovieListData(comingSoonUrl,"comingSoon","即将上映");
    this.getMovieListData(top250Url,"top250","豆瓣Top250");
  },

  }

})
豆瓣API的地址

https://developers.douban.com/wiki/?title=movie_v2#top250

9、wx.request发送http/https请求

9.1 编写getMovieListData方法

movie.js
getMovieListData:function(url,settedKey,categoryTitle){
    var that = this;
    wx.request({
      url: url,
      method:"GET",
      header:{
        "Content-type":"json"
      },
      success:function(res){
        // that.processDoubanData(res.data, settedKey, categoryTitle);
        console.log(res.data);
      },
      fail:function(error){
        console.log(error);
      }
    })
  }
image.png

image.png

10、设置wx.request的超时时间

10.1 设置请求的超时时间

app.json
  "networkTimeout":{
    "request":20000,
    "connectSocket":20000,
    "uploadFile":20000,
    "downloadFile":20000
  }

11、处理返回的电影数据

11.1 处理豆瓣电影数据

movie.js
processDoubanData:function(moviesDouban,settedKey,categoryTitle){
    var movies = [];
    //for中的代码将所有豆瓣电影数据转化成我们需要的格式
    for(var idx in moviesDouban.subjects){
      var subject = moviesDouban.subjects[idx];
      var title = subject.title;
      if(title.length >= 6){
        //电影标题只取前6个字符
        title = title.substring(0,6)+"...";
      }

      var temp = {
        stars:util.convertToStarsArray(subject.rating.stars),
        title:title,
        average:subject.rating.average,
        coverageUrl:subject.images.large,
        movieId:subject.id
      }
      movies.push(temp);
    }
    var readyData = {};
    readyData[settedKey] = {
      categoryTitle: categoryTitle,
      movies: movies
    }
    this.setData(readyData);
  }

11.2 评分的格式转化函数

util.js
//将50、35、00等形式转化成【1,1,1,1,1】的形式
function convertToStarsArray(stars){
  var num = stars/10;
  var array = [];
  for(var i = 1;i<=5;i++){
    if(i <= num){
      array.push(1);
    }else{
      if((i-num) == 0.5){
        array.push(0.5);
      }else{
        array.push(0);
      }
    }
  }
  return array;
}

11.3 输出convertToStarsArray函数

util.js
image.png

11.4 引用util模块

movies.js
image.png

12、绑定处理后的电影数据

image.png

这是一种动态设置数据绑定key的方法。由于我们并不知道当前处理的数据是哪一种电影类型(inTheaters、comingSoon、top250),因此将当前所处理的电影数据类型通过settedKey一路传递到processDoubanData方法中,并通过readyData[settedKey]生成一个包含settedKey的JavaScript对象

1)假设当前处理的数据是inTheaters类型,那么以上代码在最终调用this.setData(readyData)时相当于以下形式:

  this.setData({
    inTheaters:{
      categoryTitle:"正在热映,
      movies:movies"
    }
  })

2)假设当前处理的数据是comingSoon类型,那么以上代码在最终调用this.setData(readyData)时相当于以下形式:

  this.setData({
    comingSoon:{
      categoryTitle:"即将上映,
      movies:movies"
    }
  })

数据绑定后的效果如下所示:


image.png

13、http 和 https 在小程序中使用说明

为了保证数据的安全性,小程序中强制要求使用https,并且访问的https地址必须在小程序的后台账号中被加入到可信域名中。


image.png
因此真机上有俩个限制条件:

1)不允许使用http请求来获取数据的
2)不允许访问未在可信域名列表中配置https地址

客户端开发工具有俩种方法可以不遵循上面的规则:

1)创建项目时选取的是无appid
2)创建项目时选取的是有appid,选择不校验https的功能


image.png
image.png

14、跳转到更多电影页面

image.png

14.1 添加more-movie页面的页面路径

app.json
image.png

image.png

14.2 编写onMoreTap方法

movie.js
  onMoreTap:function(event){
    var category = event.currentTarget.dataset.category;
    wx.navigateTo({
      url: '/pages/movie/more-movie/more-movie?category='+category,
    })
  }
image.png

可能会觉得奇怪,为什么电影模板上面的点击事件要在电影页面上面上实现?
因为小程序只是实现了模板化,而没有实现组件化,模板是不具备运行js代码能力的。

15、编写movie-grid-tpl模板

image.png

15.1 movie-grid-tpl模板骨架

movie-grid-tpl.wxml
<import src="../single-movie/movie-tpl.wxml" />
<template name="movieGridTpl">
   <view class='grid-container'>
     <block wx:for="{{movies}}" wx:for-item="movie">
       <view class='single-view-container'>
        <template is="movieTpl" data="{{...movie}}"/>
      </view> 
    </block> 
  </view> 
</template>

15.2 movie-grid-tpl模板样式

movie-grid-tpl.wxss
@import "../single-movie/movie-tpl.wxss";

.single-view-container{
  float: left;
  margin-bottom: 40rpx;
}

.grid-container{
  height: 1300rpx;
  margin:40rpx 0 40rpx 6rpx;
}
image.png

16、编写“更多电影”页面

16.1 more-movie页面的骨架

more-movie.wxml
<import src="../movie-grid/movie-grid-tpl.wxml" />
<template is="movieGridTpl" data="{{movies}}" />

16.2 more-movie页面的样式

more-movie.wxss
@import "../movie-grid/movie-grid-tpl.wxss"

16.3 编写more-movie的js代码

more-movie.js
var app = getApp()
var util = require("../../../util/util.js")
Page({

  /**
   * 页面的初始数据
   */
  data: {
    movies:[]
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var category = options.category;
    var dataUrl = "";
    switch(category){
      case "正在热映":
        dataUrl = app.globalData.doubanBase + "/v2/movie/in_theaters";
      break;
      case "即将上映":
        dataUrl = app.globalData.doubanBase + "/v2/movie/coming_soon";
        break;
      case "豆瓣Top250":
        dataUrl = app.globalData.doubanBase + "/v2/movie/top250";
        break;
    }
    util.http(dataUrl,this.processDoubanData)
  },

  processDoubanData: function (moviesDouban) {
    console.log("moviesDouban===========" + moviesDouban);
    var movies = [];
    //for中的代码将所有豆瓣电影数据转化成我们需要的格式
    for (var idx in moviesDouban.subjects) {
      var subject = moviesDouban.subjects[idx];
      var title = subject.title;
      if (title.length >= 6) {
        //电影标题只取前6个字符
        title = title.substring(0, 6) + "...";
      }

      var temp = {
        stars: util.convertToStarsArray(subject.rating.stars),
        title: title,
        average: subject.rating.average,
        coverageUrl: subject.images.large,
        movieId: subject.id
      }
      movies.push(temp);
    }
   
    this.setData({
      movies: movies
    });
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
  
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
  
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
  
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
  
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
  
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
  
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
  
  }
})

16.4 编写util.http方法

封装网络访问方法,供给全局调用,以后修改只需要修改一个地方

util.js
function http(url,callBack){
  wx.request({
    url: url,
    method:"GET",
    header:{
      "content-type":"json",
    },
    success:function(res){
      callBack(res.data);
    },
    fail:function(error){
      console.log(error)
    }
  })
}

16.5 暴露.http方法

util.js
image.png
image.png
image.png

17、实现页面下拉刷新的“三部曲”

实现一个页面下拉刷新操作需要分为3不=步:

  • 在页面的json文件中配置enablePullDownRefresh选项,打开下拉刷新开关
  • 在页面的js文件中编写onPullDownRefresh函数,完成自己的下拉刷新逻辑
  • 编写完下拉刷新逻辑代码后,主动调用wx.stopPullDownRefresh函数停止当前页面的下拉刷新

17.1 配置下拉刷新开关

more-movie.json
image.png

17.2 onPullDownRefresh函数

more-movie.js
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    var refreshUrl = this.data.requestUrl + "?star=0&count=20";
    util.http(refreshUrl,this.processDoubanData);
  },

17.3 保存当前访问的豆瓣API地址

more-movie.js
image.png

17.4 结束下拉刷新状态

more-movie.js
image.png

18、在模拟器中可以执行下拉刷新但在真机中无法执行下拉刷新的常见错误

image.png

19、json中的backgroundColor配置的是哪里的颜色

其实backgroundColor配置的是下图所示的位置


image.png
image.png
image.png

19.1 配置全局窗口颜色

app.json
image.png

19.2 配置welcome页面的窗口颜色

welcome.json
image.png

20、实现上滑加载更多数据

20.1 实现onReachBottom函数

more-movie.js
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    var refreshUrl = this.data.requestUrl + "?star=0&count=20";

    //刷新页面后将页面所有初始化参数恢复到初始值
    this.data.movies = [];
    util.http(refreshUrl,this.processDoubanData);
  },

20.2 合并movies数组

more-movie.js
processDoubanData: function (moviesDouban) {
    console.log("moviesDouban===========" + moviesDouban);
    var movies = [];
    //for中的代码将所有豆瓣电影数据转化成我们需要的格式
    for (var idx in moviesDouban.subjects) {
      var subject = moviesDouban.subjects[idx];
      var title = subject.title;
      if (title.length >= 6) {
        //电影标题只取前6个字符
        title = title.substring(0, 6) + "...";
      }

      var temp = {
        stars: util.convertToStarsArray(subject.rating.stars),
        title: title,
        average: subject.rating.average,
        coverageUrl: subject.images.large,
        movieId: subject.id
      }
      movies.push(temp);
    }

    var totalMovies = [];
    totalMovies = this.data.movies.concat(movies);
   
    this.setData({
      movies: totalMovies
    });
    wx.stopPullDownRefresh();
  },

20.3 修改onPullDownRefresh函数

more-movie.js
image.png

然后就可以看到可以上拉加载更多数据了


image.png

21、动态设置导航栏loading图标

之前有使用过wx.showToast提示,wx.showToast在页面的中间位置显示一个模态或者非模态的提示框。
对于loading状态提醒,用这种置于页面中心位置的浸入式提醒体验不好,小程序提供了一个非浸入式的方法 wx.showNavigationBarLoading()


image.png

21.1 onLoad函数中显示loading

more-movie.js
image.png

21.2 加载更多时显示loading

more-movie.js
image.png

21.3 加载完成后隐藏loading

more-movie.js
image.png

21.4 在onReady中设置loading状态

more-movie.js
image.png

22、电影搜索

效果图如下:


image.png

22.1 加入电影搜索骨架代码

movie.wxml
<import src="movie-list/movie-list-tpl.wxml" />
<import src="movie-grid/movie-grid-tpl.wxml" />

<view class="search">
  <icon type="search" class="search-img" size="13" color="#405f80"></icon>
  <input type="text" placeholder="乘风破浪、西游伏妖篇" 
  placeholder-class="placeholder" bindfocus="onBindFocus" value="{{inputValue}}"
  bindconfirm="onBindConfirm"/>
  <image wx:if="{{searchPanelShow}}" src="/images/icon/wx_app_xx.png" class="xx-img" catchtap="onCancelImgTap"></image>
</view>

<view class="container" wx:if="{{containerShow}}">
  <view class="movies-template">
    <template is="movieListTpl" data="{{...inTheaters}}" />
  </view>
  <view class="movies-template">
    <template is="movieListTpl" data="{{...comingSoon}}" />
  </view>
  <view class="movies-template">
    <template is="movieListTpl" data="{{...top250}}"/>
  </view>
</view>

<view class="search-panel" wx:if="{{searchPanelShow}}">
    <template is="movieGridTpl" data="{{...searchResult}}"/>
</view>

22.2 添加电影搜索样式

movie.wxss
@import "movie-list/movie-list-tpl.wxss";
@import "movie-grid/movie-grid-tpl.wxss";

.container {
  background-color: #f2f2f2;
}

.movies-template {
  margin-bottom: 30rpx;
}

.search {
  background-color: #f2f2f2;
  height: 80rpx;
  width: 100%;
  display: flex;
  flex-direction: row;
}

.search-img {
  margin: auto 0 auto 20rpx;
}

.search input {
  height: 100%;
  width: 600rpx;
  margin-left: 20px;
  font-size: 28rpx;
}

.placeholder {
  font-size: 14px;
  color: #d1d1d1;
  margin-left: 20rpx;
}

.search-panel{
    position:absolute;
    top:80rpx;
}

.xx-img{
    height: 30rpx;
    width: 30rpx;
    margin:auto 0 auto 10rpx;
}

22.3 设置默认的显示与隐藏状态

movie.js
image.png

22.4 切换面板

movie.js
  //切换面板
  onBindFocus:function(event){
    this.setData({
      containerShow:false,
      searchPanelShow:true
    })
  },

22.5 编写隐藏搜索面板代码

movie.js
//编写隐藏搜索面板代码
  onCancelImgTap:function(event){
    this.setData({
      containerShow: true,
      searchPanelShow: false,
      searchResult:{},
      inputValue:""
    })
  },

22.6 响应搜索事件

movie.js
//响应搜索事件
  onBindConfirm:function(event){
    var keyWord = event.detail.value;
    var searchUrl = app.globalData.doubanBase+"/v2/movie/search?q="+keyWord;
    this.getMovieListData(searchUrl,"searchResult","");
  }

image.png

image.png

image.png

23、电影详情页面

电影详情页面的入口:任何一个显示电影封面的地方都可以点击进入详情页面

因为电影封面我们是用模板是封装使用的,因此点击事件只需要写在到这个模板的地方

23.1 注册并且新建movie-detail页面

app.json
image.png

23.2 新建onMovieTap函数

movie.js
//跳转到详情页面
  onMovieTap:function(event){
    var movieId = event.currentTarget.dataset.movieId;
    wx.navigateTo({
      url: 'movie-detail/movie-detail?id='+movieId,
    })
  }

23.3 新建onMovieTap函数

more-movie.js
 //跳转到详情页面
  onMovieTap: function (event) {
    var movieId = event.currentTarget.dataset.movieId;
    wx.navigateTo({
      url: '/pages/movie/movie-detail/movie-detail?id=' + movieId,
    })
  }

24、电影详情页面的骨架和样式

24.1 电影详情页面的骨架和样式

more-detail.wxml
<import src="../stars/stars-tpl.wxml" />
<view class="container">
  <image class="head-img" src="{{movie.movieImg}}" mode="aspectFill" />
  <view class="head-img-hover">
    <text class="main-title">{{movie.title}}</text>
    <text class="sub-title">{{movie.country + " · "+movie.year}}</text>
    <view class="like">
      <text class="highlight-font">
        {{movie.wishCount}}
      </text>
      <text class="plain-font">
        人喜欢
      </text>
      <text class="highlight-font">
        {{movie.commentCount}}
      </text>
      <text class="plain-font">
        条评论
      </text>
    </view>
  </view>
  <image class="movie-img" src="{{movie.movieImg}}" data-src="{{movie.movieImg}}" catchtap="viewMoviePostImg"/>
  <view class="summary">
    <view class="original-title">
      <text>{{movie.originalTitle}}</text>
    </view>
    <view class="flex-row">
      <text class="mark">评分</text>
      <template is="starsTpl" data="{{stars:movie.stars, score:movie.score}}" />
    </view>
    <view class="flex-row">
      <text class="mark">导演</text>
      <text>{{movie.director.name}}</text>
    </view>
    <view class="flex-row">
      <text class="mark">影人</text>
      <text>{{movie.casts}}</text>
    </view>
    <view class="flex-row">
      <text class="mark">类型</text>
      <text>{{movie.generes}}</text>
    </view>
  </view>
  <view class="hr"></view>
  <view class="synopsis">
    <text class="synopsis-font">剧情简介</text>
    <text class="summary-content">{{movie.summary}}</text>
  </view>
  <view class="hr"></view>
  <view class="cast">
    <text class="cast-font"> 影人</text>
    <scroll-view class="cast-imgs" scroll-x="true" style="width:100%">
      <block wx:for="{{movie.castsInfo}}" wx:for-item="item">
        <view class="cast-container">
          <image class="cast-img" src="{{item.img}}"></image>
          <text class="cast-name">{{item.name}}</text>
        </view>
      </block>
    </scroll-view>
  </view>
</view>


24.2 电影详情页面的骨架和样式

more-detail.wxss
@import "../stars/stars-tpl.wxss";

.container{
    display:flex;
    flex-direction: column;
}

.head-img{
    width:100%;
    height: 320rpx;
    -webkit-filter:blur(20px);
}

.head-img-hover{
    width: 100%;
    height: 320rpx;
    position:absolute;
    top:0;
    left:0;
    display:flex;
    flex-direction: column;
}

.main-title{
    font-size: 19px;
    color:#fff;
    font-weight:bold;
    margin-top: 50rpx;
    margin-left: 40rpx;
    letter-spacing: 2px;
}

.sub-title{
    font-size: 28rpx;
    color:#fff;
    margin-left: 40rpx;
    margin-top: 30rpx;
}

.like{
    display:flex;
    flex-direction: row;
    margin-top: 30rpx;
    margin-left: 40rpx;
}

.highlight-font{
    color: #f21146;
    font-size:22rpx;
    margin-right: 10rpx;
}

.plain-font{
    color: #666;
    font-size:22rpx;
    margin-right: 30rpx;
}


.movie-img{
    height:238rpx;
    width: 175rpx;
    position: absolute;
    top:160rpx;
    right: 30rpx;
}

.summary{
    margin-left:40rpx;
    margin-top: 40rpx;
    color: #777777;
}

.original-title{
    color: #1f3463;
    font-size: 24rpx;
    font-weight: bold;
    margin-bottom: 40rpx;
}

.flex-row{
    display:flex;
    flex-direction: row;
    margin-bottom: 10rpx;
}

.mark{
    margin-right: 30rpx;
    white-space:nowrap;
    color: #999999;
}

.hr{
    margin-top:45rpx;
    height:1px;
    width: 100%;
    background-color: #d9d9d9;
}

.synopsis{
    margin-left:40rpx;
    display:flex;
    flex-direction: column;
    margin-top: 50rpx;
}

.synopsis-font{
    color:#999;
}

.summary-content{
    margin-top: 20rpx;
    margin-right: 40rpx;
    line-height:40rpx;
    letter-spacing: 1px;
}

.cast{
    margin-left:40rpx;
    display:flex;
    flex-direction: column;
    margin-top:50rpx;
}

.cast-font{
    color: #999;
    margin-bottom: 40rpx;
}

.cast-container{
    display:inline-flex;
    flex-direction: column;
    margin-bottom: 50rpx;
    margin-right: 40rpx;
    width: 170rpx;
    text-align:center;
    white-space: normal;
}

.cast-imgs{
    white-space: nowrap;
}

.cast-img{
    width: 170rpx;
    height: 210rpx;
}
.cast-name{
    margin: 10rpx auto 0;
}

image.png
image.png

25、编写电影详情页面的业务逻辑代码

25.1 编写电影详情页面业务逻辑

movie-detail.wxml
var util = require("../../../util/util.js")

var app = getApp();
Page({

  /**
   * 页面的初始数据
   */
  data: {
    movie:{}
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    var movieId = options.id;
    var url = app.globalData.doubanBase + "/v2/movie/subject/" + movieId;
    console.log("url==============="+url);
    util.http(url,this.processDoubanData);
  },

  processDoubanData:function(data){
    if (!data) {
      return;
    }
    var director = {
      avatar: "",
      name: "",
      id: ""
    }
    if (data.directors[0] != null) {
      if (data.directors[0].avatars != null) {
        director.avatar = data.directors[0].avatars.large

      }
      director.name = data.directors[0].name;
      director.id = data.directors[0].id;
    }
    var movie = {
      movieImg: data.images ? data.images.large : "",
      country: data.countries[0],
      title: data.title,
      originalTitle: data.original_title,
      wishCount: data.wish_count,
      commentCount: data.comments_count,
      year: data.year,
      generes: data.genres.join("、"),
      stars: util.convertToStarsArray(data.rating.stars),
      score: data.rating.average,
      director: director,
      casts: util.convertToCastString(data.casts),
      castsInfo: util.convertToCastInfos(data.casts),
      summary: data.summary
    }
    this.setData({
      movie: movie
    });
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
  
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
  
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
  
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
  
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
  
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
  
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
  
  }
})

25.2 编写convertToCastString

util.js
//将数组转换为以 / 分隔的字符串
function convertToCastString(casts) {
  var castsjoin = "";
  for (var idx in casts) {
    castsjoin = castsjoin + casts[idx].name + " / ";
  }
  return castsjoin.substring(0, castsjoin.length - 2);
}

25.3 编写convertToCastInfos

util.js
function convertToCastInfos(casts) {
  var castsArray = []
  for (var idx in casts) {
    var cast = {
      img: casts[idx].avatars ? casts[idx].avatars.large : "",
      name: casts[idx].name
    }
    castsArray.push(cast);
  }
  return castsArray;
}

25.4 输出方法

util.js
image.png
image.png

image.png

26、预览电影海报

26.1 编写图片预览函数

movie-detail.js
  viewMoviePostImg:function(event){
    var src = event.currentTarget.dataset.src;
    wx.previewImage({
      current:src,
      urls:[src]
    })
  },
image.png

image.png

27、设置电影页面的导航栏标题

27.1 配置电影首页导航栏标题

image.png

image.png

27.2 保存当前电影类型

more-movie.js
image.png

27.3 动态设置导航栏标题

more-movie.js
image.png
image.png

27.4 动态设置导航栏标题

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

推荐阅读更多精彩内容