android评论控件对齐输入框顶部

来源:互联网 发布:linux命令格式 编辑:程序博客网 时间:2024/06/05 18:43

有些类似微信的评论对齐,大众点评也是这样的评论交互,产品也是参考了类似的设计,这块需求也是花了不少时间,首先是关键思路,然后才是偏移量的具体的计算,中间又遇到遍历child view,when child view have more than one line words always have the same value of one line,在getChildView里只有post new Runnable方式才能获得准确height,所以又加入了保存机制,在触发事件时再遍历saved value,总算能够精准定位了,记录一下。

三个需求,无子评论、子评论的任一项、子评论最后一项下方的输入框三种事件触发

关键思路:
listView.setSelectionFromTop(int position,int top)
设置某个item滚动到距离当前页面,但不是顶部,而是距离顶部的某个位置,距离为top参数
top=listview.getBottom-viewheight;

listview.setSelectionFromTop(position,listview.getBottom-viewheight),就可以让这个item移到屏幕底部。viewHeight为listview中每个item的高度,
在实际过程中,都会弹出输入法,所以,之前listview.getBottom还是没有输入法弹出时的高度,所以造成位置不正确。重写自定义listview继承ListVIew,然后里面有个onSizeChanged方法 ,会在ListView尺寸变化的时候调用,在这里添加了一个回调,然后,在回调里,再次获取listview的尺寸的就可以了。布局如下:

<?xml version="1.0" encoding="utf-8"?><com.xxx.app.view.ResizeRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/rl_content"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <ExpandableListView        android:id="@+id/my_lv_lpcomment"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:childDivider="@null"        android:divider="@null"        android:dividerHeight="0dp"        android:fastScrollEnabled="false"        android:groupIndicator="@null"></ExpandableListView>

private ResizeRelativeLayout rl_content;

rl_content = (ResizeRelativeLayout) view.findViewById(R.id.rl_content);
rl_content.setOnResizeListener(new ContainerOnResizeListener());

private class ContainerOnResizeListener implements ResizeRelativeLayout.OnResizeListener {        @SuppressLint("NewApi")        @Override        public void OnResize(int w, int h, int oldw, int oldh) {                   if (oldh > h && popWindowHeight > 0) {                my_lv_lpcomment.postDelayed(new Runnable() {                    @Override                    public void run() {                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                            int margin = StringUtils.dip2px(mContext, 10);                            int top = my_lv_lpcomment.getBottom() - convertViewHeight -                                                                       popWindowHeight + margin;                            my_lv_lpcomment.setSelectionFromTop(currentOptPosition,                                                                                  top);                        } else {                            my_lv_lpcomment.smoothScrollBy(convertViewHeight, 300);                        }                    }                }, 300);            } else {//布局大小变化判断软键盘的关闭                UtilsLog.i(TAG, "OnResize ...");            }        }    }

关键处就是计算convertViewHeight ,item height,如果是展开了很多child view,需要group view height+n*child view height;
这里写图片描述

这个需求直接定位到评论已展示条目下方,同时在输入法上方展示自定义输入框
convertViewHeight =group view height;即可
这里写图片描述

点击已展开的任一child view,定位到该child view下方,偏移量计算如下

 private void showSoftInputToResize(int groupPosition,int childPosition) {        int desiredWidth = View.MeasureSpec.makeMeasureSpec(my_lv_lpcomment.getWidth(),                View.MeasureSpec.UNSPECIFIED);        View groupItem = adapter.getGroupView(groupPosition, false, null,                my_lv_lpcomment);        groupItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);        this.convertViewHeight = groupItem.getMeasuredHeight();        //因为下面的方式来遍历无法得到准确的child item height,so we save in getChildView and get it        //View childItem = adapter.getChildView(position, j, false, null,my_lv_lpcomment);        for(int i=0;i<=childPosition;i++){            try{                convertViewHeight +=  mSelectedIdsMap.get(i);            }catch(Exception e){                UtilsLog.d(TAG, "showSoftInputToResize e=" +e.getMessage());            }        }        int margin = StringUtils.dip2px(mContext, 10);        convertViewHeight -= margin;        //mode=0;        InputMethodManager inputManager =                (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);        inputManager.showSoftInput(et_reply, 0);        getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.                                                      SOFT_INPUT_ADJUST_RESIZE);    }

因为遍历child view无法得到准确的child item height,so we save in getChildView and get it,健值对都是Integer,在getChildView时save position及对应的item height,
mSelectedIdsMap = new ConcurrentHashMap<>();

final View tempV = convertView;final View lastView=holder.tv_reply;tempV.post(new Runnable() {     @Override     public void run() {            int childHeight = tempV.getHeight();            Log.d(TAG,"post position="+tempPosition+ " childHeight:" + childHeight);            if(isLastChild){                mSelectedIdsMap.put(childPosition,lastView.getHeight());             }else{                mSelectedIdsMap.put(childPosition,childHeight);              }      }     });

需要区分是否是isLastChild,这个跟item view的布局有关系,最后一项比一般项多显示了输入框等,偏移量不需要计算这部分,所有保存的时候就要处理下