android计算view高度包括边距,Android布局之View.measure()动态量取高度并设置布局--(例:动态计算评论高度并显示)...

需求是这样的:

在应用程序的详情介绍时,有评论的版块,该页评论最多显示5条,而每条最大字数是140个字符,每条评论可能根据字数不同,所占据的高度也不一样,如有的是1行,有的是2、3行,且评论可以翻页。

图片效果如下:

b29ca967590b29d72737b03bf9b61d0e.png

如何解决这样的问题呢?

首先必须知道的是评论控件不要固定不变,而是需要动态计算并动态添加到显示面板中的。

下面通过实例来说一下。

1.定义布局

定义布局的时候,可以用AbsoluteLayout,因为高度是动态量取的,所以具体坐标是可以求得的。参考如下:

android:layout_width="1386px"

android:layout_height="wrap_content"

android:layout_marginTop="60px"

android:id="@+id/comment_content">

该布局文件宽度设置不变,高度根据内容填充。只需将这个布局方在需要显示评论内容的地方。

2.显示数据

显示数据,需要根据数据来计算高度,首先把数据设置到控件中,然后通过View.measure(int

widthMeasureSpec,int heightMeasureSpec)量取高度,并为该View设置坐标。参考代码:

/**

* 初始化、动态计算高度

*/

public void initCommentView() {

record_temp = new CommentRecord();

mPositionRecord = new ArrayList();

mHeightRecord = new ArrayList();

int currentHeight = 0;

int maxNum = cachedComments.size();

int sum = 0;

for (int i = comment_begin_index; i < maxNum; i++) {

if (null != mCommentCache && !mCommentCache.empty()) {

comment_temp = mCommentCache.pop();

} else {

comment_temp = new CommentSimpleView(mContext);

}

mCommentUI.add(comment_temp);

comment_temp.setData(cachedComments.get(i));

comment_temp.measure(width, height);

if (MAX_COMMENT_HEIGHT > currentHeight) {

comment_content.addView(

comment_temp,

new AbsoluteLayout.LayoutParams(1386, comment_temp

.getMeasuredHeight(), 0, FIRST_COMMENT_INTERVAL

+ currentHeight));

mPositionRecord.add(FIRST_COMMENT_INTERVAL + currentHeight);

mHeightRecord.add(comment_temp.getMeasuredHeight());

currentHeight = currentHeight

+ comment_temp.getMeasuredHeight();

comment_end_index++;

sum++;

if (sum < 5) {

comment_temp.show_Divider();

} else if (sum == 5) {

comment_temp.hide_Divider();

}

}

if (MAX_COMMENT_HEIGHT < currentHeight) {

compareHeight = 1;

isEnd = false;

RelativeLayout.LayoutParams rl = (LayoutParams) comment_content

.getLayoutParams();

rl.setMargins(0, 60, 0, 0);

rl.width = 1386;

rl.height = MAX_COMMENT_HEIGHT+20;

comment_content.setLayoutParams(rl);

break;

}

if (MAX_COMMENT_HEIGHT == currentHeight) {

compareHeight = 0;

if (maxNum == comment_end_index) {

isEnd = true;

comment_pagedown.setFocusStatus(false);

} else {

isEnd = false;

}

}

}

record_temp.setHeightRecord(mHeightRecord);

record_temp.setPositionRecord(mPositionRecord);

record_temp.setBegin_index(comment_begin_index);

record_temp.setEnd_index(comment_end_index);

if (MAX_COMMENT_HEIGHT > currentHeight) {

isEnd = true;

comment_pagedown.setFocusStatus(false);

}

}其中全局的宽、高定义如下:

int width = MeasureSpec.makeMeasureSpec(1386, MeasureSpec.EXACTLY);

int height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

3.翻页动态计算实现

/**

* 点击下一页时,判断是否有空间剩余,若有剩余则用上一页数据补充,false:无剩余

* @return

*/

private boolean hasExtraSpace() {

if(null != cachedComments && cachedComments.size()-comment_end_index >=5){ //剩下的评论大于5条

return false;

}

int beginIndex = 0;

if(1 == compareHeight){

beginIndex = comment_end_index;

}else if(0 == compareHeight){

beginIndex = comment_end_index+1;

}

int maxSize = cachedComments.size();

int HeightSum = 0;

for(int i = beginIndex;i

comment_temp = new CommentSimpleView(mContext);

comment_temp.setData(cachedComments.get(i));

comment_temp.measure(width, height);

HeightSum += comment_temp.getMeasuredHeight();

if(MAX_COMMENT_HEIGHT <= HeightSum){

return false;

}

}

lastPageHeight = HeightSum;

return true;

}

/**

* 最后一页不满一屏,为倒数第一页,从最后一条倒序排列,

*/

public void showLastPage(){

int lastCommentNum = cachedComments.size() - comment_end_index;

int copy_last_index = comment_end_index;

while(128 <= MAX_COMMENT_HEIGHT - lastPageHeight){

lastCommentNum ++;

comment_temp = new CommentSimpleView(mContext);

comment_temp.setData(cachedComments.get(--copy_last_index));

comment_temp.measure(width, height);

lastPageHeight+=comment_temp.getMeasuredHeight();

}

if(MAX_COMMENT_HEIGHT < lastPageHeight){

lastCommentNum -- ;

lastPageHeight -= comment_temp.getMeasuredHeight();

copy_last_index ++;

}

int sum = cachedComments.size();

int current_H = FIRST_COMMENT_INTERVAL + MAX_COMMENT_HEIGHT - lastPageHeight;

for(int i= copy_last_index;i

if(null != mCommentCache && !mCommentCache.empty()){

comment_temp = mCommentCache.pop();

}else{

comment_temp = new CommentSimpleView(mContext);

}

mCommentUI.add(comment_temp);

comment_temp.setData(cachedComments.get(i));

comment_temp.measure(width, height);

comment_content.addView(comment_temp, new AbsoluteLayout.LayoutParams(1386, comment_temp.getMeasuredHeight(), 0, current_H));

current_H = current_H + comment_temp.getMeasuredHeight();

if(i == sum -1){

comment_temp.hide_Divider();

}else{

comment_temp.show_Divider();

}

}

isEnd = true;

comment_pagedown.setFocusStatus(false);

}

/**

* 点击上一页,出栈,恢复数据并显示

*/

public void showPageUp(){

if(mCommentRecord.empty()){

Toast.makeText(mContext, "已是第一页", Toast.LENGTH_SHORT).show();

return;

}

record_temp = mCommentRecord.pop();

int begin = record_temp.getBegin_index();

int end = record_temp.getEnd_index();

List position = record_temp.getPositionRecord();

List height = record_temp.getHeightRecord();

if(null == position || null == height){

return;

}

int m = 0;

for(int i= begin;i<=end;i++){

if(null != mCommentCache && !mCommentCache.empty()){

comment_temp = mCommentCache.pop();

}else{

comment_temp = new CommentSimpleView(mContext);

}

mCommentUI.add(comment_temp);

comment_temp.setData(cachedComments.get(i));

comment_content.addView(comment_temp, new AbsoluteLayout.LayoutParams(1386,height.get(m), 0, position.get(m)));

m++;

if(5 == m){

comment_temp.hide_Divider();

}else{

comment_temp.show_Divider();

}

}

isEnd = false;

comment_begin_index = begin;

comment_end_index = end;

}

4.点击上一页、下一页事件处理

public class comment_pageup_click implements OkButtonViewClick {

@Override

public void onOkButtonViewClick() {

if(1 == currentPage){

//Toast.makeText(mContext, "已是第一页", Toast.LENGTH_SHORT).show();

comment_pageup.setFocusStatus(false);

return;

}else{

currentPage = currentPage - 1;

comment_content.removeAllViews();

while (!mCommentUI.isEmpty()) {

mCommentCache.push(mCommentUI.remove(0));

}

showPageUp();

comment_pagedown.setFocusStatus(true);

}

}

}

class comment_pagedown_click implements OkButtonViewClick {

@Override

public void onOkButtonViewClick() {

if(isEnd){

//Toast.makeText(mContext, "已是最后一页", Toast.LENGTH_SHORT).show();

comment_pagedown.setFocusStatus(false);

return;

}

else if(!isEnd){ //不到最后一页

if(!hasExtraSpace()){ //下一页无剩余空间,即该页不是倒数第二页

mCommentRecord.push(record_temp);

currentPage = currentPage + 1;

if(1 == compareHeight){

comment_begin_index = comment_end_index;

comment_end_index --;

}else{

comment_begin_index = comment_end_index+1;

}

if(currentPage%4 ==0){ //预加载数据

ParserHelper.getParserHelper().requestComment("1", "30", "9", callback);

}

comment_content.removeAllViews();

while (!mCommentUI.isEmpty()) {

mCommentCache.push(mCommentUI.remove(0));

}

initCommentView();

}else { //下一页有剩余空间,即该页为倒数第二页

mCommentRecord.push(record_temp);

currentPage = currentPage + 1;

comment_content.removeAllViews();

while (!mCommentUI.isEmpty()) {

mCommentCache.push(mCommentUI.remove(0));

}

showLastPage();

}

comment_pageup.setFocusStatus(true);

}

}

}

5.下一页点击时保存状态,用作恢复。(用栈保存,入栈出栈)

package com.helios.module.commentData;

import java.util.List;

public class CommentRecord {

int begin_index;

int end_index;

List positionRecord;

List heightRecord;

public CommentRecord() {

super();

}

public int getBegin_index() {

return begin_index;

}

public void setBegin_index(int begin_index) {

this.begin_index = begin_index;

}

public int getEnd_index() {

return end_index;

}

public void setEnd_index(int end_index) {

this.end_index = end_index;

}

public List getPositionRecord() {

return positionRecord;

}

public void setPositionRecord(List positionRecord) {

this.positionRecord = positionRecord;

}

public List getHeightRecord() {

return heightRecord;

}

public void setHeightRecord(List heightRecord) {

this.heightRecord = heightRecord;

}

}

6.总结语

动态计算,动态设置布局还是挺常用的。

其中的关键就是,measure()方法的使用,设置好数据就可以measure(),量好高度后,再设置到显示面板中,即调用:

struggle.gif

原文:http://blog.csdn.net/adayabetter/article/details/44993657

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值