web-dev-qa-db-fra.com

Le viewpager ne s'affiche pas dans la rangée RecyclerView

Je souhaite créer une activité ou un fragment 'Détails de la photo' dans lequel j'affiche la photo au-dessus et au-dessous de celle-ci. Un visualiseur de pages affiche les commentaires et les préférences de la photo associée (2 onglets) . Afin de rendre l'écran 'Scrollable' afin que je puisse faire défiler les commentaires et les goûts vers le haut/bas et faire glisser gauche/droite, j'ai décidé d'utiliser un RecyclerView avec 2 lignes:

ROW 1: La photo (ImageView).

ROW 2: SlidingTabLayout + ViewPager + FragmentPagerAdapter.

Le code compiler et exécuter, affiche l'image et le slideTabLayout mais pas le ViewPager.

Donc, mes deux questions principales sont:

1-Quel est le problème avec ma mise en œuvre.

2-Existe-t-il une solution alternative ou meilleure pour ce que je veux réaliser?

Remarque: Je ne souhaite pas utiliser un listView avec en-tête. Je souhaite utiliser RecyclerView car il est plus facile d'ajouter des éléments en haut/en bas du réseau.

PhotoDetailsActivity.Java

public class MainActivity extends ActionBarActivity {
    RecyclerView recyclerViewPhotoDetails;

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

        this.recyclerViewPhotoDetails = (RecyclerView) this.findViewById(R.id.recycler_view_photo_details);
        this.recyclerViewPhotoDetails.setLayoutManager(new LinearLayoutManager(this));
        this.recyclerViewPhotoDetails.setAdapter(new PhotoDetailsRecyclerAdapter(this.getSupportFragmentManager()));
    }
}

PhotosDetailsRecyclerAdapter.Java

public class PhotoDetailsRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int ROW_IMAGE = 0;
    private static final int ROW_LIKES_AND_COMMENTS = 1;
    private static final int TOTAL_ROWS = 2;

    private FragmentManager fragmentManager;

    public PhotoDetailsRecyclerAdapter(FragmentManager fragmentManager) {
        this.fragmentManager = fragmentManager;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return ROW_IMAGE;
        } else {
            return ROW_LIKES_AND_COMMENTS;
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType == ROW_IMAGE) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_image, parent, false);
            return new ImageViewHolder(view);
        } else {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_comments_and_likes, parent, false);
            return new CommentsAndLikesViewHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
    }

    @Override
    public int getItemCount() {
        return TOTAL_ROWS;
    }

    public class ImageViewHolder extends RecyclerView.ViewHolder {
        public ImageViewHolder(View itemView) {
            super(itemView);
        }
    }

    public class CommentsAndLikesViewHolder extends RecyclerView.ViewHolder {
        private SlidingTabLayout slidingTabLayout;
        private ViewPager viewPager;

        public CommentsAndLikesViewHolder(View view) {
            super(view);

            slidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tab_layout_comments_and_likes);
            viewPager = (ViewPager) view.findViewById(R.id.view_pager_comments_and_likes);

            viewPager.setAdapter(new CommentsAndLikesPagerAdapter(fragmentManager));
            slidingTabLayout.setDistributeEvenly(true);
            slidingTabLayout.setViewPager(viewPager);
        }
    }
}

activity_main.xml

<Android.support.v7.widget.RecyclerView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/recycler_view_photo_details"
    Android:scrollbars="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    />

layout_image.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"
    Android:orientation="vertical"
    >

    <ImageView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:adjustViewBounds="true"
        Android:scaleType="centerCrop"
        Android:src="@drawable/img"
        />

</FrameLayout>

layout_comments_and_likes.xml

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

    <org.bitbucket.androidapp.SlidingTabLayout
        Android:id="@+id/sliding_tab_layout_comments_and_likes"
        Android:layout_width="match_parent"
        Android:layout_height="48dp"
        Android:background="@Android:color/darker_gray"
        />

    <Android.support.v4.view.ViewPager
        Android:id="@+id/view_pager_comments_and_likes"
        Android:layout_height="match_parent"
        Android:layout_width="match_parent"
        Android:background="@Android:color/holo_blue_dark"
        />

</LinearLayout>

CommentairesAndLikesPagerAdapter.Java

public class CommentsAndLikesPagerAdapter extends FragmentPagerAdapter {
    private static final int TOTAL_TABS = 2;

    private String[] tabs = { "comments", "likes" };

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

    @Override
    public Fragment getItem(int position) {
        if(position == 0) {
            return new CommentsFragment();
        } else {
            return new LikesFragment();
        }
    }

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

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

CommentairesFragment.Java

 public class CommentsFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_comments, container, false);
        RecyclerView recyclerViewComments = (RecyclerView) view.findViewById(R.id.recycler_view_comments);
        recyclerViewComments.setLayoutManager(new LinearLayoutManager(this.getActivity()));
        recyclerViewComments.setAdapter(new CommentsRecyclerAdapter());
        return view;
    }
}

fragment_comments.xml

<Android.support.v7.widget.RecyclerView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/recycler_view_comments"
    Android:scrollbars="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    />

J'aimeFragment.Java

public class LikesFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_likes, container, false);
        RecyclerView recyclerViewLikes = (RecyclerView) view.findViewById(R.id.recycler_view_likes);
        recyclerViewLikes.setLayoutManager(new LinearLayoutManager(this.getActivity()));
        recyclerViewLikes.setAdapter(new LikesRecyclerAdapter());
        return view;
    }
}

fragment_likes.xml

<Android.support.v7.widget.RecyclerView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/recycler_view_likes"
    Android:scrollbars="vertical"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    />

layout_comment.xml

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

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_centerInParent="true"
        Android:text="Comment"
        />

</RelativeLayout>

layout_like.xml

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

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_centerInParent="true"
        Android:text="Like"
        />

</RelativeLayout>
19
Brahim Boulkriat

J'ai rencontré ce problème et résolu ce problème en définissant l'ID de chaque ViewPager:) ViewPager n'autorise pas le partage de l'ID dans le même fragment, même s'il fait partie d'un contexte recyclerview. 

pagerHolder.pager.setId(position);
34
Linh Nguyen

Mettez à jour la hauteur de ViewPager, les éléments de recyclerView ont besoin d'une hauteur spécifique 

<Android.support.v4.view.ViewPager
    Android:id="@+id/view_pager"
    Android:layout_height="300dp"
    Android:layout_width="match_parent"
    Android:background="@Android:color/holo_blue_dark" />

Vous pouvez regarder ce code et mettre à jour votre code. J'ai utilisé ce code mon projet et travaillé. Vous devez définir ViewPagerAdapter sur viewpager dans la méthode onBinViewHolder. Si cela ne fonctionne pas, je veux aider.

RecylerviewAdapter

    // Replace the contents of a view (invoked by the layout manager)
   @Override
   public void onBindViewHolder(ViewHolder holder, int position) {
      // - get element from your dataset at this position
      // - replace the contents of the view with that element
      initializeViews("Mustafa", holder, position);
   }

   private void initializeViews(final String object, final ViewHolder holder, int position) {
      holder.textViewCount.setText("5");
      holder.imageViewStar.setImageResource(R.drawable.info);
      holder.imageViewFavorite.setImageResource(R.drawable.info);
      ViewPagerBoundariesAdapter adapter = new ViewPagerBoundariesAdapter(activity, new ArrayList<ViewPagerItem>(), listener);
      holder.viewPager.setAdapter(adapter);
      holder.viewPager.setClipToPadding(false);
      holder.viewPager.setPadding(40, 0, 40, 0);
   }

ViewPagerAdapter

/**
 * Created by MustafaS on 10.3.2015.
 */
public class ViewPagerBoundariesAdapter extends PagerAdapter {
   private ArrayList<ViewPagerItem>    pagerItems;
   private LayoutInflater              inflater;
   private Context                     context;
   private ViewPagerItemClickInterface listener;

   public ViewPagerBoundariesAdapter(Context context, ArrayList<ViewPagerItem> pagerItems, ViewPagerItemClickInterface callback) {
      super();
      this.pagerItems = pagerItems;
      this.context = context;
      this.listener = callback;
      inflater = LayoutInflater.from(context);
   }

   @Override
   public Object instantiateItem(ViewGroup container, int position) {

      LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.row_viewpager, container, false);
      ImageView imageViewCampaign = (ImageView) layout.findViewById(R.id.imageview_campaign);
      TextView textViewCampaign = (TextView) layout.findViewById(R.id.textview_campaign);
      imageViewCampaign.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            listener.onViewPagerItemClick(1);
         }
      });
      // textViewCampaign.setText("Lorem ipsum dolor sit amet\n" + "aliquam nec nisi in lorem");
      imageViewCampaign.setImageDrawable(context.getResources().getDrawable(R.drawable.nusret));
      container.addView(layout);
      return layout;
   }

   @Override
   public void destroyItem(ViewGroup container, int position, Object object) {
      ((ViewPager) container).removeView((View) object);
   }

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

   @Override
   public boolean isViewFromObject(View view, Object obj) {
      return view.equals(obj);
   }

}

recylerview xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical">
    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/listview_brand"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />
</LinearLayout>

recylerview row xml

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

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_marginBottom="8dp"
        Android:layout_marginLeft="8dp"
        Android:orientation="horizontal">

        <ImageView
            Android:id="@+id/imageview_favorite"
            Android:layout_width="32dp"
            Android:layout_height="32dp"
            Android:layout_gravity="center" />

        <TextView
            Android:id="@+id/textview_brand_name"
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"
            Android:gravity="center_vertical"
            Android:paddingLeft="8dp"
            Android:text="Gucci"
            Android:textSize="@dimen/standart_text_size" />

        <FrameLayout
            Android:layout_width="32dp"
            Android:layout_height="32dp"
            Android:layout_marginRight="8dp">

            <ImageView
                Android:id="@+id/imageview_star"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent" />

            <TextView
                Android:id="@+id/textview_count"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_gravity="center"
                Android:ellipsize="end"
                Android:gravity="center"
                Android:singleLine="true"
                Android:textSize="@dimen/standart_text_size" />
        </FrameLayout>
    </LinearLayout>

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

Viewpager row xml

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

    <ImageView
        Android:id="@+id/imageview_campaign"
        Android:layout_width="match_parent"
        Android:layout_height="@dimen/parallax_image_height"
        Android:layout_marginLeft="4dp"
        Android:layout_marginRight="4dp"
        Android:adjustViewBounds="true"
        Android:scaleType="centerCrop" />

    <TextView
        Android:id="@+id/textview_campaign"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:paddingLeft="4dp"
        Android:paddingRight="4dp"
        Android:paddingTop="8dp"
        Android:text="Lorem ipsum dolor sit amet
aliquam nec nisi in lorem"
        Android:textSize="@dimen/standart_text_size" />
</LinearLayout>
3
mustafasevgi

J'ai eu le même problème et j'ai lu toutes les réponses ici. Je vais décrire comment je résous ceci.

Juste un peu de fond, j'ai un viewpager avec des onglets en haut qui affiche 3 fragments lorsque l'application démarre.

À l'intérieur de l'un des fragments se trouve une vue recyclée avec un viewpager comme l'un des éléments de la vue - appelons ce fragment A:

J'appelle cela à l'intérieur du fragment A pour définir l'adaptateur RECYCLERVIEW:

FragmentOuterAdapter fragmentOuterAdapter  = new FragmentOuterAdapter(getActivity(), this ); //this here refers to Fragment A - note this as this is IMPORTANT
mRecyclerView.setAdapter(fragmentOuterAdapter);

Dans mon adaptateur RECYCLERVIEW, j'appelle ce qui suit pour créer le viewHolder:

class ViewPagerViewHolder extends RecyclerView.ViewHolder {
    ViewPager viewPager;
    public ViewPagerViewHolder(View view) {
        super(view);
        viewPager = (ViewPager) view.findViewById(R.id.viewPager);
    }
}

Sous onCreateViewHolder, j'initialise la vue et ai une poignée dessus.

L'important morceau de code vient de onBindViewHolder:

        FragmentManager fragmentManager = fragment.getChildFragmentManager();
        ((ViewPagerViewHolder) holder).viewPager.setAdapter(new SubViewFragmentPagerAdapter(fragmentManager));

L'objet fragment qui a été passé dans FragmentOuterAdapter apparaît ici où j'utilise l'objet pour getChildFragmentManager ().

Étant donné que vous utilisez l'affichage d'un fragment à l'intérieur d'un fragment PAR le viewpager, vous devez utiliser le gestionnaire de fragments enfant à la place du gestionnaire de fragments.

Cela fera fonctionner le viewpager.

2
Simon

Essayez de configurer votre ViewPager pour avoir une hauteur codée en dur plutôt que du contenu intégré ou du parent de correspondance. J'ai eu un problème étrange où mon écran serait vide même si mon ViewPager était rempli.

0
user2403795

En tant que deuxième ligne, vous devez utiliser une disposition linéaire et ajouter à l'intérieur le pageur de vue ainsi que le widget tabhost qui affiche les commentaires et aime les fragments.

Vous pouvez utiliser la bibliothèque https://github.com/daimajia/AndroidSwipeLayout trouvée ici pour obtenir le même effet plus simplement.

Je pourrais fournir plus de détails si vous êtes intéressé.

0
codename_47

La seule façon qui a fonctionné pour moi est d'utiliser quelque chose de nouveau apparu dans Android Support Library v7: utiliser Horizontal Recyclerview avec PagerSnapHelper pour obtenir des résultats similaires à ceux de ViewPager

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerview.setLayoutManager(new LinearLayoutManager(context,
                        LinearLayoutManager.HORIZONTAL,false));
recyclerview.setAdapter(adapter);
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
0
Shyam Sunder

La réponse donnée par Linh Nguyen l'a corrigée pour moi, bien que mon cas soit légèrement différent de celui de la question initiale.

Dans une activité, j'avais RecyclerView avec des lignes:
ROW1: ViewPager avec X images (layout_height="200dp")
ROW2: texte
ROW3: ViewPager avec Y images (layout_height="100dp")
...

Comme je réutilisais la même présentation pour ROW1 et ROW3, ​​les deux ViewPagers avaient le même @+id.
Le ViewPager dans ROW1 a bien fonctionné.
Mais ViewPager dans ROW3 se comportait comme ceci:

  • Lors du chargement initial de l'écran, la méthode de création de page ViewPager serait appelée (onCreateView() pour la première et les deux pages environnantes/fragments de ViewPager dans ROW3).
  • Il semblait que rien ne soit rendu (pages vides)

Mais ensuite, j'ai remarqué que si j'avais 5 images ou plus dans ROW3, ​​je pouvais faire défiler les pages vides et éventuellement voir les pages 3, 4, etc. Une fois que j'ai atteint la fin, revenir aux pages 2 et 1 serait créé correctement (car ils ont été recréés).

Après avoir attribué un identifiant unique à ViewPager dans ROW3, ​​tout a bien fonctionné.

0
trav3ll3r