安卓开发----listview中图片拉伸问题

来源:互联网 发布:淘宝网店免费模块 编辑:程序博客网 时间:2024/06/05 04:00

在上周工作中 使用了listview

在其item中只放了一个textview(有背景) 发现图片被拉高了

1.如下是item的布局文件

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android"        android:id="@+id/tv_time"        android:layout_width="120dp"        android:layout_height="40dp"        android:background="@drawable/baby_task_point_blue"        android:gravity="center"        android:minHeight="30dp"        android:text="8:00-8:40"        android:textColor="@color/preference_nextstep_background_normal"        android:textSize="@dimen/text_normal" /></span>

2.后来就想着套一层viewgroup把背景设在viewgroup上行不行  结果还是不行

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="120dp"    android:background="@drawable/baby_task_point_blue"</span>    android:layout_height="40dp" >              <TextView android:id="@+id/tv_time"               android:layout_width="120dp"               android:layout_height="40dp"               android:gravity="center"               android:minHeight="30dp"              android:text="8:00-8:40"              android:textColor="@color/preference_nextstep_background_normal"              android:textSize="@dimen/text_normal" /></LinearLayout>

3.几经周折 最后试了下背景设在里面

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="120dp"    android:layout_height="40dp" >    <TextView        android:id="@+id/tv_time"        android:layout_width="120dp"        android:layout_height="40dp"        android:background="@drawable/baby_task_point_blue"        android:gravity="center"        android:minHeight="30dp"        android:text="8:00-8:40"        android:textColor="@color/preference_nextstep_background_normal"        android:textSize="@dimen/text_normal" /></LinearLayout></span>

于是乎就郁闷了 为什么只有套了一层 并且把背景设在里面才行


趁着周末就想找找原因了

思路是这样的 :

既然 linearlayout和textview都有问题 那肯定是他们的共同父类view有问题

先看view的onMeasure方法

<span style="font-size:14px;"> protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));    }</span>

我们知道setMeasuredDimension方法用来设置测量结果的 所以我们去看getDefaultSize方法

<span style="font-size:14px;">public static int getDefaultSize(int size, int measureSpec) {        int result = size;        int specMode = MeasureSpec.getMode(measureSpec);        int specSize = MeasureSpec.getSize(measureSpec);        switch (specMode) {        case MeasureSpec.UNSPECIFIED:            result = size;            break;        case MeasureSpec.AT_MOST:        case MeasureSpec.EXACTLY:            result = specSize;            break;        }        return result;    }</span>
先讲解下

UNSPECIFIED:表示默认值,父控件没有给子view任何限制。------二进制表示:00

EXACTLY:表示父控件给子view一个具体的值,子view要设置成这些值的大小。------二进制表示:01

AT_MOST:表示父控件个子view一个最大的特定值,而子view不能超过这个值的大小。------二进制表示:10

假设现在图片的高度是140 而我们写的layout_height=30;

那么此时specSize=30,size=140

毫无疑问 对于第1,2种布局我们的程序走到了

<span style="font-size:14px;">  case MeasureSpec.UNSPECIFIED:            result = size;            break;</span>

而第3种布局走到了


case MeasureSpec.EXACTLY:            result = specSize;            break;

那么这是为什么呢?

逐一分析:

第一种布局:

textview作为item中中的唯一控件 它的父布局就是listview给item包裹的一个viewgroup

我们来看看这个viewgroup的设置

关于listview中添加item在如下这个方法中

private View makeAndAddView(int position, int y, boolean flow, int childrenLeft,boolean selected) {View child;<span style="font-family:Roboto,sans-serif;">.......</span>// Make a new view for this position, or convert an unused view if// possible//调用getViewchild = obtainView(position, mIsScrap);// This needs to be positioned and measuredsetupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0]);return child;}
如上listview通过obtainView得到复用的view或者调用getview产生新的view

然后在setupChild方法中把item添加到对应的viewgroup中

private void setupChild(View child, int position, int y, boolean flowDown, int childrenLeft,boolean selected, boolean recycled) {       ....// <span style="font-family:Roboto,sans-serif;">那个viewgroup的</span><span style="font-family:Roboto,sans-serif; color:#222222"></span>LayoutParams <span style="font-family:Roboto,sans-serif; color:#222222"></span>AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams();if (p == null) {p = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT, 0);}<span style="font-family:Roboto,sans-serif;">                          .......</span>        }
看到了吧  这个viewgroup的高度WRAP_CONTENT

所以走到了

  case MeasureSpec.UNSPECIFIED:            result = size;            break;
第二种布局:

同第一种布局 因为此时背景设在linearlayout上  所以当它测量高度时 也走到了

 case MeasureSpec.UNSPECIFIED:            result = size;            break;
第三种布局:

此时背景设在textview中

那么当linearlayout测量高度时 走到了

case MeasureSpec.EXACTLY:            result = specSize;            break;
所以再到textview测量高度时 就一切正常了



0 0
原创粉丝点击