聊天

           看见下面的导航栏

            我们先实现这个:

            底部我们就用了一个自定义的View

             

[html]  view plain  copy
  1. BottomControlView 这个类就是我们的底部导航栏  
[html]  view plain  copy
  1. public class BottomControlView extends RelativeLayout {  
  2.   
  3.     private ImageView optionView;  
  4.     private ImageView giftView;  
  5.   
  6.     public BottomControlView(Context context) {  
  7.         super(context);  
  8.         init();  
  9.     }  
  10.   
  11.     public BottomControlView(Context context, AttributeSet attrs) {  
  12.         super(context, attrs);  
  13.         init();  
  14.     }  
  15.   
  16.     public BottomControlView(Context context, AttributeSet attrs, int defStyleAttr) {  
  17.         super(context, attrs, defStyleAttr);  
  18.         init();  
  19.     }  
  20.   
  21.     private void init() {  
  22.         LayoutInflater.from(getContext()).inflate(R.layout.view_bottom_control, this, true);  
  23.         findAllViews();  
  24.     }  
  25.   
  26.     public void setIsHost(boolean isHost) {  
  27.         if (isHost) {  
  28.             giftView.setVisibility(INVISIBLE);  
  29.             optionView.setVisibility(VISIBLE);  
  30.         } else {  
  31.             optionView.setVisibility(INVISIBLE);  
  32.             giftView.setVisibility(VISIBLE);  
  33.         }  
  34.     }  
  35.   
  36.     private void findAllViews() {  
  37.         findViewById(R.id.chat).setOnClickListener(clickListener);  
  38.         findViewById(R.id.close).setOnClickListener(clickListener);  
  39.         giftView = (ImageView) findViewById(R.id.gift);  
  40.         giftView.setOnClickListener(clickListener);  
  41.         optionView = (ImageView) findViewById(R.id.option);  
  42.         optionView.setOnClickListener(clickListener);  
  43.     }  
  44.   
  45.     private OnClickListener clickListener = new OnClickListener() {  
  46.         @Override  
  47.         public void onClick(View view) {  
  48.             if (view.getId() == R.id.chat) {  
  49.                 // 显示聊天操作栏  
  50.                 if (mOnControlListener != null) {  
  51.                     mOnControlListener.onChatClick();  
  52.                 }  
  53.             } else if (view.getId() == R.id.close) {  
  54.                 // 关闭直播  
  55.                 if (mOnControlListener != null) {  
  56.                     mOnControlListener.onCloseClick();  
  57.                 }  
  58.             } else if (view.getId() == R.id.gift) {  
  59.                 // 显示礼物选择九宫格  
  60.                 if (mOnControlListener != null) {  
  61.                     mOnControlListener.onGiftClick();  
  62.                 }  
  63.             } else if (view.getId() == R.id.option) {  
  64.                 if (mOnControlListener != null) {  
  65.                     mOnControlListener.onOptionClick(view);  
  66.                 }  
  67.             }  
  68.   
  69.         }  
  70.     };  
  71.   
  72.     private OnControlListener mOnControlListener;  
  73.   
  74.     public void setOnControlListener(OnControlListener l) {  
  75.         mOnControlListener = l;  
  76.     }  
  77.   
  78.     public interface OnControlListener {  
  79.         //显示聊天操作栏  
  80.         public void onChatClick();  
  81.         // 关闭直播  
  82.         public void onCloseClick();  
  83.         // 显示礼物选择九宫格  
  84.         public void onGiftClick();  
  85.   
  86.         public void onOptionClick(View view);  
  87.     }  
  88.   
  89. }  

    还有一个是我们的消息导航栏

[html]  view plain  copy
  1. public class ChatView extends LinearLayout {  
  2.   
  3.     private CheckBox mSwitchChatType;  
  4.     private EditText mChatContent;  
  5.     private TextView mSend;  
  6.   
  7.     public ChatView(Context context) {  
  8.         super(context);  
  9.         init();  
  10.     }  
  11.   
  12.     public ChatView(Context context, AttributeSet attrs) {  
  13.         super(context, attrs);  
  14.         init();  
  15.     }  
  16.   
  17.     public ChatView(Context context, AttributeSet attrs, int defStyleAttr) {  
  18.         super(context, attrs, defStyleAttr);  
  19.         init();  
  20.     }  
  21.   
  22.     private void init() {  
  23.         setOrientation(HORIZONTAL);  
  24.         setGravity(Gravity.CENTER_VERTICAL);  
  25.         int paddingPx = (int) (getResources().getDisplayMetrics().density * 10 + 0.5f);  
  26.         setPadding(paddingPx, paddingPx, paddingPx, paddingPx);  
  27.         setBackgroundColor(Color.parseColor("#ccffffff"));  
  28.         LayoutInflater.from(getContext()).inflate(R.layout.view_chat, this, true);  
  29.   
  30.         findAllViews();  
  31.     }  
  32.   
  33.     private void findAllViews() {  
  34.         mSwitchChatType = (CheckBox) findViewById(R.id.switch_chat_type);  
  35.         mChatContent = (EditText) findViewById(R.id.chat_content_edit);  
  36.         mSend = (TextView) findViewById(R.id.chat_send);  
  37.   
  38.         mSwitchChatType.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {  
  39.             @Override  
  40.             public void onCheckedChanged(CompoundButton compoundButton, boolean b) {  
  41.                 if (b) {  
  42.                     mChatContent.setHint("发送弹幕聊天消息");  
  43.                 } else {  
  44.                     mChatContent.setHint("和大家聊点什么吧");  
  45.   
  46.                 }  
  47.             }  
  48.         });  
  49.         mSwitchChatType.setChecked(false);  
  50.         mChatContent.setHint("和大家聊点什么吧");  
  51.         mSend.setOnClickListener(new OnClickListener() {  
  52.             @Override  
  53.             public void onClick(View view) {  
  54.                 //TODO 发送聊天消息。  
  55.                 Toast.makeText(getContext(), mChatContent.getText().toString(), Toast.LENGTH_SHORT).show();  
  56.                 //sendChatMsg();  
  57.             }  
  58.         });  
  59.     }  

    这个就是我们的消息状态栏

        当我们进行点击消息的时候隐藏BottomControlVIew,显示我们的ChatView,里面都有各种事件的监听,我这里就不详细说了,这些都是最基础的

        这里还涉及到一个就是当我们退出键盘的时候我们得回到BottomCOntrolView的界面,但是我们怎么监听键盘的关闭呢,

        这里有一个小窍门,就是我们可以监听这个界面显示了多少,通过他的界面宽度和高度的大小比较来判断键盘是否关闭

    所以我们重写了Reletivelayout来实现的,请看代码

    

[html]  view plain  copy
  1. public class SizeChangeRelativeLayout extends RelativeLayout {  
  2.   
  3.     public SizeChangeRelativeLayout(Context context) {  
  4.         super(context);  
  5.     }  
  6.   
  7.     public SizeChangeRelativeLayout(Context context, AttributeSet attrs) {  
  8.         super(context, attrs);  
  9.     }  
  10.   
  11.   
  12.     public SizeChangeRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {  
  13.         super(context, attrs, defStyleAttr);  
  14.     }  
  15.   
  16.     @Override  
  17.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  18.         super.onSizeChanged(w, h, oldw, oldh);  
  19.         if (mOnSizeChangeListener == null) {  
  20.             return;  
  21.         }  
  22.         if (h > oldh) {  
  23.             //画面变长,键盘隐藏  
  24.             mOnSizeChangeListener.onLarge();  
  25.         } else {  
  26.             //画面变短,键盘显示  
  27.             mOnSizeChangeListener.onSmall();  
  28.         }  
  29.     }  
  30.   
  31.     private OnSizeChangeListener mOnSizeChangeListener;  
  32.   
  33.     public void setOnSizeChangeListener(OnSizeChangeListener l) {  
  34.         mOnSizeChangeListener = l;  
  35.     }  
  36.   
  37.     public interface OnSizeChangeListener {  
  38.         public void onLarge();  
  39.   
  40.         public void onSmall();  
  41.     }  
  42. }  

    很简单的几句代码,里面有两个接口,键盘隐藏,出现的接口。

    通过View的显示和隐藏来进行处理,但是这样是不会实现效果的,童鞋们呢可以自己进行试验一下,这样做并不能够检测到窗口的大小变换,

    因为我们还没有在清单文件里面给我们的activity添加监听的处理在我们的activity里面添加这么一行代码

[javascript]  view plain  copy
  1. <activity android:name=".MainActivity"  
  2.             android:windowSoftInputMode="adjustResize">  

这样我们才能监听到页面改变

    好了这些基本的界面我们已经实现了,接下来开始我们的核心,也就是我们的通信流程了

    1.消息列表展示界面

        消息列表我们是用了一个listview来展示的,

    2.发送消息

          普通文本消息

            

[html]  view plain  copy
  1. ILVText iliveText = new ILVText("ss", "", ILVLiveConstants.GROUP_TYPE);  
  2.             iliveText.setText("" + textInput.getText());  
  3.             //发送消息  
  4.             ILVLiveManager.getInstance().sendText(iliveText, new ILiveCallBack() {  
  5.                 @Override  
  6.                 public void onSuccess(Object data) {  
  7.                     Toast.makeText(LiveActivity.this, "send succ!", Toast.LENGTH_SHORT).show();  
  8.                 }  
  9.   
  10.                 @Override  
  11.                 public void onError(String module, int errCode, String errMsg) {  
  12.   
  13.                 }  
  14.   
  15.             });  

        以上就是发送一个我们最基本的消息了,

发送完消息后我们需要对消息类型进行一个处理这里我们先不做讨论,之后的弹幕消息再进行处理

    那么我们发送完消息后在哪里接受呢?

       3.解析消息

        LVLiveConfig 是全局直播设置,里面可以配置一个消息回调ILVLiveConfig.ILVLiveMsgListener。通过这个消息回调可以拿到对应的消息类型,然后塞回ILVLiveManager进行配置。

        

参数类型 说明
onNewCmdMsg iLiveSDK预定义信令回调 例如上麦 下麦
onNewCustomMsg 用户自定义信令回调
onNewTextMsg 普通文本接收回调

我们是通过这个接口来实现

[html]  view plain  copy
  1.   

[javascript]  view plain  copy
  1. //对消息的接受  
  2.         ILVLiveConfig liveConfig = BearApplication.getApplication().getLiveConfig();  
  3.         liveConfig.setLiveMsgListener(new ILVLiveConfig.ILVLiveMsgListener() {  
  4.             @Override  
  5.             public void onNewTextMsg(ILVText text, String SenderId, TIMUserProfile userProfile) {  
  6.                 //接收到文本消息  
  7.             }  
  8.   
  9.             @Override  
  10.             public void onNewCustomMsg(ILVCustomCmd cmd, String id, TIMUserProfile userProfile) {  
  11.                 //接收到自定义消息  
  12.                 if (cmd.getCmd() == Constants.CMD_CHAT_MSG_LIST) {  
  13.                     String content = cmd.getParam();  
  14.                     ChatMsgInfo info = ChatMsgInfo.createListInfo(content, id, userProfile.getFaceUrl());  
  15.                     mChatListView.addMsgInfo(info);  
  16.                 } else if (cmd.getCmd() == Constants.CMD_CHAT_MSG_DANMU) {  
  17.                     String content = cmd.getParam();  
  18.                     ChatMsgInfo info = ChatMsgInfo.createListInfo(content, id, userProfile.getFaceUrl());  
  19.                     mChatListView.addMsgInfo(info);  
  20.   
  21.                     String name = userProfile.getNickName();  
  22.                     if (TextUtils.isEmpty(name)) {  
  23.                         name = userProfile.getIdentifier();  
  24.                     }  
  25.                     ChatMsgInfo danmuInfo = ChatMsgInfo.createDanmuInfo(content, id, userProfile.getFaceUrl(), name);  
  26.                     mDanmuView.addMsgInfo(danmuInfo);  
  27.                 } else if (cmd.getCmd() == Constants.CMD_CHAT_GIFT) {  
  28.                     //界面显示礼物动画。  
  29.                     GiftCmdInfo giftCmdInfo = new Gson().fromJson(cmd.getParam(), GiftCmdInfo.class);  
  30.                     int giftId = giftCmdInfo.giftId;  
  31.                     String repeatId = giftCmdInfo.repeatId;  
  32.                     GiftInfo giftInfo = GiftInfo.getGiftById(giftId);  
  33.                     if (giftInfo == null) {  
  34.                         return;  
  35.                     }  
  36.                     if (giftInfo.type == GiftInfo.Type.ContinueGift) {  
  37.                         giftRepeatView.showGift(giftInfo, repeatId, userProfile);  
  38.                     } else if (giftInfo.type == GiftInfo.Type.FullScreenGift) {  
  39.                         //全屏礼物  
  40.                         giftFullView.showGift(giftInfo, userProfile);  
  41.                     }  
  42.                 } else if (cmd.getCmd() == ILVLiveConstants.ILVLIVE_CMD_ENTER) {  
  43.                     //用户进入直播  
  44.                     mTitleView.addWatcher(userProfile);  
  45.                     mVipEnterView.showVipEnter(userProfile);  
  46.                 } else if (cmd.getCmd() == ILVLiveConstants.ILVLIVE_CMD_LEAVE) {  
  47.                     //用户离开消息  
  48.                     mTitleView.removeWatcher(userProfile);  
  49.                 }  
  50.   
  51.             }  
  52.   
  53.             @Override  
  54.             public void onNewOtherMsg(TIMMessage message) {  
  55.                 //接收到其他消息  
  56.             }  
  57.         });  
上面就是我们的信息处理

        那么我们就来处理怎么发送自定义的消息

            

[html]  view plain  copy
  1. //发送消息          
  2.                customCmd.setDestId(ILiveRoomManager.getInstance().getIMGroupId());  
  3.   
  4.                ILVLiveManager.getInstance().sendCustomCmd(customCmd, new ILiveCallBack<TIMMessage>() {  
  5.                    @Override  
  6.                    public void onSuccess(TIMMessage data) {  
  7.                        if (customCmd.getCmd() == Constants.CMD_CHAT_MSG_LIST) {  
  8.                            //如果是列表类型的消息,发送给列表显示  
  9.                            String chatContent = customCmd.getParam();  
  10.                            String userId = BearApplication.getApplication().getSelfProfile().getIdentifier();  
  11.                            String avatar = BearApplication.getApplication().getSelfProfile().getFaceUrl();  
  12.                            ChatMsgInfo info = ChatMsgInfo.createListInfo(chatContent, userId, avatar);  
  13.                            mChatListView.addMsgInfo(info);  
  14.                        } else if (customCmd.getCmd() == Constants.CMD_CHAT_MSG_DANMU) {  
  15.                            String chatContent = customCmd.getParam();  
  16.                            String userId = BearApplication.getApplication().getSelfProfile().getIdentifier();  
  17.                            String avatar = BearApplication.getApplication().getSelfProfile().getFaceUrl();  
  18.                            ChatMsgInfo info = ChatMsgInfo.createListInfo(chatContent, userId, avatar);  
  19.                            mChatListView.addMsgInfo(info);  
  20.   
  21.                            String name = BearApplication.getApplication().getSelfProfile().getNickName();  
  22.                            if (TextUtils.isEmpty(name)) {  
  23.                                name = userId;  
  24.                            }  
  25.                            ChatMsgInfo danmuInfo = ChatMsgInfo.createDanmuInfo(chatContent, userId, avatar, name);  
  26.                            mDanmuView.addMsgInfo(danmuInfo);  
  27.                        }  
  28.                    }  
  29.   
  30.                    @Override  
  31.                    public void onError(String module, int errCode, String errMsg) {  
  32.                    }  
  33.   
  34.                });  
ILVCustomCmd 和以前的发送消息不同,我们这个发送消息的是用的ILVCustomCmd来实现的,并且又sendText()改变为sendCustomCmd()来进行发送

    发送的时候有个cmd来进行我们发送的一个标记,用来辨别我们的消息到底是哪个消息,弹幕还是列表消息,

    都是通过ILVCustomCmd来实现的,这个我们需要设置他的type;是群组消息,还是一对一的消息,

    

[html]  view plain  copy
  1. ILVCustomCmd customCmd = new ILVCustomCmd();  
  2. customCmd.setType(ILVText.ILVTextType.eGroupMsg);  
  3. boolean isDanmu = mSwitchChatType.isChecked();  
  4. if (isDanmu) {  
  5.     customCmd.setCmd(Constants.CMD_CHAT_MSG_DANMU);  
  6. } else {  
  7.     customCmd.setCmd(Constants.CMD_CHAT_MSG_LIST);  
  8. }  
  9. customCmd.setParam(mChatContent.getText().toString());  
  10. mOnChatSendListener.onChatSend(customCmd);//设置消息内容  
            customCmd.setDestId(ILiveRoomManager.getInstance().getIMGroupId());

这段代码就是我们发送的消息承载体

    发送成功后我们就对信息进行处理,弹幕显示或者列表显示

    那么我们的cmd是在哪里生成的呢?

        请看这个类

[html]  view plain  copy
  1. /**  
  2.  * 直播通话配置  
  3.  */  
  4. public class ILVLiveConstants {  
  5.   
  6.     public static final int ILVLIVE_CMD_NONE = 0x700;         //无效消息  
  7.   
  8.     public static final int ILVLIVE_CMD_ENTER = ILVLIVE_CMD_NONE + 1;                                 //用户加入直播, Group消息  
  9.     public static final int ILVLIVE_CMD_LEAVE = ILVLIVE_CMD_ENTER + 1;                           //用户退出直播, Group消息  
  10.     public static final int ILVLIVE_CMD_INVITE = ILVLIVE_CMD_LEAVE + 1;                           //邀请上麦,C2C消息  
  11.     public static final int ILVLIVE_CMD_INVITE_CANCEL = ILVLIVE_CMD_INVITE + 1;                       //取消邀请上麦,C2C消息  
  12.     public static final int ILVLIVE_CMD_INVITE_CLOSE = ILVLIVE_CMD_INVITE_CANCEL + 1;                    //关闭上麦,C2C消息  
  13.     public static final int ILVLIVE_CMD_INTERACT_AGREE = ILVLIVE_CMD_INVITE_CLOSE + 1;                  //同意上麦,C2C消息  
  14.     public static final int ILVLIVE_CMD_INTERACT_REJECT = ILVLIVE_CMD_INTERACT_AGREE + 1;                       //拒绝上麦,C2C消息  
  15.   
  16.     /**  
  17.      * 用户自定义消息段  
  18.      */  
  19.     public static final int ILVLIVE_CMD_CUSTOM_LOW_LIMIT = 0x800;          //自定义消息段下限  
  20.     public static final int ILVLIVE_CMD_CUSTOM_UP_LIMIT = 0x900;          //自定义消息段上线  
  21.   
  22.     /** 信令专用标识 */  
  23.     //public static final String TCEXT_MAGIC          = "LiveNotification";  
  24.   
  25.     /**  
  26.      * 命令字  
  27.      */  
  28.     public static final String CMD_KEY = "userAction";  
  29.     /**  
  30.      * 命令参数  
  31.      */  
  32.     public static final String CMD_PARAM = "actionParam";  
  33.   
  34.   
  35.   
  36.   
  37. }  

这个类里面就有我们的所有cmd,我们也可以进行自定义只不过要在人家给的范围内进行使用(16进制的100)

    

[html]  view plain  copy
  1. public class Constants {  
  2.   
  3.     //自定义发送列表聊天  
  4.     public static final int CMD_CHAT_MSG_LIST = ILVLiveConstants.ILVLIVE_CMD_CUSTOM_LOW_LIMIT + 1;  
  5.     //自定义发送弹幕聊天  
  6.     public static final int CMD_CHAT_MSG_DANMU = ILVLiveConstants.ILVLIVE_CMD_CUSTOM_LOW_LIMIT + 2;  
  7.   
  8.     //自定义发送礼物  
  9.     public static final int CMD_CHAT_GIFT = ILVLiveConstants.ILVLIVE_CMD_CUSTOM_LOW_LIMIT + 3;  
  10.   
  11.   
  12. }  

    这个是我们自定义的cmd

    这样我们就实现了自定义消息的功能

    自定义完我们的消息后我们就要进行弹幕消息的播放:

            1>. 这里我们选用了一个github上面的一个开源库

compile 'com.anbetter:danmukulight:1.0.1'

            2.我们自己封装了一个弹幕播放类

            

[html]  view plain  copy
  1. /**  
  2.  * 弹幕库使用帮助类  
  3.  *  
  4.  * 建议凡是弹幕中涉及到的图片,大小控制在50kb以内,尺寸控制在100x100以内(单位像素)  
  5.  *  
  6.  * Created by android_ls on 2016/12/18.  
  7.  */  
  8. public final class DanMuHelper {  
  9.   
  10.     private ArrayList<WeakReference<IDanMuParent>> mDanMuViewParents;  
  11.     private Context mContext;  
  12.   
  13.     public DanMuHelper(Context context) {  
  14.         this.mContext = context.getApplicationContext();  
  15.         this.mDanMuViewParents = new ArrayList<>();  
  16.     }  
  17.   
  18.     public void release() {  
  19.         if (mDanMuViewParents != null) {  
  20.             for (WeakReference<IDanMuParent> danMuViewParentsRef : mDanMuViewParents) {  
  21.                 if (danMuViewParentsRef != null) {  
  22.                     IDanMuParent danMuParent = danMuViewParentsRef.get();  
  23.                     if (danMuParent != null)  
  24.                         danMuParent.release();  
  25.                 }  
  26.             }  
  27.             mDanMuViewParents.clear();  
  28.             mDanMuViewParents = null;  
  29.         }  
  30.   
  31.         mContext = null;  
  32.     }  
  33.   
  34.     public void add(final IDanMuParent danMuViewParent) {  
  35.         if (danMuViewParent != null) {  
  36.             danMuViewParent.clear();  
  37.         }  
  38.   
  39.         if (mDanMuViewParents != null) {  
  40.             mDanMuViewParents.add(new WeakReference<>(danMuViewParent));  
  41.         }  
  42.     }  
  43.     //添加一个广播 true是全局的广播  
  44.     public void addDanMu(DanmakuEntity danmakuEntity, boolean broadcast) {  
  45.         if (mDanMuViewParents != null) {  
  46.             //从集合中取出一个  
  47.             WeakReference<IDanMuParent> danMuViewParent = mDanMuViewParents.get(0);  
  48.             //如果是全局广播  
  49.             if (!broadcast) {  
  50.                 danMuViewParent = mDanMuViewParents.get(1);  
  51.             }  
  52.             //获取一个DanmUModel  
  53.             DanMuModel danMuView = createDanMuView(danmakuEntity);  
  54.             if (danMuViewParent != null && danMuView != null && danMuViewParent.get() != null) {  
  55.                 danMuViewParent.get().add(danMuView);  
  56.             }  
  57.         }  
  58.     }  
  59.   
  60.     private DanMuModel createDanMuView(final DanmakuEntity entity) {  
  61.         final DanMuModel danMuView = new DanMuModel();  
  62.         //动画从右到左  
  63.         danMuView.setDisplayType(DanMuModel.RIGHT_TO_LEFT);  
  64.         //弹幕的 等级  
  65.         danMuView.setPriority(DanMuModel.NORMAL);  
  66.         //设置左编剧  
  67.         danMuView.marginLeft = DimensionUtil.dpToPx(mContext, 30);  
  68.         //public static final int DANMAKU_TYPE_SYSTEM = 0;// 系统弹幕消息  
  69.        // public static final int DANMAKU_TYPE_USERCHAT = 1;// 用户聊天弹幕消息  
  70.         if (entity.getType() == DanmakuEntity.DANMAKU_TYPE_USERCHAT) {  
  71.             // 用户的头像大小  
  72.             int avatarSize = DimensionUtil.dpToPx(mContext, 30);  
  73.             danMuView.avatarWidth = avatarSize;  
  74.             danMuView.avatarHeight = avatarSize;  
  75.   
  76.             String avatarImageUrl = entity.getAvatar();  
  77.             //加载头像  
  78.             Phoenix.with(mContext)  
  79.                     .setUrl(avatarImageUrl)  
  80.                     .setWidth(avatarSize)  
  81.                     .setHeight(avatarSize)  
  82.                     .setResult(new IResult<Bitmap>() {  
  83.                         @Override  
  84.                         public void onResult(Bitmap bitmap) {  
  85.                             danMuView.avatar = CircleBitmapTransform.transform(bitmap);  
  86.                         }  
  87.                     })  
  88.                     .load();  
  89.   
  90.             // 等级  
  91.             int level = entity.getLevel();  
  92.             int levelResId = getLevelResId(level);  
  93.             Drawable drawable = ContextCompat.getDrawable(mContext, levelResId);  
  94.             danMuView.levelBitmap = drawable2Bitmap(drawable);  
  95.             danMuView.levelBitmapWidth = DimensionUtil.dpToPx(mContext, 33);  
  96.             danMuView.levelBitmapHeight = DimensionUtil.dpToPx(mContext, 16);  
  97.             danMuView.levelMarginLeft = DimensionUtil.dpToPx(mContext, 5);  
  98.   
  99.             if (level > 0 && level < 100) {  
  100.                 danMuView.levelText = String.valueOf(level);  
  101.                 danMuView.levelTextColor = ContextCompat.getColor(mContext, R.color.white);  
  102.                 danMuView.levelTextSize = DimensionUtil.spToPx(mContext, 14);  
  103.             }  
  104.   
  105.             // 显示的文本内容  
  106.             String name = entity.getName() + ":";  
  107.             String content = entity.getText();  
  108.             SpannableString spannableString = new SpannableString(name + content);  
  109.             spannableString.setSpan(  
  110.                     new ForegroundColorSpan(ContextCompat.getColor(mContext, R.color.white)),  
  111.                     0,  
  112.                     name.length(),  
  113.                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);  
  114.             MLog.i("spannableString = " + spannableString);  
  115.   
  116.             danMuView.textSize = DimensionUtil.spToPx(mContext, 14);  
  117.             danMuView.textColor = ContextCompat.getColor(mContext, R.color.light_green);  
  118.             danMuView.textMarginLeft = DimensionUtil.dpToPx(mContext, 5);  
  119.             danMuView.text = spannableString;  
  120.   
  121.             // 弹幕文本背景  
  122.             danMuView.textBackground = ContextCompat.getDrawable(mContext, R.drawable.corners_danmu);  
  123.             danMuView.textBackgroundMarginLeft = DimensionUtil.dpToPx(mContext, 15);  
  124.             danMuView.textBackgroundPaddingTop = DimensionUtil.dpToPx(mContext, 3);  
  125.             danMuView.textBackgroundPaddingBottom = DimensionUtil.dpToPx(mContext, 3);  
  126.             danMuView.textBackgroundPaddingRight = DimensionUtil.dpToPx(mContext, 15);  
  127.   
  128.             danMuView.enableTouch(true);  
  129.             danMuView.setOnTouchCallBackListener(new OnDanMuTouchCallBackListener() {  
  130.   
  131.                 @Override  
  132.                 public void callBack(DanMuModel danMuView) {  
  133.                     Toast.makeText(mContext, "点击了", Toast.LENGTH_SHORT).show();  
  134.                 }  
  135.             });  
  136.         } else {  
  137.             // 显示的文本内容  
  138.             danMuView.textSize = DimensionUtil.spToPx(mContext, 14);  
  139.             danMuView.textColor = ContextCompat.getColor(mContext, R.color.light_green);  
  140.             danMuView.textMarginLeft = DimensionUtil.dpToPx(mContext, 5);  
  141.   
  142.             if (entity.getRichText() != null) {  
  143.                 danMuView.text = RichTextParse.parse(mContext, entity.getRichText(), DimensionUtil.spToPx(mContext, 18), false);  
  144.             } else {  
  145.                 danMuView.text = entity.getText();  
  146.             }  
  147.   
  148.             // 弹幕文本背景  
  149.             danMuView.textBackground = ContextCompat.getDrawable(mContext, R.drawable.corners_danmu);  
  150.             danMuView.textBackgroundMarginLeft = DimensionUtil.dpToPx(mContext, 15);  
  151.             danMuView.textBackgroundPaddingTop = DimensionUtil.dpToPx(mContext, 3);  
  152.             danMuView.textBackgroundPaddingBottom = DimensionUtil.dpToPx(mContext, 3);  
  153.             danMuView.textBackgroundPaddingRight = DimensionUtil.dpToPx(mContext, 15);  
  154.   
  155.             danMuView.enableTouch(false);  
  156.         }  
  157.   
  158.         return danMuView;  
  159.     }  
  160.   
  161.     /**  
  162.      * Drawable转换成Bitmap  
  163.      *  
  164.      * @param drawable  
  165.      * @return  
  166.      */  
  167.     public Bitmap drawable2Bitmap(Drawable drawable) {  
  168.         if (drawable instanceof BitmapDrawable) {  
  169.             // 转换成Bitmap  
  170.             return ((BitmapDrawable) drawable).getBitmap();  
  171.         } else if (drawable instanceof NinePatchDrawable) {  
  172.             // .9图片转换成Bitmap  
  173.             Bitmap bitmap = Bitmap.createBitmap(  
  174.                     drawable.getIntrinsicWidth(),  
  175.                     drawable.getIntrinsicHeight(),  
  176.                     drawable.getOpacity() != PixelFormat.OPAQUE ?  
  177.                             Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);  
  178.             Canvas canvas = new Canvas(bitmap);  
  179.             drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),  
  180.                     drawable.getIntrinsicHeight());  
  181.             drawable.draw(canvas);  
  182.             return bitmap;  
  183.         } else {  
  184.             return null;  
  185.         }  
  186.     }  
  187.   
  188.     /**  
  189.      * 设置等级  
  190.      *  
  191.      * @param level level=100表示主播  
  192.      */  
  193.     public int getLevelResId(int level) {  
  194.         int resId = R.drawable.icon_level_stage_zero;  
  195.         switch (level) {  
  196.             case 100:  
  197. //                resId = R.mipmap.lv_1000;  
  198.                 break;  
  199.             case 0:  
  200.                 resId = R.drawable.icon_level_stage_zero;  
  201.                 break;  
  202.             case 1:  
  203.             case 2:  
  204.             case 3:  
  205.             case 4:  
  206.             case 5:  
  207.                 resId = R.drawable.icon_level_stage_one;  
  208.                 break;  
  209.             case 6:  
  210.             case 7:  
  211.             case 8:  
  212.             case 9:  
  213.             case 10:  
  214.                 resId = R.drawable.icon_level_stage_two;  
  215.                 break;  
  216.             case 11:  
  217.             case 12:  
  218.             case 13:  
  219.             case 14:  
  220.             case 15:  
  221.                 resId = R.drawable.icon_level_stage_three;  
  222.                 break;  
  223.             case 16:  
  224.             case 17:  
  225.             case 18:  
  226.             case 19:  
  227.             case 20:  
  228.                 resId = R.drawable.icon_level_stage_four;  
  229.                 break;  
  230.             case 21:  
  231.             case 22:  
  232.             case 23:  
  233.             case 24:  
  234.             case 25:  
  235.                 resId = R.drawable.icon_level_stage_five;  
  236.                 break;  
  237.             case 26:  
  238.             case 27:  
  239.             case 28:  
  240.             case 29:  
  241.             case 30:  
  242.             default:  
  243.                 resId = R.drawable.icon_level_stage_six;  
  244.                 break;  
  245.         }  
  246.   
  247.         return resId;  
  248.     }  
        当我们需要添加一个房间内弹幕时候只需
[html]  view plain  copy
  1. //发送一条房间内弹幕消息  
  2.         findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {  
  3.             @Override  
  4.             public void onClick(View view) {  
  5.                 DanmakuEntity danmakuEntity = new DanmakuEntity();  
  6.                 danmakuEntity.setType(DanmakuEntity.DANMAKU_TYPE_USERCHAT);  
  7.                 danmakuEntity.setName("小A");  
  8.                 danmakuEntity.setAvatar("http://q.qlogo.cn/qqapp/100229475/E573B01150734A02F25D8E9C76AFD138/100");  
  9.                 danmakuEntity.setLevel(23);  
  10.                 danmakuEntity.setText("滚滚长江东逝水,浪花淘尽英雄~~");  
  11.   
  12.                 addRoomDanmaku(danmakuEntity);  
  13.             }  
  14.         });  

        addDanmu()就是我们封装好的进行弹幕发送的api

        

[html]  view plain  copy
  1. /**  
  2.     * 发送一条房间内的弹幕  
  3.     */  
  4.    private void addRoomDanmaku(DanmakuEntity danmakuEntity) {  
  5.        if (mDanMuHelper != null) {  
  6.            mDanMuHelper.addDanMu(danmakuEntity, false);  
  7.        }  
  8.    }  

        当我们需要发送一个全局的弹幕时:

[html]  view plain  copy
  1. findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {  
  2.             @Override  
  3.             public void onClick(View view) {  
  4.                 String jsonStr = "{\"type\":306,\"name\":\"\",\"text\":\"恭喜小A在小马过河的房间12200031赠送幸运礼物-300棒棒糖,中奖500倍,获得5000钻石。\",\"richText\":[{\"type\":\"text\",\"content\":\"恭喜\",\"color\":\"89F9DF\"},{\"type\":\"text\",\"content\":\"小A\"},{\"type\":\"text\",\"content\":\"在\",\"color\":\"89F9DF\"},{\"type\":\"text\",\"content\":\"小马过河\"},{\"type\":\"text\",\"content\":\"的房间\",\"color\":\"89F9DF\"},{\"type\":\"text\",\"content\":12200031},{\"type\":\"text\",\"content\":\"赠送\",\"color\":\"89F9DF\"},{\"type\":\"icon_gift\",\"extend\":\"text\",\"gift_id\":3816,\"content\":\"300棒棒糖\"},{\"type\":\"text\",\"content\":\",中奖\",\"color\":\"89F9DF\"},{\"type\":\"text\",\"content\":\"500倍\",\"color\":\"FFED0A\"},{\"type\":\"text\",\"content\":\",获得\",\"color\":\"89F9DF\"},{\"type\":\"text\",\"content\":\"5000钻石。\",\"color\":\"FFED0A\"}],\"live_id\":\"1220003114804106040\"}";  
  5.   
  6.                 Gson json = new Gson();  
  7.                 DanmakuEntity danmakuEntity = json.fromJson(jsonStr, DanmakuEntity.class);  
  8.                 danmakuEntity.setType(DanmakuEntity.DANMAKU_TYPE_SYSTEM);  
  9.   
  10.                 addDanmaku(danmakuEntity);  
  11.             }  
  12.         });  

    addDanmuku()

[html]  view plain  copy
  1. /**  
  2.      * 发送一条全站弹幕  
  3.      */  
  4.     private void addDanmaku(DanmakuEntity danmakuEntity) {  
  5.         if (mDanMuHelper != null) {  
  6.             mDanMuHelper.addDanMu(danmakuEntity, true);  
  7.         }  
  8.     }  

    发送当弹幕时全局的时候就是true,否则为false

这样我们就可以进行弹幕的发送,虽然看起来代码有点多,但是逻辑很简单

    当我们需要隐藏所有的弹幕时我们可以调用

DanMuView的hideALLDanMuView(boolean falg)进行隐藏

    

    

到此我们的聊天就暂时告一段落了

猜你喜欢

转载自blog.csdn.net/zhangkaiyazky/article/details/79634272