## 投票组件

### 版本历史

版本号 | 更新时间 | 更新描述
--- | --- | ---
1.0.1 | 2022.5.7 | 投票组件上线
1.2.4 | 2023.8.7 | 修复已知问题
1.2.6 | 2023.12.1 | 升级依赖Glide4.x版本
1.2.7 | 2024.2.2 | 修复已知问题

### 组件引入

注意：所有使用互动组件必须要引入basemodule库，最新版本见 互动组件对接文档

项目根目录build.gradle引入：

     repositories {     maven { url 'http://nexus-app.bokecc.com/repository/sdk-group/' } }

module的build.gradle引入：

     dependencies {     api ('com.bokecc:basemodule:x.x.x')     api ('com.bokecc.module:votemodule:x.x.x') }

Application的onCreate方法中，调用 `DWLiveEngine.init` 初始化dwlivesdk后，添加代码：

    VoteInteractSDK.getInstance().init(app);

### 1. 组件描述

投票组件是基于基础组件库扩展的投票组件服务，通过IM组件实现投票活动事件的实时推送，包括获取投票列表，获取投票详情、发送投票等功能，为业务方提供投票能力。投票组件包含管理器和基于管理器实现的UI界面，接入方可基于管理器对外API实现完全自定义UI的投票，也可直接集成组件SDK提供的UI。

### 2. 组件架构

#### 2.1 组件架构图

#### 2.2 核心对外API

IVoteManager内部唯一实现类为VoteManagerImpl

作用 | API
--- | ---
初始化 | init(BaseVoteListener listener, String userId, String roomId, String interactToken)
发送投票 | sendVote(String activityId, List optionIdList, IBaseCallBack
获取投票列表 | getVoteList(IBaseCallBack<List> callBack)
获取投票详情 | getVoteDetail(String activityId, IBaseCallBack callBack)
重连 | reConnect()
释放 | release()

API接口代码

    public interface IVoteManager {
        /**     * @param listener      监听     * @param userId        viewerId     * @param roomId        房间id     * @param interactToken token     */    void init(BaseVoteListener listener, String userId, String roomId, String interactToken);
        /**     * 投票     *     * @param activityId   id     * @param optionIdList 选择的id     * @param callBack     回调     */    void sendVote(String activityId, List<Integer> optionIdList, IBaseCallBack<Object> callBack);
        /**     * 投票结果列表     *     * @param callBack 回调     */    void getVoteList(IBaseCallBack<List<VoteResult>> callBack);
        /**     * 获取正在进行的投票     *     * @param callBack 回调     */    void getVoting(IBaseCallBack<VoteBean> callBack);
        /**     * 获取投票详情     *     * @param activityId 投票活动id     * @param callBack 回调     */    void getVoteDetail(String activityId, IBaseCallBack<VoteBean> callBack);
        /**     * 重连     */    void reConnect();
        /**     * 释放     */    void release();
    }

#### 2.3 数据参数定义

数据类参数说明

    public class VoteBean {
        /**     * 投票id     */    private String activityId;    /**     * 业务线     */    private String businessLine;    /**     * 客户id     */    private String accountId;    /**     * 房间id     */    private String roomId;
        /**     * 标题     */    private String title;    /**     * 截止时间     */    private String endTime;    /**     * 主题色:1.白色 2.绿色 3红色 4橙色 5蓝色     */    private int themeColor;    /**     * 显示banner     */    private int showBanner;    /**     * 投票形式 1.图文 2.文字     */    private int voteForm;    /**     * 选项类型 1.单选 2.多选     */    private int voteType;    /**     * 多选限制 0为不限制     */    private int voteLimit;    /**     * 显示结果 0 不显示 1显示     */    private int showResult;    /**     * 参加人数     */    private int voteCount;    /**     * 状态:  0未开始 1.投票中 2.已结束     */    private int status;    /**     * 选项     */    private List<VoteOptionsDTO> voteOptions;    /**     * banner图片地址     */    private String bannerUrl;}

### 3. 组件接入

#### 3.1 使用组件提供UI

投票ViewGroup为VoteMainLayout

1. 登录业务SDK（云直播等）

2. xml中添加VoteMainLayout

       <?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#eeeeee"    android:orientation="vertical">

           <com.bokecc.vote.ui.VoteMainLayout        android:id="@+id/vote_layout"        android:layout_width="match_parent"        android:layout_height="match_parent"/>
       </LinearLayout>

3. 设置VoteMainLayout的Listener

       voteLayout.setVoteMainListener(new IVoteMainListener() {                    @Override                    public void onVoteStart() {                        Toast.makeText(VoteTestActivity.this,"投票开始",Toast.LENGTH_SHORT).show();                    }
                           @Override                    public void onVoteEnd() {                        Toast.makeText(VoteTestActivity.this,"投票结束",Toast.LENGTH_SHORT).show();
                           }
                           @Override                    public void onCloseClick() {                      //投票面板关闭回调                        Toast.makeText(VoteTestActivity.this,"close",Toast.LENGTH_SHORT).show();
                           }                });

4. 初始化组件

   1. 获取token-初始化投票需要传递参数token，可以通过业务SDK（云直播等）提供的对外API获取token

   2. 获取正在进行活动-如果需要进入时就展示互动组件，需要调用业务SDK提供的正在进行中组件活动API获取正在进行的活动

   3. 初始化组件-使用前两步获取的信息初始化组件SDK

      代码示例（以云直播为例）：

       DWLive..getInstance().getInteractiveToken(new BaseCallback<String>() {                    @Override                    public void onError(String error) {
                           }
                           @Override                    public void onSuccess(String token) {                        //获取正在进行的互动                        DWLive.getInstance().getInteractiveOngoing(new BaseCallback<List<InteractionOngoing>>() {                            @Override                            public void onError(String error) {                                initVote(token,                                        loginInfo.getUserId(),                                        loginInfo.getRoomId(),                                        false,                                        ""                                );
                                   }
                                   @Override                            public void onSuccess(List<InteractionOngoing> interactionOngoings) {                                //是否正在进行                                boolean isOngoing = false;                                String ongoingId = "";                                if (interactionOngoings != null) {                                    for (int i = 0; i < interactionOngoings.size(); i++) {                                      //  互动组件红包雨 TYPE_INTERACT_RED_PACKET = 6;                                      // 互动组件投票 TYPE_INTERACT_VOTE = 7;                                        if (interactionOngoings.get(i).getType() == InteractionOngoing.TYPE_INTERACT_VOTE) {                                            isOngoing = true;                                            ongoingId = interactionOngoings.get(i).getId();                                            break;                                        }                                    }                                }
                                       initVote(                                        token,                                        loginInfo.getUserId(),                                        loginInfo.getRoomId(),                                        isOngoing,                                        ongoingId                                );                            }                        });                    }                });

       private void initVote(String token, String userId, String roomId, boolean isOngoing, String ongoingId) {  //获取组件开关，用于判断房间组件是否开启，以云直播为例        if (DWLive.getInstance().getInteractionConfigure().getVoteSwitch() == 1) {            voteLayout.initialize(new VoteBaseLayout.VoteConfig()                    .setInteractToken(token)                    .setUserId(userId)                    .setRoomId(roomId)                    .setOngoing(isOngoing)                    .setOngoingId(ongoingId));        }    }

5. 销毁组件

       xxxxxxxxxx@Override    protected void onDestroy() {        super.onDestroy();        voteLayout.release();    }

#### 3.2 使用组件管理器+自定义UI

投票管理器实现类为VoteManagerImpl，对外方法参照IVoteManager，UI可以参考VoteBaseLayout以及其子类VoteMainLayout实现

### 4. 混淆配置

混淆配置

    xxxxxxxxxx-keep class com.bokecc.**{*;}-keep interface com.bokecc.**{*;}

### 5. 组件库依赖

    implementation 'com.android.support:appcompat-v7:28.0.0'implementation 'com.android.support:recyclerview-v7:28.0.0'implementation 'com.android.support:cardview-v7:28.0.0'implementation 'com.github.bumptech.glide:glide:4.9.0'