仿微信朋友圈里的listitem与评论框对齐(安卓)

hommilist 2015-05-25 07:00:21
项目中有一需求,需要仿微信下的,当点击评论后,弹出的输入框跟当前点击的item底部对齐:



为了便于讲解,我把我现在做的项目比喻成微信。
我现在的做法是,微信是通过listview来一条一条列出来的,当点击评论后,通过:
InputMethodManager imm =
(InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
conEdit.requestFocus();
//强制显示软键盘
imm.showSoftInput(conEdit,InputMethodManager.SHOW_FORCED);
来强制显示软键盘,我软键盘的弹出模式是:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
也就是挤压模式,然后我监听朋友圈的根容器的resize事件(我键盘调出的模式会调用这个方法),我朋友圈的主布局文件:
<?xml version="1.0" encoding="utf-8"?>
<!-- 社友圈 android:descendantFocusability="blocksDescendants"-->
<com.zhsq.view.ResizeRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/app_layout_bg_gray_color"
android:id="@+id/rootView">

<include
android:id="@+id/common_actionbar"
layout="@layout/include_action_bar" />

<com.zhsq.view.xlist.XListView android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none"
android:fastScrollEnabled="false"
android:layout_below="@id/common_actionbar"
android:dividerHeight="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:background="#e6e6e6"/>
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_alignParentBottom="true"
android:background="#e6e6e6"
android:id="@+id/reviewContainer">
<TextView android:layout_width="wrap_content"
android:id="@+id/sendReview"
android:text="发送"
android:layout_height="27dp"
android:layout_gravity="center_vertical"
android:gravity="center_vertical|center_horizontal"
android:textSize="13sp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_alignParentRight="true"/>
<EditText android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:id="@+id/conEdit"
android:background="@color/white"
android:hint="写评论"
android:layout_toLeftOf="@id/sendReview"
android:focusable="true"
android:enabled="true"
android:focusableInTouchMode="true"/>
</RelativeLayout>

</com.zhsq.view.ResizeRelativeLayout>
这个com.zhsq.view.ResizeRelativeLayout是我自定义的layout,用于监听onResize这个方法:
---------------------------------ResizeRelativeLayout start ----------------------------------
public class ResizeRelativeLayout extends RelativeLayout {
private OnResizeListener mListener;
public interface OnResizeListener {
void OnResize(int w, int h, int oldw, int oldh);
void OnLayout(boolean changed, int l, int t, int r, int b);
}
public ResizeRelativeLayout(Context context) {
super(context);
}
public ResizeRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (null != mListener) {
mListener.OnResize(w, h, oldw, oldh);
}
}

private int layoutCount;
//l,t,r,b分别是放置父控件的矩形可用空间(除去margin和padding的空间)的左上角的left、top以及右下角right、bottom值。
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b){

Log.e("onLayout " + layoutCount++, "=>OnLayout called! changed=" + changed + " l=" + l + ", t=" + t + ",r=" + r + ",b="+b);
if (null != mListener) {
//mListener.OnLayout(changed, l, t, r, b);
}

super.onLayout(changed, l, t, r, b);
}

public void setOnResizeListener(OnResizeListener l) {
mListener = l;
}
}
---------------------------------ResizeRelativeLayout end ----------------------------------
当键盘弹出后,com.zhsq.view.ResizeRelativeLayout的onResize将被调用,然后会调用我定义的OnResizeListener 这个借口进入:
---------------------------------ContainerOnResizeListener start ----------------------------------
public class ContainerOnResizeListener implements OnResizeListener, OnSetPositionListener{
private int position; //通过adapter的OnSetPositionListener接口传进来的值,就是item的index
private int oldt = 0;
private int itemDis;

@SuppressLint("NewApi")
@Override
public void OnResize(int w, int h, int oldw, int oldh) {
if(oldh > h){ //判断是否缩小的resize还是放大的resize
//itemDis = listitem距离屏幕顶上距离 + listitem的高度,通过adapter的OnSetPositionListener接口传进来的值
//oldh = onresize前的的高度
//h=onresize后的高度
//reviewContainer.getMeasuredHeight(); = 图片中输入框的整个layout的高度
//获得的hSub 就是要滚动的高度
int hSub = itemDis - (oldh - h) - reviewContainer.getMeasuredHeight();
listView.scrollListBy(hSub); //这里开始滚动
}
}

@Override
public void onSetPosition(int position,int itemDis) {
this.position = position;
this.itemDis = itemDis;
}

@SuppressLint("NewApi")
@Override
public void OnLayout(boolean changed, int l, int t, int r, int b) {

}
}
---------------------------------ContainerOnResizeListener end ----------------------------------

...全文
5433 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
Crzaybilibili 2016-12-21
  • 打赏
  • 举报
回复
474010422@qq.com楼主求demo
qq_35623066 2016-08-14
  • 打赏
  • 举报
回复
28353704@qq.com 同求
qq_21823949 2016-05-03
  • 打赏
  • 举报
回复
大神,求源码,小女子感激不尽,邮箱2291602189@qq.com
longxing6691 2016-04-08
  • 打赏
  • 举报
回复
大神,你是好人,243640498@qq.com
ddoge 2016-01-18
  • 打赏
  • 举报
回复
求源码。。。。。。。。。。。
zzl035202 2016-01-06
  • 打赏
  • 举报
回复
总结问题: 如果item的高度能有1/2以上显示在屏幕,那么滚动是正常对齐到底部的输入框,没有问题 但是如果item的高度有1/2以上超过屏幕下端(隐藏),那么相同的计算方式item不能滚动到指定的位置上(滚动距离正确),同时获得的item的高度, item偏离屏幕左上的距离也正确,但是不能滚动指定的长度,而是滚动到部分长度就停了,弄了3天,没弄好,望好心人指点迷津,感激不尽! Re:由于你是在父容器onSIzeChange里进行计算并滚动listView,此时父容器并么有完成对listView的重新Layout,所以超过屏幕下端的部分移动不了,解决思路:等待父容器Layout完成即可 1:可以用handler延迟scrollListBy 2:给listView添加addOnGlobalLayoutListener,在这里scrollListBy
wang3184128 2015-12-30
  • 打赏
  • 举报
回复
求楼主来一份啊 看了一天没有合适的454655322@qq.com
qq_33419412 2015-12-24
  • 打赏
  • 举报
回复
楼主来一份好吗,我写了几天了
qq_33419412 2015-12-24
  • 打赏
  • 举报
回复
楼主来一份好吗,我写了几天了
qq_33419412 2015-12-24
  • 打赏
  • 举报
回复
楼主来一份好吗,我写了几天了
qeaq 2015-11-24
  • 打赏
  • 举报
回复
楼主解决了吗求份demo,308289006@qq.com多谢
l1zheng 2015-11-24
  • 打赏
  • 举报
回复
楼主 正在做类似的东西 能给个demo 吗 1465214537@qq.com
qq_21225755 2015-11-19
  • 打赏
  • 举报
回复
最近也在写相似的项目,楼主给个Demo把,QQ550304343@qq.com
findbycsdn 2015-11-06
  • 打赏
  • 举报
回复
楼主,好人一生平安啊!求demo! 331453547@qq.com
佐岸_天空 2015-10-28
  • 打赏
  • 举报
回复
最近也在写相似的项目,楼主给个Demo把,QQ2859912441@qq.com
鸡毛飞上天 2015-10-21
  • 打赏
  • 举报
回复
最近也在写相似的项目,楼主给个Demo把,QQ651139790@qq.com
鸡毛飞上天 2015-10-21
  • 打赏
  • 举报
回复
求Demo啊啊啊
—— 2015-10-13
  • 打赏
  • 举报
回复
楼主求分享源码!
dai_jiawei 2015-07-21
  • 打赏
  • 举报
回复
楼主解决了吗、。?能给个demo吗?
hommilist 2015-05-25
  • 打赏
  • 举报
回复
adapter代码: ---------------------------------MemberCircleAdapter start ---------------------------------- public class MemberCircleAdapter extends BaseListAdapter<ShuoShuoVo> { public static SimpleDateFormat sf = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); public final int reviewShowCount = 5; private RelativeLayout reviewContainer; private EditText conEdit; private OnSetPositionListener onSetPositionListener; private XListView listView; public interface OnSetPositionListener{ public void onSetPosition(int position,int itemDis); } public MemberCircleAdapter(Context context , List<ShuoShuoVo> list , RelativeLayout reviewContainer , EditText conEdit , XListView listView , OnSetPositionListener onSetPositionListener) { super(context, list); this.reviewContainer = reviewContainer; this.conEdit = conEdit; this.listView = listView; this.onSetPositionListener = onSetPositionListener; } @Override public boolean areAllItemsEnabled() { return false; } @Override public boolean isEnabled(int position) { return false; } // @Override // public View getItemView(int i){ // return null; // } @Override public View bindView(int position, View convertView, ViewGroup parent) { final ShuoShuoVo shuoShuoVo = getItem(position); if(null == convertView){ convertView = mInflater.inflate(R.layout.member_circle_listitem, parent, false); // convertView.setTag(position); } //因为convertView会重复使用,此处获得的view只是当前正在显示的view才正确 views.put(position, convertView); ImageView head = ViewHolder.get(convertView, R.id.head); ImageLoader.getInstance().displayImage(shuoShuoVo.getPhoto() , head, ImageLoadOptions.getOptionsNoRounded()); //别名 TextView nickName = ViewHolder.get(convertView, R.id.nickName); //发表时间 TextView time = ViewHolder.get(convertView, R.id.time); //发表评论 ImageView review = ViewHolder.get(convertView, R.id.review); review.setOnClickListener(new reviewOnClickListener(position)); //赞一个 ImageView praise = ViewHolder.get(convertView, R.id.praise); praise.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(mContext, "你点击了赞一个", Toast.LENGTH_SHORT).show(); } }); //内容 TextView con = ViewHolder.get(convertView, R.id.con); //发表的图片 ImageView img = ViewHolder.get(convertView, R.id.img); ImageLoader.getInstance().displayImage(shuoShuoVo.getImage() , img, ImageLoadOptions.getOptionsNoRounded()); img.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //Toast.makeText(mContext, "你点击了图片放大--->", Toast.LENGTH_SHORT).show(); Intent i = new Intent(mContext,PhotoPagerActivity.class); i.putExtra("type", PhotoPagerActivity.SamplePagerAdapter.HANDLETYPE.REMOTE); i.putExtra("drawables", new String[]{shuoShuoVo.getImage() }); i.putExtra("con", shuoShuoVo.getCon()); mContext.startActivity(i); } }); //显示赞的数量 TextView praiseCount = ViewHolder.get(convertView, R.id.praiseCount); praiseCount.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(mContext, "你点击了展开赞列表", Toast.LENGTH_SHORT).show(); } }); //转发 TextView zhuanfa = ViewHolder.get(convertView, R.id.zhuanfa); zhuanfa.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(mContext, "你点击了转发", Toast.LENGTH_SHORT).show(); } }); //罗列评论的list ListView previewList = ViewHolder.get(convertView, R.id.previewList); List<ReviewVo> arrList = shuoShuoVo.getReview().getReviews() == null ? new ArrayList<ReviewVo>() : shuoShuoVo.getReview().getReviews(); MemberCircleReviewAdapter adapter = new MemberCircleReviewAdapter(mContext,arrList); previewList.setAdapter(adapter); //底部加载更多评论 TextView loadPreview = ViewHolder.get(convertView, R.id.loadPreview); LinearLayout reviewContainer = ViewHolder.get(convertView, R.id.reviewContainer); reviewContainer.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(mContext, "你点击了加载更多评论", Toast.LENGTH_SHORT).show(); } }); //这里表示当前是展开了所有评论的状态 int reviewTotalCount = shuoShuoVo.getReview().getTotalCount(); // int showedCount = previewList.getAdapter().getCount(); //隐藏或显示加载按钮 if(reviewTotalCount == 0 || (0 < reviewTotalCount && reviewTotalCount <= reviewShowCount )){ reviewContainer.setVisibility(View.INVISIBLE); }else{ reviewContainer.setVisibility(View.VISIBLE); } nickName.setText(shuoShuoVo.getNickname()); time.setText(shuoShuoVo.getTime() == null ? "" : sf.format(shuoShuoVo.getTime())); con.setText(shuoShuoVo.getCon()); praiseCount.setText((shuoShuoVo.getPraiseCount() == null ? 0 : shuoShuoVo.getPraiseCount()) + " 人觉得赞"); //重新调整评论的list的高度 BaseListAdapter.setListViewHeightBasedOnChildren(previewList); return convertView; } public View getItemView(int position){ return views.get(position); } private Map<Integer,View> views = new HashMap<Integer,View>(); class reviewOnClickListener implements OnClickListener{ private int position; public reviewOnClickListener(){ } public reviewOnClickListener(int position){ this.position = position; } @SuppressLint("NewApi") @Override public void onClick(View v) { View view = MemberCircleAdapter.this.getItemView(position); int[] itemLoca = new int[2]; view.getLocationOnScreen(itemLoca); int viewH = view.getMeasuredHeight() + view.getPaddingBottom() + view.getPaddingTop(); if(null != onSetPositionListener){ //这里在onresize前传入这两个值,因为onresize后这个值可能会被改变 onSetPositionListener.onSetPosition(position,itemLoca[1] + viewH); } // if(MembersCircleActivity.subDis != 0){ // listView.scrollListBy(itemLoca[1] + viewH - MembersCircleActivity.subDis -50); // } // listView.scrollListBy(1000); // View view = getItemView(position); // Toast.makeText(mContext, "当前itemview的高度[" + view.getMeasuredHeight() + "],宽度[" + view.getMeasuredWidth() + "]", Toast.LENGTH_SHORT).show(); if(null != reviewContainer){ InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); // if(!imm.isActive()){ // imm.showSoftInput(conEdit,InputMethodManager.SHOW_FORCED); // } conEdit.requestFocus(); //强制显示软键盘 imm.showSoftInput(conEdit,InputMethodManager.SHOW_FORCED); // imm.showSoftInputFromInputMethod(conEdit.getWindowToken(), 0); if(reviewContainer.getVisibility() == View.GONE) reviewContainer.setVisibility(View.VISIBLE); } } } } ---------------------------------MemberCircleAdapter end ---------------------------------- 以上代码,运行测试的症状: 总结问题: 如果item的高度能有1/2以上显示在屏幕,那么滚动是正常对齐到底部的输入框,没有问题 但是如果item的高度有1/2以上超过屏幕下端(隐藏),那么相同的计算方式item不能滚动到指定的位置上(滚动距离正确),同时获得的item的高度, item偏离屏幕左上的距离也正确,但是不能滚动指定的长度,而是滚动到部分长度就停了,弄了3天,没弄好,望好心人指点迷津,感激不尽!

3,143

社区成员

发帖
与我相关
我的任务
社区描述
微信开发即微信公众平台开发,将企业信息、服务、活动等内容通过微信网页的方式进行表现,通过二次开发可以将公众账号由一个媒体型营销工具转化成提供服务的产品。
社区管理员
  • 微信开发
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧