Ответ 1
Я столкнулся с этой проблемой и разрешил это, установив ID для каждого ViewPager:) ViewPager не разрешает совместное использование идентификатора в том же фрагменте, даже если он является частью контекста recyclerview.
Я хочу сделать активность или фрагмент "Сведения о фото", где я показываю фотографию сверху и под ней aViewpPager, которая отображает как комментарии, так и похожие фотографии (2 вкладки). Чтобы сделать экран "прокручиваемым", чтобы я мог прокручивать вверх/вниз по обоим комментариям и нравится и слайд влево/вправо, я решил использовать RecyclerView с двумя строками:
ROW 1: фотография (ImageView).
ROW 2: SlidingTabLayout + ViewPager + FragmentPagerAdapter.
Кодирование и запуск кода, отображение изображения и slideTabLayout, но не ViewPager.
Итак, мои два основных вопроса:
1 -Что случилось с моей реализацией.
2-Есть ли альтернативное или лучшее решение для чего я хочу достичь?
Примечание: Я не хочу использовать listView с заголовком. Я хочу использовать RecyclerView, потому что проще добавлять элементы сверху/снизу из сети.
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>
CommentsAndLikesPagerAdapter.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;
}
}
CommentsFragment.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"
/>
LikesFragment.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>
Я столкнулся с этой проблемой и разрешил это, установив ID для каждого ViewPager:) ViewPager не разрешает совместное использование идентификатора в том же фрагменте, даже если он является частью контекста recyclerview.
Обновите высоту ViewPager, элементы recyclerView нуждаются в определенной высоте
<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" />
Вы можете посмотреть этот код и обновить свой код. Я использовал этот код для своего проекта и работал. Вы должны установить ViewPagerAdapter в viewpager внутри метода onBinViewHolder. Если это не сработало, я хочу помочь.
// 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);
}
/**
* 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);
}
}
<?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>
<?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>
<?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>
У меня была такая же проблема и прочитал все ответы здесь. Я опишу, как я это решаю.
Просто какой-то фон, у меня есть viewpager с вкладками вверху, который отображает 3 фрагмента при запуске приложения.
Внутри одного из фрагментов есть recyclerview с viewpager как один из элементов в представлении - позволяет вызвать этот фрагмент A:
Я вызываю это внутри Fragment A, чтобы установить адаптер RECYCLERVIEW:
FragmentOuterAdapter fragmentOuterAdapter = new FragmentOuterAdapter(getActivity(), this ); //this here refers to Fragment A - note this as this is IMPORTANT
mRecyclerView.setAdapter(fragmentOuterAdapter);
Внутри моего адаптера RECYCLERVIEW я вызываю следующее для создания viewHolder:
class ViewPagerViewHolder extends RecyclerView.ViewHolder {
ViewPager viewPager;
public ViewPagerViewHolder(View view) {
super(view);
viewPager = (ViewPager) view.findViewById(R.id.viewPager);
}
}
В onCreateViewHolder я инициализирую представление и получаю дескриптор на нем.
Важная часть кода входит в onBindViewHolder:
FragmentManager fragmentManager = fragment.getChildFragmentManager();
((ViewPagerViewHolder) holder).viewPager.setAdapter(new SubViewFragmentPagerAdapter(fragmentManager));
Объект фрагмента, который был передан в FragmentOuterAdapter, появляется здесь, где я использую объект для getChildFragmentManager().
Поскольку вы используете отображение фрагмента внутри фрагмента ЧЕРЕЗ viewpager, вам нужно использовать диспетчер дочерних фрагментов вместо диспетчера фрагментов.
Это заставит просмотрщик работать.
Попробуйте настроить ViewPager на жесткую кодированную высоту, а не на wrap-content или match-parent. У меня была странная проблема, когда мой экран был пуст, даже если мой ViewPager был заселен.
В качестве второй строки вы должны использовать линейный макет и внутри, добавляя пейджер представления вместе с виджетами tabhost, который показывает комментарии и любит фрагменты.
Вы можете использовать библиотеку https://github.com/daimajia/AndroidSwipeLayout, найденную здесь, чтобы добиться такого же эффекта более простым способом.
Я мог бы предоставить более подробную информацию, если вы заинтересованы.
Ответ, указанный Linh Nguyen, исправил его для меня, хотя у меня был немного другой случай из исходного вопроса.
В работе у меня был RecyclerView со строками:
ROW1: ViewPager с изображениями X (layout_height="200dp"
)
ROW2: текст
ROW3: ViewPager с изображениями Y (layout_height="100dp"
)
...
Поскольку я повторно использовал один и тот же макет для ROW1 и ROW3, оба ViewPagers имели тот же @+id
.
ViewPager в ROW1 работал нормально.
Но ViewPager в ROW3 вел себя так:
onCreateView()
для первой и двух окружающих страниц/фрагментов ViewPager в ROW3)Но потом я заметил, что если бы у меня было 5+ изображений в ROW3, я мог бы пронести по пустым страницам, и в итоге я мог бы видеть страницы 3, 4 и так далее. Как только я дойду до конца, возвращение к страницам 2 и 1 будет создано правильно (потому что они были созданы заново).
После предоставления ViewPager в ROW3 уникальный идентификатор все начало работать нормально.
Чтобы ответить на ваш первый вопрос "Что случилось с моей реализацией".
вы установили android:orientation="vertical"
в RelativeLayout
и в FrameLayout
.
Может быть, исправить не их там. Пожалуйста, дайте мне знать, если это подходящее решение.