最近公司配套智能自行车的App要做发布骑行活动的功能,这就不可避免的要模仿微信朋友圈的很多功能了,这篇文章主要介绍如何做出和微信一样的列表评论效果。

下面先放出实际运行效果:

首先介绍实现这个功能需要经历以下几步:

1)封装方法,通过代码控制弹出和隐藏系统输入法;

2)封装方法,获得手机键盘输入法的高度;

3)代码控制ListView上下滚动指定的距离;

4)自定义一个评论的输入Editext框和发送按钮的布局放在activity中,要求高度写死,并且 alignParentButton 设置为true,在系统输入法显示的时候设置为 Visible,平时设置为 Gone(这个太简单,下面就不写了);

5)在用户点击评论时,计算出ListView需要上下滚动的距离;

6)封装方法,通过代码模拟点击事件确保评论输入的EditText获得焦点;

下面就按照以上知识点的顺序上代码:

1)弹出和隐藏系统输入法:

(1)显示系统输入法的关键代码(如果此时输入法已经显示,调用它就隐藏输入法)

  final InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);

(2)强制隐藏系统输入法的关键代码

  InputMethodManager imm = (InputMethodManager) mInstance.getSystemService(Context.INPUT_METHOD_SERVICE);imm.hideSoftInputFromWindow(windowToken, 0);// weindowToken参数可以通过页面上任意控件的 getWindowToken() 方法获得,我一般习惯用listview调用此方法

2)获得手机键盘输入法的高度

由于这个高度不是统一的,所以每次显示系统输入法的时候最好都要调用它进行测量,以下为关键代码:

  // 当输入法弹出完毕之后,获取当前页面窗口的显示范围,并以此计算输入法的高度Rect rect = new Rect();getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);  // 获取当前手机屏幕显示内容的范围// 以下两行代码用于获取手机屏幕整体高度WindowManager windowManager = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);int screenHeight = windowManager.getDefaultDisplay().getHeight(); // 得到手机屏幕整体高度// 屏幕高度 - 当前正在显示内容范围的高度 = 键盘实际高度int keyBoardHeight = screenHeight - rect.bottom;

方法调用注意事项:由于系统键盘弹出需要时间,因此需要在调用弹出系统输入法之后的 500毫秒 才能开始获取键盘高度,键盘处于隐藏状态时 keyBoardHeight 为 0

3)代码控制ListView上下滚动指定的距离

(这部分代码出自百度经验:http://jingyan.baidu.com/article/e6c8503c0564cbe54f1a18e7.html)

获得了键盘的高度后,就要让 ListView  被评论的条目在键盘弹出后正好置于评论输入框的上方了。但是ListView并没有暴露此方法,因此我们需要反射ListView的 trackMotionScroll() 方法来控制ListView控件的滚动距离了。

以下是关键代码:

 /*** ListView自动向上移动需调用的方法* @param listview 需要自动向上移动的ListView控件* @param activity ListView 所在的Activity* @param y ListView 需要滚动的像素距离,正数为向上滚动,负数向下滚动*/public static void scrollVertical(final ListView listView, Activity activity, final int y) {if (listView == null)return;activity.runOnUiThread(new Runnable() { //执行自动化测试的时候模拟滑动需要进入UI线程操作@Overridepublic void run() {invokeMethod(listView, "trackMotionScroll", new Object[]{-y, -y}, new Class[]{int.class, int.class});}});}

// 以下是上面代码片段 invokeMethod 方法的实际实现

/*** 遍历当前类以及父类去查找方法,例子,写的比较简单 (ListView自动向上移动方法中调用)* @param object* @param methodName* @param params* @param paramTypes* @return*/public static Object invokeMethod(Object object, String methodName, Object[] params, Class[] paramTypes) {Object returnObj = null;if (object == null) {return null;}Class cls = object.getClass();Method method = null;for (; cls != Object.class; cls = cls.getSuperclass()) { //因为取的是父类的默认修饰符的方法,所以需要循环找到该方法try {method = cls.getDeclaredMethod(methodName, paramTypes);break;} catch (NoSuchMethodException e) {// e.printStackTrace();} catch (SecurityException e) {// e.printStackTrace();}}if (method != null) {method.setAccessible(true);try {returnObj = method.invoke(object, params);} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}return returnObj;}

5)ListView上下滚动距离的计算     知道如何控制ListView上下滚动之后,我们就可以开始计算ListView在输入法弹出时应当滚动多少距离了。核心思路如下:
      (1)借助评论按钮的点击事件获取评论按钮在屏幕上的大致位置
      (2)通过ListView的条目布局获得评论按钮距离条目底部的像素值,并反推出当前条目底部在手机屏幕上的位置
      (3)把当前条目底部在手机屏幕上的位置和系统输入法的位置坐对比,计算出差值,此差值就是ListView需要移动的距离
        以下为关键代码:

// 注意,以下代码在 ListView 的 Adapter 下的 getView() 方法中!// 当回复按钮按下的时候viewHolder.ll_replay_btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 首先获取这个点击事件发生的位置int[] location = new int[2];v.getLocationOnScreen(location);int onClickY = location[1];// onClickY就是这个点击事件在Y轴的发生位置,也就是被点击的评论按钮在屏幕Y轴的大体位置/*** 根据自己ListView条目的布局来确定评论按钮距离当前Item底部的距离* 为方便阅读,我统一这个距离为10dp*/// 根据不同的手机分辨率算出 10dp 所对应的像素值float density = context.getResources().getDisplayMetrics().density;int px = (int) (10 * density + .5);  // 获得 10dp 所对应的像素值// 按钮的Y轴位置 + 评论按钮距离条目底部的像素长度 = 条目底部的Y轴位置int itemButtonY = onClickY + px;// 调用方法显示系统输入法(第一步已经有关键代码了,省略)// 调用方法获得键盘的高度(第二步已经有关键代码了,省略)// 开始计算ListView需要上下滚动的距离WindowManager windowManager = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);int screenHeight = windowManager.getDefaultDisplay().getHeight(); // 得到手机屏幕整体高度// listView需要上下滚动的距离 = 被评论条目底部的Y轴位置 - (屏幕高度 - 输入法高度 - 自定义评论输入布局高度)int listViewScrollDistance = itemButtonY - (screenHeight - keyBoardHeight - replyInputLayoutHeight);// 调用方法让ListView滚动到指定的位置(第三步已经有关键代码了,省略)}});

注意事项:

(1)假如当前用户评论的是ListView中最后一个条目,则无需再计算它的滚动位置了,直接调用 scrollToPosition(int position) 方法将条目滚动到最后即可。
      (2)此外,我们还需要在 ListView 的最后加上一个固定的 footerView,这个 view 的高度必须和评论输入布局的高度一样,如果不加这个 footerView 最后一个 item 在被评论的时候会被评论输入布局遮挡住部分内容

6)代码模拟点击事件使EditText获取焦点
        由于在部分手机上发现EditText并不会自动获取焦点,因此我使用了这个简单暴力的方式 ╮(╯▽╰)╭
        使用很简单,输入想要被点击的 View,然后随意输入这个View的相对坐标,然后它就被点击了,很好用的方法
        上关键代码:

 /*** 模拟控件点击事件* @param view 控件(这里指的就是评论的EditText)* @param x 控件相对x坐标* @param y 控件相对y坐标*/public static void setSimulateClick(View view, float x, float y) {long downTime = SystemClock.uptimeMillis();final MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,MotionEvent.ACTION_DOWN, x, y, 0);downTime += 1000;final MotionEvent upEvent = MotionEvent.obtain(downTime, downTime,MotionEvent.ACTION_UP, x, y, 0);view.onTouchEvent(downEvent);view.onTouchEvent(upEvent);downEvent.recycle();upEvent.recycle();}

注意事项:为了保证输入框在获得焦点的时候,光标就在所有文字的后面,建议最好把评论EditText的宽度和高度写死。这样,我们就可以获取到评论EditText最右下角的坐标了,点击这个坐标就可以确保光标永远在所有文字之后。

到此为止,所有的主要功能就算完成了。隐藏系统输入法的逻辑各位可以写在 onBackPress()  方法中,以及复写的ListView 的 onTouchListener 方法中。
由于公司代码不便公开,暂时还不能提供Demo,等有时间整理代码的时候我会公布给大家。

微信朋友圈评论功能的实现步骤相关推荐

  1. html仿微信评论输入框,简单仿微信朋友圈评论功能

    [实例简介] 简单实现了微信朋友圈评论的功能,被点击的评论能够随着输入框高度的改变而改变位置! [实例截图] [核心代码] 简单仿微信朋友圈评论 └── TalkInTalk ├── AndroidM ...

  2. 微信朋友圈评论/回复/cell/键盘谈起

    微信朋友圈评论功能的细节考虑及实现   微信朋友圈回复tableview iOS 实现微信朋友圈评论回复功能(一) 转载于:https://www.cnblogs.com/daxueshan/p/10 ...

  3. android 评论发表情,安卓手机怎么在微信朋友圈评论发表情包?

    核心提示:目前,微信的最新版本更新了朋友圈评论表情包的功能,也就是说用户可以朋友圈开启"斗图模式"啦!但是有些安卓系统的小伙伴发现,自己更新了微信后似乎也不能在朋友圈发评论,具体是 ...

  4. android 仿微信朋友圈 评论,2020年android 仿微信朋友圈 评论

    2020年android 仿微信朋友圈 评论 1.如果有人问我:那些艰难的岁月你是怎么熬过来的?我想我只有一句话回答:我有一种强大的精神力量支撑着我,这种力量名字叫"想死又不敢" ...

  5. 微信分享功能android,关于Android实现简单的微信朋友圈分享功能

    1.先下载微信分享的jar包放在lib目录下,并且添加依赖, android:name=".wxapi.WXEntryActivity" android:exported=&quo ...

  6. android朋友圈评论功能兼容沉浸式状态栏,九宫格图片显示

    android朋友圈评论功能,沉浸式状态栏,九宫格图片显示器,上拉加载下拉刷新功能,可直接用到项目中 背景 在前两个项目开发过程中用到了朋友圈这个功能,包含了评论回复.九宫格图片及大图展示展示,上拉加 ...

  7. TextView实现点击部分文字跳转,实现微信朋友圈评论Item的显示效果

    大家都熟悉微信朋友圈或者是贴吧里的某一条评论, 比如: 小A回复小B:大吉大利,今晚吃鸡,哈哈哈. 点击小A和小B可以跳转到用户页面,点击整个Item就会响应其它事件,比如弹出键盘输入回复. 要实现这 ...

  8. 朋友圈评论发html,微信评论怎么发图片(微信朋友圈评论可以发表情包啦)

    今天你的朋友圈被表情包淹没了没? 啊费一打开朋友圈 几乎全都在"索求"表情包 看到各种沙雕表情包,默默收集了一波哈哈哈 不止朋友圈,就连微博都上了热搜 一波表情包的热潮刷爆了网上 ...

  9. 微信朋友圈/评论/点赞/搜索/购物车

    微信朋友圈 功能:是否可以正常发布,是否可以单独编辑文字,是否可以单独发布图片,是否可以文字和图片一起发送,是否可以选择发布的范围,发布后下面是否可以正常评论,是否可以单独回复每一条评论,是否可以删除 ...

  10. android 微信朋友圈 全功能,Android仿微信朋友圈文字展开全文功能 Android自定义TextView仿微信朋友圈文字展开全文功能...

    Android自定义TextView仿微信朋友圈文字信息,展开全文功能 代码及注释如下: 首先写一个xml文件 showmore.xml: android:orientation="vert ...

最新文章

  1. postgres 备份 恢复
  2. 如何使盘ISO图像文件
  3. Lync 2013部署(1)—AD准备
  4. OpenCV图像仿射变换
  5. 总结css中单位px和em,rem的区别
  6. springboot配置多项目下统一切换不同环境变量profile办法
  7. Java中使用Jedis操作Redis,java初级面试笔试题
  8. wince -- 线程中SetEvent及WaitForSingleObject用法
  9. MongoDB数据库的介绍和连接(非常详细、易懂)
  10. python1e2_Python必修基础(1)
  11. SpringMVC+Spring+Mybatis简单总结
  12. 2020 CPU性能排行天梯图
  13. flash如何同时访问本地文件系统和网络文件
  14. 华为手机图标怎么变小_华为手机怎么设置图标由大变小
  15. 对讲机写频教程以(TCL-HT9为例)
  16. 景深决定照相机什么特性_什么是景深?
  17. aardio - f()函数通过变量名将变量值整合到一串文本中
  18. LayoutTransiton实现简单的录制按钮
  19. MySQL参数优化:back_log
  20. 使用交叉编译工具链编译并调试linux内核

热门文章

  1. 计算机网络-路由交换技术
  2. 火狐 ajax提交失败,Firefox下AJAX0x80040111错误的解决方法
  3. 直播app源码,跳转站外链接或平台内部跳转页面
  4. JSP文件怎么运行JAVA_jsp文件怎么运行
  5. react 实现图片正在加载中 加载完成 加载失败三个阶段的
  6. 车机没有carlife可以自己下载吗_论互联哪家强 Carlife/Carplay针尖对麦芒
  7. 微信开发者工具的tabBar和数据双向绑定
  8. 苹果电脑安装计算机一级,苹果电脑安装Win10系统的详细步骤
  9. 高数 | 常用求极限方法总结
  10. Spring Cloud Eureka Server 源码解析(七)处理客户端增量下载请求、读写锁问题