Android GridView。滚动时避免反弹/颠簸

时间:2014-09-03 11:49:51

标签: java android gridview adapter bounce

我的项目中使用StaggeredGridView(https://github.com/etsy/AndroidStaggeredGrid)有一个GridView。 每个项目都由ImageView和TextView组成,不同的ImageViews的高度从一个变为另一个。

当滚动回到顶部时出现问题,因为视图回收,当图像重新加载时,由于具有不同的高度,StaggeredGridView'反弹'有点烦人。

我试图删除弹跳,就像Pinterest或Etsy的应用程序一样(那些根本不反弹并且似乎保持长宽比在内存中)。我已经设法弄明白了。

以下是一些代码:

GridItemAdaptem

@Override
    public View getView(final int position, View convertView, final ViewGroup parent) {
        final Holder holder;

        if( convertView!=null ){
            holder = (Holder) convertView.getTag();
        } else {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            convertView = inflater.inflate( R.layout._grid_guide_item, parent, false );
            holder = new Holder( convertView );
            convertView.setTag(holder);
        }

        final Guide guide = this.guides.get(position);
        holder.pic.post(new Runnable() {
            @Override
            public void run() {
                try {
                    int height = Integer.parseInt( guide.getCover().getHeight() ) * holder.pic.getWidth() / Integer.parseInt(guide.getCover().getWidth());
                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( holder.pic.getWidth(), height );
                    holder.pic.setScaleType(ImageView.ScaleType.FIT_XY);
                    holder.pic.setLayoutParams(params);
                    ImageAware imageAware = new ImageViewAware( holder.pic, true);
                    imageLoader.displayImage(
                        FavoAPI.getImageURL( guide.getCoverId() ),
                        imageAware
                    );
                } catch (NotCoverException ignored) {}
            }
        } );
        holder.name.setText( guide.getName() );
        holder.user.setText( Finals.AUTHOR + guide.getOwner().getFull_name() );

        return convertView;
    }

    static class Holder {
        @InjectView( R.id._grid_item_user )
        TextView user;
        @InjectView( R.id._grid_item_name )
        TextView name;
        @InjectView( R.id._grid_item_pic)
        RoundedCornerImageView pic;

        public Holder( View view ){
            ButterKnife.inject(this, view);
        }
    }

grid_item.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/GuidePreviewGuideCardItem"
>
    <nl.favoThings.favoroute.Views.Widgets.RoundedCornerImageView
        android:id="@+id/_grid_item_pic"
        style="@style/gridItem_image"
    />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="@dimen/formDefault_tinnyMargin"
    >
        <TextView
            android:id="@+id/_grid_item_name"
            style="@style/gridItem_bigText"
            />

        <TextView
            android:id="@+id/_grid_item_user"
            style="@style/gridItem_smallText"
            android:layout_width="wrap_content"
            />
    </LinearLayout>
</LinearLayout>

ImageView的样式

<style name="gridItem_image">
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_margin">@dimen/gridItem_image_margin</item>
        <item name="android:padding">@dimen/gridItem_image_margin</item>
        <item name="android:background">@color/white</item>
        <item name="android:scaleType">fitStart</item>
        <item name="android:adjustViewBounds">true</item>
        <item name="android:src">@drawable/default_route</item>
    </style>

1 个答案:

答案 0 :(得分:0)

抛弃Runnable。只需在getView()调用中直接执行该代码即可。

正如您的代码所示,您正在UI线程上执行Runnable。这意味着你在getView()方法中使用它并没有任何好处...它也在UI线程上执行。您会看到调整大小,因为从View返回的getView()会在Runnable执行之前呈现在屏幕上。如果是,它会更新View,您会看到视觉上的变化。通过删除Runnable,您的View在呈现到屏幕之前将处于正确的大小。