Android开发——即时通讯中自定义聊天页面封装实现

说明

本人大四党,菜鸟,毕业设计有即时通讯的部分,目前即时通讯的模块基本完成,记录一下在Android平台下实现整个即时通讯界面功能的过程。

good

功能点

  • 已完成功能点
  1. 适应键盘高度
  2. 自定义灵活的功能面板
  3. 表情消息
  • 尚未完成的功能点
  1. 语音消息
  2. 图片消息

话不多说系列

示例图

关键代码

底部聊天栏管理器ChatBarManager
/**
 * 聊天底部栏管理器
 * @author 赵陈淏
 */
public class ChatBarManager implements ChatBar.ChatBarAdapter
{
   
	//功能/表情面板最大和最小高度限制
    private static final int MIN_HEIGHT=720;
    private static final int MAX_HEIGHT=950;
    private Activity mActivity;
    private ResizeLayout resizeLayout;
    private ChatBar chatBar;
    private int softKeyBoardHeight=0;
    private InputMethodManager inputManager;

    public ChatBarManager(Activity activity,ChatBar bar,ResizeLayout root)
    {
   
        this.mActivity=activity;
        this.chatBar=bar;
        this.resizeLayout=root;
        inputManager=(InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
		//这里对根部局加上尺寸调整监听,得以对键盘弹起时的高度进行记录
        resizeLayout.setOnResizeListener(new ResizeLayout.OnResizeListener() {
   
            @Override
            public void OnResize(int w, int h, int oldw, int oldh) {
   
                if (oldw != 0 && oldh != 0) {
   
                    if (h < oldh) {
   
                        int cur = oldh - h;
                        cur = Math.max(MIN_HEIGHT,
                                cur);
                        cur=Math.min(cur,MAX_HEIGHT);
                        if (cur!=softKeyBoardHeight)
                        {
   
                            softKeyBoardHeight=cur;
                            Log.e("CHAT","检测到键盘高度为"+softKeyBoardHeight);
                            chatBar.setFuncPanelHeight(softKeyBoardHeight);
                        }
                    }
                }
            }
        });

        chatBar.setChatBarAdapter(this);
    }

    /**
     * 设置自定义的功能
     */
    public void setUpFunctions(FunctionPanel.ChatFunction[] functions)
    {
   
        chatBar.setUpFunctions(functions);
    }

    /**
     * 设置功能点击监听
     * @param functionClickListener 功能监听
     */
    public void setFunctionClickListener(FunctionPanel.FunctionClickListener functionClickListener) {
   
        chatBar.setFunctionClickListener(functionClickListener);
    }

    @Override
    public void sendText(CharSequence text) {
   
        ToastUtils.showToast(mActivity.getApplicationContext(),"消息",text.toString());
    }

    @Override
    public void funcPanelShow(boolean isShow) {
   
        showFuncPanel(isShow);
    }


    /**
     * 收起键盘与功能栏
     * 仅用于
     */
    public void hideSoftInput()
    {
   
        Log.e("Manager","调用隐藏键盘");
        inputManager.hideSoftInputFromWindow(chatBar.getSendText().getWindowToken(), 0);
        if (chatBar.isFuncPanelShow())
        {
   
            hideFuncPanelDelayed();
        }
    }

    /**
     * 显示/关闭 功能面板
     * @param isShow 显示/关闭
     */
    private void showFuncPanel(boolean isShow)
    {
   
        Log.e("Manager","调用了show"+isShow);
        if (isShow)
        {
   
            mActivity.getWindow().setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
            inputManager.hideSoftInputFromWindow(chatBar.getSendText().getWindowToken(), 0);
            chatBar.setFuncPanelVisible(View.VISIBLE);
        } else {
   
            inputManager
                    .showSoftInput(chatBar.getSendText(), InputMethodManager.HIDE_NOT_ALWAYS);
            hideFuncPanelDelayed();
        }
    }

    /**
     * 延迟隐藏功能面板
     */
    private void hideFuncPanelDelayed()
    {
   
        Log.e("ChatBarManager","延迟隐藏");
        //这里要delayed执行否则依然会跳动,因为隐藏面板的同时要弹出键盘,
        // 弹出键盘有个延迟,如果在弹出键盘前执行的话就会造成跳动
        chatBar.postDelayed(()-> {
   
            chatBar.setFuncPanelVisible(View.GONE);
            mActivity.getWindow().setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
            chatBar.getSendText().requestFocus();
        },300);
    }
}

实现的功能面板类FunctionPanel.java
这里利用ViewPager+Fragment和public void setUpFunctions(ChatFunction[] functions)装载功能项目后,计算功能数量并自动分页、适应布局。
其中的内部类ChatFunction的成员变量:
-funcResId
-funcText
-funcFlag
分别用来代指功能面板的图片资源id、功能描述和标志int,Flag用来监听其点击事件
在这里插入图片描述
功能面板FunctionPanel中涵盖了FacePanel,通过设置两个ViewGroup的可见性来做切换。
其实更合理的设计是对两个类别的面板再作分离 :

  • 底部面板
    • 表情面板
    • 功能面板

我这里的设计是:

  • 功能面板
    • 表情面板:FacePanel
    • LinearLayout(子控件:ViewPager+FuncPointer)

其实是懒得改(小声BB),下面是功能面板代码

package com.biang.manage.widget.chat.func;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.GridLayout;
import android.widget.LinearLayout;

import com.biang.manage.R;
import com.biang.manage.core.base.BaseActivity;
import com.biang.manage.core.base.BaseChatActivity;
import com.biang.manage.core.base.BaseFragment;
import com.biang.manage.widget.chat.FacePanel;
import com.biang.manage.widget.common.iconbutton.IconButton;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;

public class FunctionPanel extends LinearLayout
{
   
    private FunctionClickListener functionClickListener;
    private FacePanel facePanel;
    private View functionPanel;
    private ViewPager funcPager;
    private FuncPointer mPointer;
    public static final int FACE=0;
    public static final int FUNC=1;
    private int witchPanel=0;
    private BaseChatActivity mActivity;

    /**
     * 切换面板
     */
    public void setWitchPanel(int witchPanel)
    {
   
        if (witchPanel!=0&&witchPanel!=1)
            return;
        this.witchPanel=witchPanel;
        switch (witchPanel)
        {
   
            case FACE:
                facePanel.setVisibility(VISIBLE);
                functionPanel.setVisibility(GONE);
                break;
            case FUNC:
                facePanel.setVisibility(GONE);
                functionPanel.setVisibility(VISIBLE);
                break;
        }
    }
    public FunctionPanel(Context context) {
   
        super(context);
        initView(context);
    }
    public FunctionPanel(Context context, AttributeSet set) {
   
        super(context,set);
        initView(context);
    }

    /**
     * 设置表情点击监听
     */
    public void setOnFaceClickListener(FacePanel.OnFaceClickListener listener) {
   
        facePanel.setOnFaceClickListener(listener);
    }

    /**
     * 设置功能
     */
    public void setUpFunctions(ChatFunction[] functions)
    {
   
        List<FuncFragment> fragments=new ArrayList<>();
        List<
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值