2

我不清楚这是否是不同版本的 Android 或不同屏幕尺寸的问题,但我得到了一些不可预测的行为。

我正在测试正在打开的MultiAutoCompleteTextViewa下拉列表的 UI,并且正在测试正在打开的a 。Nexus SAndroid v4.1.2Nexus 4Android v4.2.1

当我开始在其中输入文本时,MultiAutoCompleteTextView它会返回一些结果。我创建了一个自定义视图,其中ImageView包含TextView. 当 a 行首次显示时,ImageView将具有一定的高度和宽度(左图)。

但是,一旦您滚动浏览结果列表并返回到原来的第一行,就会发生两件事。要么ImageView保持相同的尺寸,要么尺寸ImageView将改变(右图)。

这种特定行为以及提供的屏幕截图Nexus 4Nexus S.

我正在加载BitmapsImageViews就像在开发人员培训Loading Large Bitmaps Efficiently中所做的一样。

这是联系人行的布局资源:

contact_entry2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/contactPic"
        android:layout_width="wrap_content"
        vandroid:layout_height="fill_parent"
        android:contentDescription="@string/contact_pic_desc"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:src="@drawable/ic_contact_picture" />

    <CheckedTextView
        android:id="@+id/contactInfo"
        style="@style/CheckedTextViewStyle" >
    </CheckedTextView>

</LinearLayout>

样式.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <style name="CheckedTextViewStyle">
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_height">match_parent</item>
        <item name="android:textColor">@color/black</item>
        <item name="android:background">@color/white</item>
        <item name="android:gravity">center_vertical</item>
        <item name="android:paddingLeft">10dp</item>
    </style>

</resources>

RecipientsCursorAdapter 是SimpleCursorAdapter(BaseContactsAdapter extends SimpleCursorAdapter)的孙类:

RecipientsCursorAdapter

package com.sendit.adapters;

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckedTextView;
import android.widget.ImageView;

import com.sendit.Contact;
import com.sendit.R;
import com.sendit.util.ContactsUtils;
import com.sendit.util.ImageFetcher;

public class RecipientsCursorAdapter extends BaseContactsAdapter {

    private final String DEBUG_TAG = getClass().getSimpleName().toString();
    private Cursor mCursor;
    private ImageFetcher mImageFetcher;

    public RecipientsCursorAdapter(Context context, int layout, Cursor c,
        String[] from, int[] to, Activity a, int flags, ImageFetcher imageFetcher) {
            super(context, layout, c, from, to, a, flags);
            mImageFetcher = imageFetcher;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.contact_entry2, null);
            // Creates a ViewHolder and store references to the children views
            // we want to bind data to.
            holder = new ViewHolder();
            holder.contactInfo = (CheckedTextView) convertView
                .findViewById(R.id.contactInfo);
            holder.contactPic = (ImageView) convertView
                .findViewById(R.id.contactPic);

            convertView.setTag(holder);

        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();
        }

        holder.position = position;

        mCursor = getCursor();

        mCursor.moveToPosition(position);

        int contactId = mCursor.getInt(mCursor
            .getColumnIndex(ContactsContract.Contacts._ID));

        if (mContactCache.get(contactId) == null) {
            String name = mCursor.getString(mCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            String number = ContactsUtils.getPhoneNumber(mContext, contactId);
            mContactCache.put(contactId, new Contact(name, number));
        }

        Contact c = mContactCache.get(contactId);

        CharSequence contactInfo = getContactInfoSpan(c.getName(), c.getPhoneNumber());

        holder.contactInfo.setText(contactInfo);

        mImageFetcher.loadImage(contactId, holder.contactPic);

        return convertView;
    }

}

至于要研究什么,谁能指出我正确的方向?这是屏幕分辨率问题,还是最新版本的 Android 处理这种情况的方式与以前的版本不同?

4

2 回答 2

2

我会大胆猜测这与视图回收有关....当您从列表中向下然后备份时,您的原始图像显示在一个回收视图中,该视图的宽度/高度在初始加载时设置不同大小的图像。

如果是这样,则可能是Android版本中的错误。无论哪种方式,您都必须处理它。

也许当您回收视图时,您应该再次明确设置/重置图像视图大小,或者基于重新加载到其中的图像,或者如果您希望它们都具有相同的高度,则高度具有常数。

您可能还想使用一些 ImageView 参数,例如 adjustViewBounds 或 Fit/Scale 设置。

最近,我在 Android 4.0.6 和 4.1.2 (内存中的数字......)之间遇到了一些完全不同的行为(是 EditTextView),而且这种废话似乎正在发生......甚至在最近和非常接近的版本之间安卓:-(

于 2013-01-03T10:12:25.890 回答
1

感谢@Andrew 的建议。这是我解决图像大小调整问题的方法。我在实例化引用时调用了ImageView setScaleType()and方法。setLayoutParams()ViewHolder

public class RecipientsCursorAdapter extends BaseContactsAdapter {

    private final String DEBUG_TAG = getClass().getSimpleName().toString();
    private Cursor mCursor;
    private ImageFetcher mImageFetcher;
    private final Drawable mDefaultContactPic;
    private LinearLayout.LayoutParams mImageViewLayoutParams;

    public RecipientsCursorAdapter(Context context, int layout, Cursor c,
        String[] from, int[] to, Activity a, int flags, ImageFetcher imageFetcher) {

        super(context, layout, c, from, to, a, flags);
        mImageFetcher = imageFetcher;
        mDefaultContactPic = context.getResources().getDrawable(R.drawable.ic_contact_picture);
        mImageViewLayoutParams = new LinearLayout.LayoutParams(mDefaultContactPic.getIntrinsicWidth(), mDefaultContactPic.getIntrinsicHeight());
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.contact_entry2, null);
            // Creates a ViewHolder and store references to the children views
            // we want to bind data to.
            holder = new ViewHolder();
            holder.contactInfo = (CheckedTextView) convertView.findViewById(R.id.contactInfo);
            holder.contactPic = (ImageView) convertView.findViewById(R.id.contactPic);

            holder.contactPic.setScaleType(ImageView.ScaleType.CENTER_CROP);
            holder.contactPic.setLayoutParams(mImageViewLayoutParams);

            convertView.setTag(holder);

        } else {
            // Get the ViewHolder back to get fast access to the TextView
            // and the ImageView.
            holder = (ViewHolder) convertView.getTag();
        }

        holder.position = position;

        mCursor = getCursor();

        mCursor.moveToPosition(position);

        int contactId = mCursor.getInt(mCursor.getColumnIndex(ContactsContract.Contacts._ID));

        /*...*/

        mImageFetcher.loadImage(contactId, holder.contactPic);

        return convertView;
    }

}
于 2013-01-04T09:05:26.147 回答