【问题标题】:Weird behavior,Item in ListView auto-scale when scrolling?奇怪的行为,ListView 中的项目在滚动时自动缩放?
【发布时间】:2012-03-24 15:50:35
【问题描述】:

这是正常的:

这很奇怪,当我滚动列表视图时,一些项目缩小了(但宽度和高度的值没有改变。):

在这个截图中 item[1:3] 是同一种类型,但是 item[3] 没有缩放。哪个项目缩放似乎随机化可能基于设备或内容。

ListView和Adapter的代码没什么特别的:

mListView = new ListView(mContext);
mListView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
mProviderAdapter = new ProviderAdapter();
mListView.setAdapter(mProviderAdapter);


class ProviderAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return mCount;
        }

        @Override
        public Object getItem(int position) {
            return mProviders.get(position);
        }

        @Override
        public long getItemId(int position) {
            return mProviders.get(position).mMsgSpace;
        }

        @Override
        public int getViewTypeCount() {
            return 10000;
        }
        @Override
        public int getItemViewType(int position) {
            // TODO Auto-generated method stub
            return (position);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return mProviders.get(position).getUI().getView();
        }

    }

Hierarchy Viewer截图(右下角):Link

这是自定义视图:

<?xml version="1.0" encoding="UTF-8"?>
<ViewAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#44FFFFFF" >


        <LinearLayout
            android:id="@+id/word"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <TextView
                    android:id="@+id/content"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#EC5800"
                    android:textSize="24sp" />

                <TextView
                    android:id="@+id/pron"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="bottom" />
            </LinearLayout>

            <TextView
                android:id="@+id/definition"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="20sp" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <Button
                    android:id="@+id/add"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:padding="16dp"
                    android:text="@string/add"
                    android:textSize="20sp" />

                <Button
                    android:id="@+id/sound"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="16dp"
                    android:contentDescription="@string/audio"
                    android:padding="16dp"
                    android:text="@string/audio"
                    android:textSize="20sp" />

                <Button
                    android:id="@+id/switch_button"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="16dp"
                    android:contentDescription="@string/audio"
                    android:padding="16dp"
                    android:text="@string/definition"
                    android:textSize="20sp" />

            </LinearLayout>
        </LinearLayout>

    <LinearLayout
        android:id="@+id/login"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <Button
            android:id="@+id/login_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="Login" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/blank"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </LinearLayout>

</ViewAnimator>

另一种观点:

<?xml version="1.0" encoding="utf-8"?>
<ViewSwitcher xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ViewSwitcher1"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/example_panel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/example_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <TextView
            android:id="@+id/example_zh_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView" />

        <TextView
            android:id="@+id/example_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Medium Text"
            android:textAppearance="?android:attr/textAppearanceMedium" />

        <TextView
            android:id="@+id/example_zh_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView" />

        <Button
            android:id="@+id/switchto_note"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/note_panel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <EditText
            android:id="@+id/note_input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textMultiLine" >

            <requestFocus />
        </EditText>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <Button
                android:id="@+id/comfirm"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button" />

            <Button
                android:id="@+id/cancel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button" />
        </LinearLayout>
    </LinearLayout>

</ViewSwitcher>

【问题讨论】:

  • 可以把ListView en custom Row的xml代码贴出来吗?
  • 你真的有10000种不同的观点吗?
  • 10000 可能是魔法值 :) 在 getItemViewType() 中更好地返回 IGNORE_ITEM_VIEW_TYPE。
  • getViewTypeCount 必须返回此适配器将创建的视图类型的数量。因此,如果您不需要 10000 个视图,让我们 getViewTypeCount 您需要的视图类型的确切数量
  • 什么是 mProviders ?以及它是如何设置的?

标签: android user-interface


【解决方案1】:

@mice 的评论将解决问题。

@Override
public int getItemViewType(int position) {
    return IGNORE_ITEM_VIEW_TYPE
}

因为这个问题是由listview的回收机制引起的(稍微复杂一点,我还在学习中,无法解释更多:()

更准确的是视图的缓存机制。

但它无法解释奇怪的缩放比例。

经过更多测试,我终于发现奇怪的缩放是一个兼容性问题。 将&lt;uses-sdk android:minSdkVersion="4"/&gt; 添加到AndroidManifest.xml 将修复它。

为什么?

Display display = getWindowManager()
        .getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
View v  = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
String s = "DisplayMetrics:"
        + getResources().getDisplayMetrics()
        + "\nview : "
            + v.getWidth()+"*"+v.getHeight()
            + "\nscreen:" + width + "*" + height;

之前:

之后:

所以如果不添加android:minSdkVersion,View.buildDrawingCache(boolean autoScale) 将返回错误的缓存位图,这就是发生奇怪缩放的原因。

btw:return 10000 或 getViewTypeCount 中的任何其他值没有意义。因为我发现系统从来不调用它。

【讨论】:

    【解决方案2】:

    你似乎误用了getViewTypeCount

    从您的适配器中删除以下方法

    @Override
    public int getViewTypeCount() {
        return 10000;
    }
    @Override
    public int getItemViewType(int position) {
        // TODO Auto-generated method stub
        return (position);
    }
    

    如果您希望列表中的第一项看起来不同,请在 ListView 上使用 addHeaderView(View v, Object data, boolean isSelectable) 而不是使用类型。

    【讨论】:

    • 我相信 getViewTypeCount() 是指您的列表视图将容纳多少不同的视图。例如)在聊天应用程序中,您可能需要使用不同的聊天气泡,一个用于您发送的消息,一个用于发送给您的消息。在这种情况下,我相信 getViewTypeCount 应该返回 2。然后 getItemViewType() 将用于通过告诉列表视图在某个位置使用哪个视图类型来帮助回收视图。例如)返回 1 表示发送给您的消息,返回 2 表示您发送的消息。
    • 这是正确的@Zachary,但对于 OPs 示例,他不需要视图类型,但他声明了 10000 种视图类型,这显然不适合它。
    • 您说得对,它不需要重载这些函数。我对实现 ListAdapter 接口感到困惑,您必须将这些函数与子类化 BaseAdapter 来实现,而 BaseAdapter 可以选择覆盖。作为删除函数的替代方法,可以将 getViewTypeCount() 的返回值设置为 1,将 getItemViewType() 的返回值设置为 0,这样可以解决问题,同时保持相同的结构并允许混合不同的视图。
    猜你喜欢
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多