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

在上周工作中 使用了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
		//调用getView
		child = obtainView(position, mIsScrap);

		// This needs to be positioned and measured
		setupChild(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测量高度时 就一切正常了



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值