Android-聊天窗口实现
2016-02-01 01:13
393 查看
实习的时候,做了一个小练习,实现一个聊天界面窗口效果图:项目实现的关键:1、要实现输入框的功能栏,同时要实现功能栏的切换和键盘弹出之间的顺滑过度,我们需要知道一个关键值,即键盘高度。经过一番查阅,我们知道,键盘的弹出方式一般来说有两种,一种是顶起式,另一种是覆盖式。顶起式:android:windowSoftInputMode="stateAlwaysHidden|adjustPan"覆盖式:android:windowSoftInputMode="stateAlwaysHidden|adjustNothing"我们选择通过顶起式来获取键盘高度,覆盖式来实现聊天界面的键盘弹出方式。A首先是键盘弹出的时机顶起式弹出键盘,会动态改变布局,因此,我们可以通过View的布局监听接口,来监听布局是否发生变化,判断键盘已经弹起view.getViewTreeObserver().addOnGlobalLayoutListener(listener);然而,我们并不能判断,哪一个时刻,才是键盘已经完全弹起的时候。因此,我们选择另一种方式,在输入框文字即将输入的时候,获取键盘高度,这时候获取到的键盘高度是可靠的。通过查阅资料,我们知道EditText通过TextChangedListener来监听文字输入,接下来,就是键盘高度的计算了。B键盘高度的计算其实网上分享的键盘高度的计算,大多是通过键盘顶起前的视图高度和顶起后的视图高度的相减值来获取。
privateintgetSupportSoftInputHeight(){ Rectr=newRect(); this.getWindow().getDecorView().getWindowVisibleDisplayFrame(r); intscreenHeight=this.getWindow().getDecorView().getRootView().getHeight(); intsoftInputHeight=screenHeight-r.bottom; if(Build.VERSION.SDK_INT>=18){ //WhenSDKLevel>=18,thesoftInputHeightwillcontaintheheightofsoftButtonsBar(ifhas) softInputHeight=softInputHeight-getSoftButtonsBarHeight(); } returnsoftInputHeight; } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) privateintgetSoftButtonsBarHeight(){ DisplayMetricsmetrics=newDisplayMetrics(); this.getWindowManager().getDefaultDisplay() .getMetrics(metrics); intusableHeight=metrics.heightPixels; this.getWindowManager().getDefaultDisplay().getRealMetrics(metrics); intrealHeight=metrics.heightPixels; if(realHeight>usableHeight){ returnrealHeight-usableHeight; }else{ return0; } }2、接下来是ListView实现三种视图,一种是文字,一种是语音,一种是图片,我们通过adapter的两个关键方法来实现://返回当前item的类型//这个方法会在getView()之前被调用publicintgetItemViewType(intposition)//返回item类型的个数publicintgetViewTypeCount()(1)我们可以定义三种item:privatefinalstaticintTYPE_TEXT=0;privatefinalstaticintTYPE_SOUND=1;privatefinalstaticintTYPE_BITMAP=2;(2)重写两个关键方法:
@Override publicintgetItemViewType(intposition){ returnmChatModels.get(position).getType(); } @Override publicintgetViewTypeCount(){ return3; }(3)重写getView:
@Override publicViewgetView(intposition,ViewconvertView,ViewGroupparent){ ViewHolderholder; inttype=getItemViewType(position); if(convertView==null){ holder=newViewHolder(); switch(type){ caseTYPE_TEXT: convertView=LayoutInflater.from(parent.getContext()).inflate(R.layout .item_chat_text,null); holder.mTextViewContent=(TextView)convertView.findViewById(R.id.tv_content); break; caseTYPE_SOUND: convertView=LayoutInflater.from(parent.getContext()).inflate(R.layout .item_chat_sound,null); holder.mTextViewSeconds=(TextView)convertView.findViewById(R.id.tv_seconds); holder.mSoundView=(SoundView)convertView.findViewById(R.id.sv_sound); break; caseTYPE_BITMAP: convertView=LayoutInflater.from(parent.getContext()).inflate(R.layout .item_chat_bitmap,null); holder.mImageView=(ImageView)convertView.findViewById(R.id.iv_image); break; } holder.mTextViewName=(TextView)(convertView!=null? convertView.findViewById(R.id.tv_name):null); holder.mTextViewTime=(TextView)(convertView!=null? convertView.findViewById(R.id.tv_time):null); if(convertView!=null)convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.mTextViewName.setText(mChatModels.get(position).getName()); holder.mTextViewTime.setText(mChatModels.get(position).getTime()); switch(type){ caseTYPE_TEXT://textmessage ChatTextModelchatTextModel=(ChatTextModel)mChatModels.get(position); holder.mTextViewContent.setText(chatTextModel.getText()); break; caseTYPE_SOUND://soundmessage ChatSoundModelchatSoundModel=(ChatSoundModel)mChatModels.get(position); holder.mSoundView.setData(chatSoundModel.getSoundPath()); break; caseTYPE_BITMAP://bitmapmessage ChatBitmapModelchatBitmapModel=(ChatBitmapModel)mChatModels.get(position); holder.mImageView.setTag(chatBitmapModel.getScaleBitmap()); break; } returnconvertView; }3、然后是缓存策略,由于图片是本地图片,为了提高图片的加载效率,采用内存缓存加磁盘缓存,这里使用的是我自己封装的ImageLoader,把原来的网络获取改为本地获取。
ImageLoader.getInstance().loadBitmap(image_url,mImageView,R.drawable.default_bitmap);
4、自定义视图
--自定义圆角ImageView
--自定义录音控件
--自定义语音播放控件
具体代码都在这里:点击打开链接
尽管写得不是很好,但是通过实战的方式,可以学到很多东西。
相关文章推荐
- 《Android开发艺术探索》读书笔记 (2) 第2章 IPC机制
- Android学习路线
- Android问题解决记录—android.content.res.Resources$NotFoundException: Unable to find resource ID
- Android 判断签名MD5——防止二次打包
- Android activity_main.xml文件中的FrameLayout
- Android 一张图理解getWidth和getMeasuredWidth
- android:gravity与android:layout_gravity
- Android Studio JNI开发
- android框架
- 赤兔安卓版语音图片资料处理
- php-5.5.1-android.patch.v3
- cBPM-android - Code::Blocks环境搭建
- viewpager切换动画
- 选择蜂窝教育Android培训 成就未来
- Android调用默认浏览器打开指定Url的方法实例
- Android NDK and pthread
- Port Node.js to Android running on Genymotion Emulator (x86)
- android— javascript/HTML5/JS read/write local file
- 研究人员开发自治Android应用创建网状网
- 五道口宅男 - Android NDK and OpenCV Development With Android Studio