Android布局之View.measure()動態量取高度並設定布局--(例:動態計算評論高度並顯示)

來源:互聯網
上載者:User

標籤:android   動態布局   

 需求是這樣的:

在應用程式的詳情介紹時,有評論的版塊,該頁評論最多顯示5條,而每條最大字數是140個字元,每條評論可能根據字數不同,所佔據的高度也不一樣,如有的是1行,有的是2、3行,且評論可以翻頁。

圖片效果如下:




如何解決這樣的問題呢?

首先必須知道的是評論控制項不要固定不變,而是需要動態計算並動態添加到顯示面板中的。

下面通過執行個體來說一下。

1.定義布局

定義布局的時候,可以用AbsoluteLayout,因為高度是動態量取的,所以具體座標是可以求得的。參考如下:

 <AbsoluteLayout        android:layout_width="1386px"        android:layout_height="wrap_content"        android:layout_marginTop="60px"        android:id="@+id/comment_content">         </AbsoluteLayout>
該布局檔案寬度設定不變,高度根據內容填充。只需將這個布局方在需要顯示評論內容的地方。

2.顯示資料


顯示資料,需要根據資料來計算高度,首先把資料設定到控制項中,然後通過View.measure(int widthMeasureSpec, int heightMeasureSpec)量取高度,並為該View設定座標。參考代碼:

<span style="font-size:14px;">/** * 初始化、動態計算高度 */public void initCommentView() {record_temp = new CommentRecord();mPositionRecord = new ArrayList<Integer>();mHeightRecord = new ArrayList<Integer>();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);}}</span>
其中全域的寬、高定義如下:

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<maxSize;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<sum;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<Integer> position = record_temp.getPositionRecord();List<Integer> 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 {@Overridepublic 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 {@Overridepublic 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 <Integer> positionRecord;List <Integer> 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<Integer> getPositionRecord() {return positionRecord;}public void setPositionRecord(List<Integer> positionRecord) {this.positionRecord = positionRecord;}public List<Integer> getHeightRecord() {return heightRecord;}public void setHeightRecord(List<Integer> heightRecord) {this.heightRecord = heightRecord;}   }


6.總結語 動態計算,動態設定布局還是挺常用的。其中的關鍵就是,measure()方法的使用,設定好資料就可以measure(),量好高度後,再設定到顯示面板中,即調用:ViewGroup.addView(View child,LayoutParams params)第一次寫動態布局,寫的不好,希望大家勿噴,有疑問歡迎留言討論,大家互相學習,慢慢進步。

Android布局之View.measure()動態量取高度並設定布局--(例:動態計算評論高度並顯示)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.