0

I am trying to setup a tab title strip using swipes to switch between the fragments as demoed in the documentation here. It works, up to a point. The gridview shows all the images as required however, both fragment 1 and fragment 2 are showing the same images. It appears that fragment 2 is overwriting the images because if you click on the image in fragment 1, the fragment 1 details screen pops up (even though it shows an image from fragment 2).

Basically, I need my ImageAdapter (BaseAdapter) to show the correct images for each separate fragment. I don't see how the second fragment is interacting with the first if there are no static elements.

Edit: I tried changing to Picasso and the same error occurred so there has to be something in my code.

Edit2: I found this answer and it does let me redraw the grid when a fragment becomes visible but that causes a noticeable flicker and it is obvious the images were wrong. The problem has to lie somwhere with UIL/Picasso thinking the gridview in the separate fragments are the same object (they do have the same images but in different orders).

public void setupFragmentSwipes() {
    mDemoCollectionPagerAdapter =
            new DemoCollectionPagerAdapter(
                    getFragmentManager());
    mViewPager = (ViewPager) mRootView.findViewById(R.id.pager);
    mViewPager.setAdapter(mDemoCollectionPagerAdapter);
}

  public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
    String[] array = getResources().getStringArray(R.array.SortOptions);
    public DemoCollectionPagerAdapter(FragmentManager fm) {
        super(fm);
    }
    @Override
    public Fragment getItem(int i) {
        Fragment fragment = new FragmentGrid();
        Bundle args = new Bundle();

        args.putInt("mMode", mMode);
        args.putInt("mSortAorD", mSortAorD);
        args.putInt("mSortType", i);
        fragment.setArguments(args);
        return fragment
    }

    @Override
    public int getCount() {
        return array.length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return array[position];
    }
}

FragmentGrid

public class FragmentGrid extends Fragment {
public int mode;
private ArrayList<Theme> mThemes;
private GridView listView;
private static DisplayImageOptions options;
protected ImageLoader imageLoader = ImageLoader.getInstance();
protected int mSavedPosition;
private int sortType;
private int sortAorD;
@Override
    public View onCreateView(LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    // The last two arguments ensure LayoutParams are inflated
    // properly.
    View rootView = inflater.inflate(
            R.layout.fragment_collection_object, container, false);
    Bundle args = getArguments();

    mode = args.getInt("mMode", BaseConstants.ViewModes.NORMAL);

    sortType = args.getInt("mSortType", BaseConstants.Sort.POPULAR);
    sortAorD = args.getInt("mSortAorD", BaseConstants.Sort.DESC);
    listView = (GridView) rootView.findViewById(R.id.gridview2);



    options = new DisplayImageOptions.Builder()
            .showStubImage(R.drawable.ic_stub)
            .showImageForEmptyUri(R.drawable.ic_error)
            .showImageOnFail(R.drawable.ic_error)
            .cacheOnDisc(true)
            .imageScaleType(ImageScaleType.EXACTLY)
            .bitmapConfig(Bitmap.Config.RGB_565)
            .build();



    return rootView;
}
@Override
public void onResume() {
    super.onResume();
    listView.setSelection(mSavedPosition);
    ThemeManager tm = new ThemeManager(getActivity().getApplicationContext());
    mThemes = tm.getModifiedThemeList(mode);
    mThemes = tm.compare(sortType, sortAorD, checkIfTesting());
    listView.setAdapter(new ImageAdapter(mThemes));
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            mSavedPosition = position;
            Intent intent = new Intent(getActivity(), ImagePagerActivity.class);
            intent.putExtra("mMode", mode);
            intent.putExtra("mSortAorD", sortAorD);
            intent.putExtra("mSortType", sortType);
            intent.putExtra("mPosition", position);
            startActivity(intent);
        }
    });

}
public class ImageAdapter extends BaseAdapter {
    ArrayList<Theme> imageAdapterThemeList;
    public ImageAdapter(ArrayList<Theme> themes) {
        imageAdapterThemeList = themes;
    }
    @Override
    public int getCount() {
        int result = 0;
        if (imageAdapterThemeList != null) {
            result = imageAdapterThemeList.size();
        }
        return result;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
         ImageView imageView;

        if (convertView == null) {
            imageView = (ImageView) getActivity().getLayoutInflater().inflate(R.layout.item_grid_image, parent, false);
        } else {
            imageView = (ImageView) convertView;
        }

        Theme theme = imageAdapterThemeList.get(position);

        imageLoader.displayImage(theme.getImageURL(), imageView, options);

        return imageView;
    }
}

fragment_collection_object.xml

<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:horizontalSpacing="4dip"
android:numColumns="auto_fit"
android:columnWidth="150dip"
android:scrollbars="vertical"
android:stretchMode="columnWidth"
android:verticalSpacing="4dip"
android:padding="4dip" />
Community
  • 1
  • 1
easycheese
  • 5,859
  • 10
  • 53
  • 87

3 Answers3

1

The only difference between your two fragment instances is that you have mSortType in your arguments Bundle set to 0 or 1 based on the page. You only use that to set up mThemes, which you never seem to use in your ImageAdapter.

So, if you are expecting your two ImageAdapter instances to return separate results, you need to either have it pay attention to mSortType or otherwise have it vary based on the page.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • mThemes is created and then sorted based on mSortType (via compare method). mThemes is then passed into ImageAdapter and is called imageAdapterThemeList. Sort types 0 and 1 cause mThemes to be different so each ImageAdapter should be different.. The image that is shown always seems to come from fragment 1 which is created after fragment 0. If I click on one from fragment 0, it displays the correct information though. – easycheese Jul 06 '14 at 20:54
  • 1
    @easycheese: My apologies -- it is difficult to keep track of the ever-changing variable names. You might try logging `theme.getImageURL()` in `getView()` and see if that gives you clues. – CommonsWare Jul 06 '14 at 21:21
  • You did get me thinking in the right direction and I was able to find the issue. I don't understand the underlying reason though, perhaps you can take a look at the answer and tell me what I'm missing. – easycheese Jul 06 '14 at 22:01
0

I encountered a problem that sounds very similar to this a while ago. It turned out to be the animations used when swapping pages and nothing to do with the pager or adapter at all. Essentially the animation resulted in fragment1 being on top of the fragment2 but completely transparent, so the user thought they were touching fragment2, but the events were received by fragment1..which makes it behave very much like the adapter was returning the wrong fragment...

In short, if you are using animations (particularly z-order altering animations) try disabling them and see if the problem goes away. If it does, you have a problem in your animations.

Hope that helps, Good Luck.

C B J
  • 1,838
  • 16
  • 22
0

Ok, I found the answer but I don't know why. I had to change the following from:

ArrayList<Theme> imageAdapterThemeList;
public ImageAdapter(ArrayList<Theme> themes) {
    imageAdapterThemeList = themes;
}

to:

ArrayList<Theme> imageAdapterThemeList = new ArrayList<Theme>();

    public ImageAdapter(ArrayList<Theme> themes) {

        for (int i = 0; i< themes.size() ;i++) {
            imageAdapterThemeList.add(i, themes.get(i));
        }

    }

I think, rather than creating a new ArrayList I was merely pointing to the old one. This new method actually recreates it but I'm sure it's not very efficient.

easycheese
  • 5,859
  • 10
  • 53
  • 87
  • 1
    "I think, rather than creating a new ArrayList I was merely pointing to the old one" -- that would depend a bit on your implementation of `getModifiedThemeList()`. Given how you are using this `ArrayList`, you do need separate copies of the array list. It would be easier for you to use the copy constructor (`new ArrayList(themes)`). – CommonsWare Jul 06 '14 at 22:04