[Android]用ListView做IM聊天时遇到的问题

很羞愧的是,第一个有关程序的随笔就是一处我暂时无法解决并解释的问题, 先记录下来吧, 等以后弄明白了再补充.

最近在做一个android端的IMAPP, 通讯协议采用的XMPP(因为时间比较紧,并属于内部软件,一切从简了), 服务器用的openfire二次开发, android端自然就是asmack了, 网上有很多例子, 封装的已经很到位了.

在做的过程中, 聊天页肯定是采用ListView了.大约得效果如下图:

技术分享   不好意思哈,这个效果图是仿的微信...

  大家都用过微信,知道进入聊天界面时,ListView会自动滚动到最新的一条消息, 也就是最后一行.

  看起来这个效果应该很好做,因为ListView有很多方法可以做到这一点.

  但是...但是...问题来了...

  我的做法是

  1.首先在XML里设置了

android:transcriptMode="alwaysScroll"

网上对这个属性的解释是: 可以在列表改变的时候自动将最后一行滑到可视范围.

注意是...改变的时候...也就是说如果新加一条数据,或者ListView的大小发现变化的时候(就是点击EditView时弹出键盘时),会出现自动滚屏的效果.

这里不包括初次加载数据时,至少我这里的真机是没有任何效果,对了我以上以下所说的现象都是我个人测试现象,没有任何通用性权威性可言.

继续查百度, 有人说要加上一句

android:stackFromBottom="true"

我加上了, 确实是有效果, 但还是有个问题: 如果ListView的数据量是可以超出一个屏幕的时候, 效果满足, 如果数据量不足一个屏幕就是会出现下面的效果:

技术分享  那我就考虑通过ListView里数据量来动态设置这个属性

if(...){
    lv.setStackFromBottom(true);      //默认是false
}

满以为这样就可以了.. 是的, 如果是纯文本确实没问题, 但如果有需要异步加载的图片时...问题又来了...我用的开源组件ImageLoader

String mapUrl = Scheme.FILE.wrap(data.getPath());
ImageLoader.getInstance().displayImage(mapUrl, content_img, options);

一旦有图片需要加载,ListView又会显示第一条数据了...怎么办?百度...查到ListView的setSelection(position)方法.我的想法是在设置完适配器后在手动选择最后一行:

listview.setAdapter(adapter);
listview.setSelection(adapter.getCount()-1);

然后现象很是奇怪, activity第一次onCreate时, 滚动条是在不在最上也不是最下面,在中间的某个位置, 然后返回键, 再次进入, 就是最下面了...

技术分享第一次进入明显滚动条在中间位置,上面第一条显示不完全技术分享返回键后,再次进入一切正常了

我觉得原因是第一次因为image异步加载时操作了UI, 导致setSelected()失效, 第二次正常可能是imagLoader有缓存,并没有加载图片...

我实在没有办法了..那我等图片加载完再setSelected()吧.

ImageLoader.getInstance().displayImage(imageUrl, content_img, options, 
    new SimpleImageLoadingListener() {
        @Override
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
          super.onLoadingComplete(imageUri, view, loadedImage);
          ChatListAdapter.this.listView.setSelection(getCount()-1);
    }
});

这总行了吧...还是有问题...这样的写法在列表滑动过程中如果加载图片了, 会有个跳卡的效果.所以最后还要判断并设置在第一次进入界面时加载图片成功执行上面代码...然后就不执行了...

告诉我, 为什么会做的这么复杂!!! 我把流程贴出来就不怕你们笑话了...求教!!!

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。