0

My main objective is to create a listview, in each row a viewpager with a "ImageWordFragment" in each page, which cotains an Imageview.

Please DON'T tell me not to use viewpager inside a listview. A lots of apps are doing it, just help get to my goal.

I tried setting "setId()" but it prompts a null exception in the ViewPager variable inside the "getView" function.

The problem is the the first viewpager works in the first row of the listview. But the rest of it doesn't.

This is the xml of "fragment_word_image.xml":

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

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="LALA"/>

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/background_grey"/>

</LinearLayout>

This is the xml of "item_word.xml":

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

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

    </LinearLayout>

This is the adapter:

public class WordAdapter extends BaseAdapter {

    private AppCompatActivity activity;
    private LayoutInflater inflater;
    private List<Word> wordItems;

    public WordAdapter(AppCompatActivity activity, List<Word> wordItems) {
        this.activity = activity;
        this.wordItems = wordItems;
    }

    @Override
    public int getCount() {
        return wordItems.size();
    }

    @Override
    public Word getItem(int position) {
        return wordItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (inflater == null) {
            inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.item_word, parent, false);
        }

        FrameLayout container = (FrameLayout) convertView.findViewById(R.id.container);
        TextView type = (TextView) convertView.findViewById(R.id.type);
        TextView name = (TextView) convertView.findViewById(R.id.name);
        ImageView progress = (ImageView) convertView.findViewById(R.id.progress);

        final LinearLayout moreInfo = (LinearLayout) container.findViewById(R.id.moreInfo);
        ViewPager pager = (ViewPager) convertView.findViewById(R.id.viewPager);

        // Getting word data
        final Word w = wordItems.get(position);

        //Pager
        WordPagerAdapter adapter = new WordPagerAdapter(activity.getSupportFragmentManager(), activity, pager);

        Bundle args1 = new Bundle();
        args1.putString(ImageWordFragment.ARG_LINK, w.getImage());
        adapter.addTab(R.string.title_section1, ImageWordFragment.class, args1);

        Bundle args2 = new Bundle();
        args2.putString(ImageWordFragment.ARG_LINK, w.getImage());
        adapter.addTab(R.string.title_section1, ImageWordFragment.class, args2);

        Bundle args3 = new Bundle();
        args3.putString(ImageWordFragment.ARG_LINK, w.getImage());
        adapter.addTab(R.string.title_section1, ImageWordFragment.class, args3);

        //Notify Changes
        adapter.notifyTabsChanged();

        return convertView;
    }

    private class WordPagerAdapter extends FragmentStatePagerAdapter {

        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

        private final Context mContext;

        private final FragmentManager mFragmentManager;

        private final ViewPager mViewPager;

        final class TabInfo {

            private final Class<?> mClass;

            private final Bundle mArgs;

            private final int mTitleRes;

            TabInfo(Class<?> fragmentClass, Bundle args, int titleRes) {
                mClass = fragmentClass;
                mArgs = args;
                mTitleRes = titleRes;
            }
        }

        public WordPagerAdapter(FragmentManager fm, Context context, ViewPager pager) {
            super(fm);
            mFragmentManager = fm;
            mContext = context;

            //Setup view pager
            mViewPager = pager;
            mViewPager.setAdapter(this);
        }

        public void addTab(int titleRes, Class<?> fragmentClass, Bundle args) {
            mTabs.add(new TabInfo(fragmentClass, args, titleRes));
        }

        public void notifyTabsChanged() {
            notifyDataSetChanged();
        }

        public void setCurrentItem(int position) {
            mViewPager.setCurrentItem(position);
        }

        public void setOffscreenPageLimit(int pages) {
            mViewPager.setOffscreenPageLimit(pages);
        }

        @Override
        public Fragment getItem(int position) {
            TabInfo tab = mTabs.get(position);
            return Fragment.instantiate(mContext, tab.mClass.getName(), tab.mArgs);
        }

        @Override
        public int getCount() {
            return mTabs.size();
        }
    }

}

Thsi is the fragment:

public class ImageWordFragment extends Fragment {

    public static final String ARG_LINK = "ARG_LINK";

    @InjectView(R.id.imageView)
    ImageView imageView;

    String imageUrl;

    public ImageWordFragment() {

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        imageUrl = getArguments().getString(ARG_LINK);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_word_image, container, false);

        ButterKnife.inject(this, rootView);

        new ImageLoadTask(imageUrl, imageView);

        return rootView;
    }

}
Alex
  • 131
  • 2
  • 11
  • What doesn't work? What does the error log say? Also, you should be open minded to other options in regards to your `ViewPager` in a `ListView` idea. Curious, what other apps are following this same technique? – em_ Sep 16 '15 at 21:15
  • @ElliotM "The problem is the the first viewpager works in the first row of the listview." But the rest of the viewpagers in the other rows don't. There isn't any error logs, it just doesn't work. I'm open minded if the result is the same as having a viewpager inside the listview. I heard Netflix app was doing something similar – Alex Sep 16 '15 at 21:22
  • What do you mean by `it doesn't work`? Please be constructive. – Muhammad Babar Sep 17 '15 at 05:54
  • If you use my code you'll understand. The content of the second viewpager (and the rest of them) dont show up. And it seems as if you need to swipe twice each page to reach to he end – Alex Sep 17 '15 at 08:42
  • @John have you tried not using ButterKnife? – JulianSymes Sep 17 '15 at 15:14

1 Answers1

1

A couple of experiments indicate this is probably caused by your ViewPagers all having the same id (from the XML). Have you tried generating ids at runtime using View.generateViewId()?

JulianSymes
  • 2,135
  • 22
  • 24
  • Do you mean after `ViewPager pager = (ViewPager) convertView.findViewById(R.id.viewPager);` ? – Alex Sep 17 '15 at 16:16
  • Yes, but in addition I'd suggest - to eliminate another possible source of error - not reusing convertView but inflating every time. Not for the final code, but to see if it gets things working. – JulianSymes Sep 17 '15 at 16:24
  • Great! The `generateViewId()` and the `convertView` solution worked. Now I have a different problem. I'm using a `NonScrollListView` from [here](http://stackoverflow.com/questions/18813296/non-scrollable-listview-inside-scrollview) and I need to update the height dynamically. How can I do it ? – Alex Sep 17 '15 at 17:02
  • @John you should really accept my answer and post a new question for the new issue. – JulianSymes Sep 20 '15 at 11:59