0

This is surprisingly my first attempt at using fragments. I know I should have started using them ages ago but well, better late than never.

I followed this guide http://developer.android.com/training/animation/screen-slide.html

It didn't work for me so I searched here on stack and studied this answer How to implement a ViewPager with different Fragments / Layouts

However, my fragment still refuses to show up. Maybe I have done something wrong, some very basic mistake. Here is my code:

ImageGalleryFragment.java

 public class ImageGalleryFragment extends Fragment
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View v = inflater.inflate(R.layout.fragment_images, container, false);

        ImageView iv = (ImageView) v.findViewById(R.id.imageView);
        Picasso.with(getActivity()).load("https://i.stack.imgur.com/WvXbA.png".replaceAll(" ", "%20")).into(iv);

        return v;
    }

    public static ImageGalleryFragment newInstance(String text)
    {
        ImageGalleryFragment f = new ImageGalleryFragment();
        Bundle b = new Bundle();
        b.putString("image", text);

        return f;
    }
}

fragment_images.xml

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ImageView
    android:id="@+id/imageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="fitXY"
    android:src="@drawable/placeholder"/>
</LinearLayout>

Details.java (relevant parts)

int NUM_PAGES = 5;
private ViewPager mPager;
private PagerAdapter mPagerAdapter;

mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);

private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter
{
    public ScreenSlidePagerAdapter(FragmentManager fm)
    {
        super(fm);
    }

    @Override
    public Fragment getItem(int position)
    {
        return new ImageGalleryFragment().newInstance("https://i.stack.imgur.com/WvXbA.png");
    }

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

I know I'm hardcoding some stuff but that's because I was getting nullpointerexception on the following:

getArguments().getString("image")

Finally, here is my viewpager in the xml:

<android.support.v7.widget.CardView
            android:id="@+id/card_view0"
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:card_view="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            card_view:cardBackgroundColor="#ffffff"
            card_view:cardCornerRadius="4dp">

            <android.support.v4.view.ViewPager
                android:id="@+id/pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </android.support.v7.widget.CardView>

So what am I not doing or doing wrong? There is no sign of the fragment in my activity.

Community
  • 1
  • 1
Asim
  • 6,962
  • 8
  • 38
  • 61
  • please put your fragment's java code – Nirav Tukadiya Feb 25 '15 at 06:46
  • I have, haven't I? The first code. ImageGalleryFragment – Asim Feb 25 '15 at 06:47
  • Make sure you are using Fragment from v4 library and not from app. – Abhishek V Feb 25 '15 at 06:56
  • does your code compile? remove the "new" in the adapters getItem call. Put a Log in your fragments onCreateView() and see if it turns up in your logcat.... This will help us pinpoint the problem – Chris Feb 25 '15 at 06:56
  • @AbhishekV I'm using the support library. – Asim Feb 25 '15 at 07:01
  • @Chris Yes it compiles fine. I can't remove the new because the getView function expects a fragment to be returned. And yes, onCreateview of the fragment does get called. – Asim Feb 25 '15 at 07:03
  • Yes, but that is what the "newInstance" should return you. inside newInstance you are instantiating using "new" which should be what you want. You dont have to say "new newInstance()" – Chris Feb 25 '15 at 07:08
  • @Chris understood. Changed to return ImageGalleryFragment.newInstance("http://i.stack.imgur.com/WvXbA.png"); It's still not working though. Can you check the xml I posted? The layout doesn't show the viewpager at all (doesn't even show the placeholder image). – Asim Feb 25 '15 at 07:11
  • ok great, lets just try something for sanity sake... quickly place the viewpager in a normal layout like linearLayout or relativeLayout. So in other words, remove it from the CardView... Just so we can be sure the problem is not with a viewpager inside a cardview – Chris Feb 25 '15 at 07:14
  • also, when you say placeholder image, does this mean you commented out the Picasso image loader? – Chris Feb 25 '15 at 07:16
  • My fragment has an ImageView. It has a src defined (the placeholder). Picasso loads an image into the same ImageView. – Asim Feb 25 '15 at 07:18
  • Also, I've discovered a weird issue. The viewpager doesn't show if its layout_height is set to wrap_content. If i give it a fixed height, it shows up and loads the image (using Picasso) – Asim Feb 25 '15 at 07:18
  • Also, getArguments() throws a nullpointerexception when I use it instead of the hardcoded image link inside ImageGalleryFragment. Am I using it wrong? – Asim Feb 25 '15 at 07:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/71649/discussion-between-asim-and-chris). – Asim Feb 25 '15 at 07:27
  • ah great stuff man! it would seem that either the parent layout (Cardview) or the pager itself will need to have a fixed height unless the parent is set to fill_parent. – Chris Feb 25 '15 at 07:32

1 Answers1

2

The problem is with the viewPagers height as you have correctly noted. Picasso loads the image only after the view is inflated and thus already wrapped. The solution would be to either set the CardView or ViewPagers height to a fixed dp.

Another option is to write a custom ViewPager that extends ViewPager and measure the images height in onMeasure(). Then implement this custom ViewPager in your xml layout:

public class CustomViewPager extends ViewPager { //extend the android viewpager

  public CustomViewPager(Context context) {
      super(context);
  }

  public CustomViewPager(Context context, AttributeSet attrs) {
      super(context, attrs);
  }

  @Override //override onMeasure so we can measure the heights of our children
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

      int height = 0;
      for(int i = 0; i < getChildCount(); i++) {
          View child = getChildAt(i);
          child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
          int h = child.getMeasuredHeight();
          if(h > height) height = h;
      }

      heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  }

}

Then in you xml:

  <android.support.v7.widget.CardView
        android:id="@+id/card_view0"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardBackgroundColor="#ffffff"
        card_view:cardCornerRadius="4dp">

        <com.your.path.to.CustomViewPager //point this path the package where your custom class is
                    android:id="@+id/imagePager"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"/>

    </android.support.v7.widget.CardView>
Asim
  • 6,962
  • 8
  • 38
  • 61
Chris
  • 4,593
  • 1
  • 33
  • 37