8

[EDIT]: Thank you for all the meaningful answers, the problem is now solved, thank to your help. Similar issue: Android: I am unable to have ViewPager WRAP_CONTENT

I'm trying to implement the UI of my app : I want a ListView with a ViewPager in each row.

Here are my files :

MainActivity.java

package com.condi;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.Menu;

public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setListAdapter(new CardListAdapter(this, getFragmentManager()));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

CardListAdapter.java

package com.condi;

import java.util.List;

import android.app.FragmentManager;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class CardListAdapter extends BaseAdapter {

    private Context context;
    private FragmentManager fragmentManager;
    private List<Profile> profiles;

    CardListAdapter(Context context, FragmentManager fragmentManager) {
        this.context = context;
        this.fragmentManager = fragmentManager;
        this.profiles = new DatabaseHelper(context).getProfiles();
    }

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

    @Override
    public Profile getItem(int position) {
        return profiles.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = View.inflate(context, R.layout.profile_card, null);
        CardPagerAdapter mCardPagerAdapter = new CardPagerAdapter(
                fragmentManager);
        ViewPager viewPager = (ViewPager) convertView.findViewById(R.id.pager);
        viewPager.setAdapter(mCardPagerAdapter);
        viewPager.setId(R.id.pager);
        return convertView;
    }
}

profile_card.xml (issue came from wrap_content).

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="4dp"
        android:layout_marginLeft="6dp"
        android:layout_marginRight="6dp"
        android:layout_marginTop="4dp"
        android:background="@drawable/card_background"
        android:orientation="vertical" >

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

</FrameLayout>

CardPagerAdapter.java

package com.condi;

import android.app.Fragment;
import android.app.FragmentManager;
import android.support.v13.app.FragmentPagerAdapter;

public class CardPagerAdapter extends FragmentPagerAdapter {

    public CardPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
        case 0:
            return new Fragment1();
        case 1:
            return new Fragment2();
        }
        return null;
    }

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

Fragment1.java

package com.condi;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment1 extends Fragment {

    public Fragment1() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.preference_category, container, false);
    }
}

Fragment2.java

package com.condi;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment2 extends Fragment {

    public Fragment2() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.preference_category, container, false);
    }
}

The database that furnishes the profiles is working well. The problem is that I am getting an empty list with the correct number of item, but no ViewPager displayed at all. screenshot of my app

What am I doing wrong ?

Community
  • 1
  • 1

6 Answers6

5

Try to change your ViewPager's height in xml. wrap_content does not work.

twlkyao
  • 14,302
  • 7
  • 27
  • 44
  • It made a long time since I posted this issue, _many thanks_ for the answer ! I could really not know that by myself ! –  Jul 17 '14 at 22:12
2

To make is clear, its a bad practice to use viewpagers inside a list view as this design hits the ui performance. The best way to handle this problem is:

  1. To do manual inflation of viewpagers and add to a layout.

  2. Add a unique id to each viewpager so that it is identified uniquely by the system.

  3. Extend a custom viewpager and onmeasure() measure the child layout inflated at the page selected. You can do this by setting a callback in your custom viewpager and trigger the callback from viewpagers onPageScrolled listener, passing the position to identify the child layout.
  4. In your onMeaure() method measure the child layout height and set it as the viewpagers height using super.onMeasure() passing the newly measured specs.

Key points to make a note of :

N.B. Set a unique id to the viewpager inflated by you.

  • Thank you, I take note of it. The app was not complex enough at this point for performances issues to be noticed, so this really helps! –  Apr 10 '16 at 12:25
2

try this problem in layout height

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

 <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="4dp"
    android:layout_marginLeft="6dp"
    android:layout_marginRight="6dp"
    android:layout_marginTop="4dp"
    android:background="@drawable/card_background"
    android:orientation="vertical" >

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

</FrameLayout>
wadali
  • 2,221
  • 1
  • 20
  • 38
  • `wrap_content` was definetely not the solution. This is better. Thank you! –  Apr 10 '16 at 12:28
  • @Josual could you please tell me how u sort out if its not definitely solution . – wadali Apr 11 '16 at 06:34
  • 1
    I mean the layout I chose (`android:layout_height="wrap_content"`) was provoking an issue, so was really not the solution. On the other hand, what you advised (`android:layout_height="match_parent"`) is better as it avoid the `wrap_content` causing the issue. –  Apr 17 '16 at 19:10
1

It's a bad practice to use wrap_content for your viewpager's height. You can use match_parent or a static dp for your viewpager's height.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="4dp"
        android:layout_marginLeft="6dp"
        android:layout_marginRight="6dp"
        android:layout_marginTop="4dp"
        android:background="@drawable/card_background"
        android:orientation="vertical" >

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

</FrameLayout>

If it's a must to use wrap_content for your viewpager's height you can override your viewpager's onMeasure() and calculate height. Here's an example below about it.

Android: I am unable to have ViewPager WRAP_CONTENT

I hope this'll help you.

Community
  • 1
  • 1
savepopulation
  • 11,736
  • 4
  • 55
  • 80
0

ViewPager doesn’t support wrap_content as it stands now because it doesn’t load all of its children at the same time, meaning it can’t get an appropriate measurement. You must fix View's height in your xml or create a custom ViewPager (read more at here) and use it in your xml

Community
  • 1
  • 1
tjeubaoit
  • 986
  • 7
  • 7
0

Try using a fixed height ViewPager inside the ListView.ViewPager does not support wrap_content

Ravi Theja
  • 3,371
  • 1
  • 22
  • 34