聊天记录,踩的坑:设置EditText焦点;EditText软键盘和recyclerview的交互;SpannableStringBuilder的使用;ClickableSpan失效;软键盘挡住edi

效果概述:

  • 模仿QQ聊天记录

效果图如下:

模拟器只有逍遥安卓了,实在不想重走genymotion的坑,但是逍遥没法弹出软键盘,就这么看吧,可以下载源码在手机上运行,就可以看出来了。
聊天记录,踩的坑:设置EditText焦点;EditText软键盘和recyclerview的交互;SpannableStringBuilder的使用;ClickableSpan失效;软键盘挡住edi_第1张图片

遇到的问题(一)设置EditText焦点

 我想实现点击进去EditText并不获取焦点,而是手动点击的时候获取到焦点,键盘弹出

这个实现倒不难,在EditText的父控件上加上这样两行代码即可

        android:focusable="true"
        android:focusableInTouchMode="true"

遇到的问题(二)EditText软键盘和recyclerview的交互

 我想实现(1)软键盘弹出,recyclerview自动调整布局,即将最后一条显示于软键盘之上
        (2)软键盘弹出的前提下,发送消息后,recyclerview再次调整布局,将发送的消息显示于软键盘之上

这个问题折磨我好久,网上找出各种示例都不成功。
so,我把我的最后的解决办法抛出来,能不能解决你的问题那就看缘分啦

  1. 首先Manifests文件中此activity加入如下代码;这是当弹出软键盘的时候,自动调整布局。网上有详细解释,我就不多说了。

        <activity
            android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
            android:name=".MainActivity">
  2. 其次监听软键盘;当软键盘弹出的时候,让RecyclerView滑动到最后一个位置

        layout = (RelativeLayout) findViewById(R.id.activity_main);
         ViewTreeObserver observer = layout.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect rect = new Rect();
                layout.getWindowVisibleDisplayFrame(rect);
    
                int screenHeight=layout.getRootView().getHeight();//获取屏幕高度
                int heightDiff=screenHeight-(rect.bottom-rect.top);//获取高度之差
    
                Log.e("自定义标签", screenHeight+"_____________"+heightDiff+"");//heightDiff 48--568
    
                if (heightDiff>50){//50是因为我设置的editText高度为40,这个数值可以随时调整的
                    //此时软键盘弹出
                    recycler.scrollToPosition(MyAdapter.list.size()-1);
                }
    
            }
        });

    ViewTreeObserver是主布局获取的布局树,通过布局树监听整个屏幕高度的动态改变

  3. 最后当发送消息的时候,让RecyclerView滑动到最后一个位置

    public void send(View view){
        String s = et.getText().toString();
        adapter.add("right_"+s);
        adapter.add("left_");
        et.setText("");
        recycler.scrollToPosition(MyAdapter.list.size()-1);
    }

遇到的问题(三)SpannableStringBuilder的使用

想实现如图所示,客服回复的内容是一个TextView,带有点击事件,带有颜色和下划线

这个倒也不难,网上教程很多啊

遇到的问题(四)ClickableSpan失效

总之,就是点击不成功,无效

从http://www.jianshu.com/p/d4349a4ca216看到的解决办法。主要是两点:

 1. TextView的setText()方法必须放在setSpan()之后才有效
 2. 必须有txt.setMovementMethod(LinkMovementMethod.getInstance());//即设置可点击或者可实现的一个效果。但是我在搜索这个的时候,发现有网友指出这个语句会导致listview的setOnItemClickListener 事件失效,如果真碰到了可以参考链接 http://blog.csdn.net/yang19910524/article/details/50988028
 3. 还不对的话,仍然不对的话,检查一下你的TextView的setText()方法传递进去的,应该是,SpannableStringBuilder或者SpannableString本身,而不是  .toString() 【QAQ】

遇到的问题(五)沉浸式状态栏,EditText在底部,软键盘的弹出挡住了EditText

如描述所说,沉浸式状态栏,EditText在底部,EditText获取焦点后弹出软键盘,但是软键盘挡住了EditText

我在网上搜索相关的消息,据知乎上有个网友解释这是一个bug,系统级未修复。
我的解决办法是,弃用官方的沉浸式状态栏的标准代码(很简单啊可惜可惜),改用第三方库SystemBarTint。
CSDN上有个博主有SystemBarTint的详细介绍,可以参考下。 http://blog.csdn.net/hwe_xc/article/details/50553758

核心代码

核心代码就不贴啦,坑解决了就没啥难点了。已经把代码贴到github上了。

实现源码

欢迎访问我的github,有帮助的话就star/fork一个吧,^3^
https://github.com/liuda555/ChatUI

你可能感兴趣的:(Android-UI)