Saturday, April 9, 2016

ViewPagers in a ListView showing blank list items

Leave a Comment

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

<?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 ?

6 Answers

Answers 1

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

Answers 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.

Answers 3

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> 

Answers 4

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.

Answers 5

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

Answers 6

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

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment