在GridView中使用ArrayAdapter和ViewFlipper将位置0多次调用getView,导致图像显示在任何位置

时间:2015-11-28 18:55:34

标签: android gridview android-arrayadapter viewflipper getview

我正在尝试为我的Android应用程序创建一个可滚动图像的gridView。每个Grid包含textView作为标题和viewFlipper,每个viewflipper都使用imageView自动更改图像。我正在使用具有holder图案的ArrayAdapter来设置视图。

问题陈述:

我能够让设置正常工作,但遇到了一个重大问题。问题是每个网格的ViewFlipper显示其他所有其他网格的图像,但textview即标题正确显示。理想情况下,每个网格的ViewFlipper应显示在其自己的集合中翻转的图像。但它也显示了其他网格的viewflipper图像的图像。

当我查看日志时,我可以看到getView在大多数情况下都是零位置调用。我无法理解它的行为。根据我的理解,我已经正确地完成了所有工作,并且每个网格应该在其自己的图像集之间翻转图像。但它没有按照预期工作。

适配器代码: -

public class GalleryImageAdapter extends ArrayAdapter<GalleryImage> {
    public GalleryImageAdapter(Context context, int resource) {
        super(context, resource);
    }


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


        if( convertView == null ) {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(getContext()).inflate( R.layout.view_gallery_thumbnail, parent, false );

            holder.vp = (ViewFlipper) convertView.findViewById( R.id.viewFlipper );

            holder.caption=(TextView) convertView.findViewById(R.id.textView);
            convertView.setTag( holder );

        } else {
            holder = (ViewHolder) convertView.getTag();

        }


        holder.caption.setText(getItem(position).getCaption());
        Log.e("GalleryAdapter", "Caption-out" + getItem(position).getCaption());

       RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                                                       RelativeLayout.LayoutParams.MATCH_PARENT);



        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_START);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);


        for (int i = 1; i <= 4; i++) {

            String slideUrl = null;
            holder.image1 = new ImageView(getContext());
            holder.image1.setScaleType(ImageView.ScaleType.FIT_XY);
            holder.image1.setAdjustViewBounds(true);
            holder.image1.setLayoutParams(layoutParams);


            if (getItem(position).getCaption().equals("AD")){

                slideUrl = "http://www.example.com/projects/musicvideos/img/"+ getItem(position).getSlideBg(i) ;

            }else {

                slideUrl = "http://www.example.com/vi/" + getItem(position).getSlideBg(i) + "/xyz.jpg";
            }

            Log.e("GalleryAdapter", "slideUrl" + slideUrl);

            Picasso.with(getContext()).load(slideUrl)
         .placeholder(getContext().getResources().getDrawable(R.drawable.place))
               .error(getContext().getResources().getDrawable(R.drawable.place))
                    .into(holder.image1);

            holder.vp.addView(holder.image1);
        }

        holder.vp.setInAnimation(getContext(), android.R.anim.fade_in);
        holder.vp.setOutAnimation(getContext(), android.R.anim.fade_out);

        holder.vp.setAutoStart(true);
        holder.vp.setFlipInterval(4000);

        return convertView;
    }

    private class ViewHolder {
        ImageView   image1;
        ViewFlipper vp;
        TextView    caption;

    }
}

view_gallery_thumbnail.xml: -

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:id="@+id/textView"
        android:textColor="#304f9f"
        android:textColorHighlight="#304f9f"
        android:textStyle="bold"
        android:textSize="15sp"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>

    <ViewFlipper
        android:id="@+id/viewFlipper"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/textView"
        />


</RelativeLayout>

我正在动态获取数据并且日志确认数据正在被正确获取但是适配器在某种程度上没有以正确的顺序显示它。我正在使用毕加索进行图像显示。

我在过去的15天里遇到了这个问题而没有任何成功。我已阅读并尝试了对stackoverflow中提到的类似问题的所有建议,但没有任何成功。

请帮忙。

1 个答案:

答案 0 :(得分:1)

我认为您的问题是,当网格项目被回收时,您永远不会从任何ViewFlipper中删除任何视图。这意味着ViewFlipper已经有来自之前getView()来电的孩子,现在您在回收时会添加更多子视图。一个简单的单行修复是在for循环之前删除所有以前的子节点:

holder.vp.removeAllViews();
for (int i = 0; i < 4; i++) { ... }

或者,您可以在ImageView标记内的布局XML中放置四个ViewFlipper,并将新图像绑定到它们,而不是每次回收时实际删除,构建和添加新视图(它也会更有效率)。在这种情况下,您的ViewHolder应该包含其中的所有四个,并且您不应该使用任何addView()removeAllViews()来电。您还必须在加载正确的图像时调用imageView.setImageBitmap(null)清除当前图像,以便用户看不到先前绑定的错误图像。

修改

将ImageView放在您的布局中:

<RelativeLayout ... >
    <TextView ... />
    <ViewFlipper ... >
        <!-- HERE -->
        <ImageView android:id="@+id/image1" ... />
        <ImageView android:id="@+id/image2" ... />
        <ImageView android:id="@+id/image3" ... />
        <ImageView android:id="@+id/image4" ... />
    </ViewFlipper>
</RelativeLayout>

更新ViewHolder以保存ImageViews。你必须找到它们并在convertView为空时分配它们。

class ViewHolder {
    ViewFlipper viewFlipper;
    TextView textView;
    ImageView[] images;
}

然后你的绑定逻辑不需要删除或添加任何视图到ViewFlipper,只需更新图像。

for (int i = 0; i < 4; i++) {
    ImageView imageView = holder.images[i];
    // This is a recycled view, so clear the previous image, otherwise there
    // might be flickering in the UI
    imageView.setImageBitmap(null);
    // load proper image for this item
    String url = ...
    Picasso.with(getContext()).load(url)
        ...
        .into(imageView);
}