- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要在垂直显示列表的 RecyclerView 中有一个 ViewPager(类似于水平画廊)。 RecyclerView 的每一行都有一个 ViewPager,它允许在一些图像之间滑动。 ViewPager 还将支持将传播到父 RecyclerView 的点击事件。
目前,我有以下实现:
列表适配器:
@Override
public void onBindViewHolder(MyHolder holder, int position) {
super.onBindViewHolder(holder, position);
Item listItem = get(position);
...
GalleryAdapter adapter =
new GalleryAdapter(getActivity().getSupportFragmentManager(),
item.mediaGallery);
holder.imageGallery.setAdapter(adapter);
...
}
图库适配器:
public class GalleryAdapter extends FragmentStatePagerAdapter {
private final List<Item.Gallery> mItems;
@Bind(R.id.gallery_item)
ImageView galleryView;
public SearchResultsGalleryPagerAdapter(FragmentManager fm, @NonNull ArrayList<Item.Gallery> mediaGallery) {
super(fm);
mItems = mediaGallery;
}
@Override
public Fragment getItem(int position) {
GalleryFragment fragment = GalleryFragment.newInstance(mItems.get(position));
...
return fragment;
}
@Override
public int getCount() {
return null == mItems ? 0 : mItems.size();
}
@Override
public int getItemPosition(Object object) {
//return super.getItemPosition(object);
return PagerAdapter.POSITION_NONE;
}
}
图库 fragment :
public class GalleryFragment extends Fragment {
private static final String GALLERY_ITEM_BUNDLE_KEY = "gallery_item_bundle_key";
@Bind(R.id.gallery_item)
ImageView mGalleryView;
private Item.Gallery mGalleryItem;
// Empty constructor, required as per Fragment docs
public GalleryFragment() {}
public static SearchResultsGalleryFragment newInstance(Item.Gallery galleryItem) {
GalleryFragment fragment = new GalleryFragment();
// Add the item in the bundle which will be set to the fragment
Bundle bundle = new Bundle();
bundle.putSerializable(GALLERY_ITEM_BUNDLE_KEY, galleryItem);
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGalleryItem = (Item.Gallery) getArguments().getSerializable(GALLERY_ITEM_BUNDLE_KEY);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_gallery_item, container, false);
ButterKnife.bind(this, view);
displayGalleryItem();
return view;
}
private void displayGalleryItem() {
if (null != mGalleryItem) {
Glide.with(getContext()) // Bind it with the context of the actual view used
.load(mGalleryItem.getImageUrl()) // Load the image
.centerCrop() // scale type
.placeholder(R.drawable.default_product_400_land) // temporary holder displayed while the image loads
.crossFade()
.into(mGalleryView);
}
}
}
我遇到的问题是 ViewPager 的 fragment 没有正确创建和显示。有时它们会在手动滚动后出现(但并非总是如此),在大多数情况下它们根本不会出现。
有人知道我实现的错误吗?
最佳答案
我已经设法通过直接使用 PagerAdapter
解决了这个问题。
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DecodeFormat;
import com.peoplepost.android.R;
import com.peoplepost.android.common.listener.ItemClickSupport;
import com.peoplepost.android.network.merv.model.Product;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* Custom pager adapter which will manually create the pages needed for showing an slide pages gallery.
* </p>
* Created by Ionut Negru on 13/06/16.
*/
public class GalleryAdapter extends PagerAdapter {
private static final String TAG = "GalleryAdapter";
private final List<Item> mItems;
private final LayoutInflater mLayoutInflater;
/**
* The click event listener which will propagate click events to the parent or any other listener set
*/
private ItemClickSupport.SimpleOnItemClickListener mOnItemClickListener;
/**
* Constructor for gallery adapter which will create and screen slide of images.
*
* @param context
* The context which will be used to inflate the layout for each page.
* @param mediaGallery
* The list of items which need to be displayed as screen slide.
*/
public GalleryAdapter(@NonNull Context context,
@NonNull ArrayList<Item> mediaGallery) {
super();
// Inflater which will be used for creating all the necessary pages
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// The items which will be displayed.
mItems = mediaGallery;
}
@Override
public int getCount() {
// Just to be safe, check also if we have an valid list of items - never return invalid size.
return null == mItems ? 0 : mItems.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
// The object returned by instantiateItem() is a key/identifier. This method checks whether
// the View passed to it (representing the page) is associated with that key or not.
// It is required by a PagerAdapter to function properly.
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
// This method should create the page for the given position passed to it as an argument.
// In our case, we inflate() our layout resource to create the hierarchy of view objects and then
// set resource for the ImageView in it.
// Finally, the inflated view is added to the container (which should be the ViewPager) and return it as well.
// inflate our layout resource
View itemView = mLayoutInflater.inflate(R.layout.fragment_gallery_item, container, false);
// Display the resource on the view
displayGalleryItem((ImageView) itemView.findViewById(R.id.gallery_item), mItems.get(position));
// Add our inflated view to the container
container.addView(itemView);
// Detect the click events and pass them to any listeners
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != mOnItemClickListener) {
mOnItemClickListener.onItemClicked(position);
}
}
});
// Return our view
return itemView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// Removes the page from the container for the given position. We simply removed object using removeView()
// but could’ve also used removeViewAt() by passing it the position.
try {
// Remove the view from the container
container.removeView((View) object);
// Try to clear resources used for displaying this view
Glide.clear(((View) object).findViewById(R.id.gallery_item));
// Remove any resources used by this view
unbindDrawables((View) object);
// Invalidate the object
object = null;
} catch (Exception e) {
Log.w(TAG, "destroyItem: failed to destroy item and clear it's used resources", e);
}
}
/**
* Recursively unbind any resources from the provided view. This method will clear the resources of all the
* children of the view before invalidating the provided view itself.
*
* @param view
* The view for which to unbind resource.
*/
protected void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
/**
* Set an listener which will notify of any click events that are detected on the pages of the view pager.
*
* @param onItemClickListener
* The listener. If {@code null} it will disable any events from being sent.
*/
public void setOnItemClickListener(ItemClickSupport.SimpleOnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
/**
* Display the gallery image into the image view provided.
*
* @param galleryView
* The view which will display the image.
* @param galleryItem
* The item from which to get the image.
*/
private void displayGalleryItem(ImageView galleryView, Item galleryItem) {
if (null != galleryItem) {
Glide.with(galleryView.getContext()) // Bind it with the context of the actual view used
.load(galleryItem.getImageUrl()) // Load the image
.asBitmap() // All our images are static, we want to display them as bitmaps
.format(DecodeFormat.PREFER_RGB_565) // the decode format - this will not use alpha at all
.centerCrop() // scale type
.placeholder(R.drawable.default_product_400_land) // temporary holder displayed while the image loads
.animate(R.anim.fade_in) // need to manually set the animation as bitmap cannot use cross fade
.thumbnail(0.2f) // make use of the thumbnail which can display a down-sized version of the image
.into(galleryView); // Voilla - the target view
}
}
}
以及更新的父 RecyclerView 的 onBindViewHolder():
@Override
public void onBindViewHolder(MyHolder holder, int position) {
super.onBindViewHolder(holder, position);
Item listItem = get(position);
...
GalleryAdapter adapter =
new GalleryAdapter(getActivity(), product.mediaGallery);
// Set the custom click listener on the adapter directly
adapter.setOnItemClickListener(new ItemClickSupport.SimpleOnItemClickListener() {
@Override
public void onItemClicked(int position) {
// inner view pager page was clicked
}
});
// Set the adapter on the view pager
holder.imageGallery.setAdapter(adapter);
...
}
我注意到内存使用量略有增加,但用户界面非常流畅。我想可以对保留的页面数量以及销毁和恢复页面的方式进行一些进一步的优化。
我希望这对处于类似情况的其他人有所帮助。
关于android - RecyclerView 中的 ViewPager 作为行项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37789091/
我目前面临将 ViewPager 放入另一个 ViewPager 中的问题,两者都可滑动。我成功创建了我的第一个 ViewPager,它包含三个页面,中间一个是第二个(内部)ViewPager,其中包
在我的主要 Activity 中,我有一个水平 viewpager。在 viewpager 的一个 fragment 中,我有另一个垂直 viewpager。两者都很好。但是对于水平 viewpage
我想创建一个 ViewPager(包含三个项目),其中每个 View 都是另一个 ViewPager(包含两个项目)。用户然后像这样滑动项目: ViewPager1[0] ViewPager2[0]
如何修复这个错误 setupWithViewPager(android.support.v4.view.ViewPager) in TabLayout cannot br applied to (an
我有一个包含 3 张图片的数组的 viewPage,我想在缩放其中一张时锁定 viewPager,因为当我在右侧滚动时,会出现下一张照片!这是我的代码 enter code here public
我是第一次实现 ViewPager,我遇到了一些问题,因为我收到以下错误: 06-20 10:40:51.366 11377-11377/com.example.ruelas.elite E/Andr
我真的是 android 的新手,如果对我的类(class)作业有任何帮助,我将不胜感激。 我需要做的: 1) 在一个 Activity 中有两个 ViewPagers(未嵌套) 2)两个ViewPa
我正在自定义我的 Android 应用程序以在四个方向上滑动,我正在使用 ViewPager 水平 和 VerticalViewPager 滑动垂直滑动(这就像对 DirectionalViewPag
我需要为平板电脑创建一个 ViewPager,在平板电脑的左侧会有导航按钮供用户选择。例如。 左侧导航将有 4 个图像按钮,每个项目将用户带到不同的教程。每个图像按钮都会加载一个 ViewPager。
我用过Vertical Viewpager在我的显示数据集合的项目中。在单个数据(项目)中,我有更多图像要显示。所以我尝试使用 viewpager。 但是当我水平滚动时,它会阻止垂直 Viewpage
我有一个父级 ViewPager,它的每个页面都包含一个子级 ViewPager。子 ViewPager 可能包含一个 ListView 或一个垂直的 ScrollView。我想将子级 ViewPag
我的任务是创建一个非常不正统的布局,只能通过另一个 viewpager 的第二个 Pane 内的 viewpager 来完成,幸运的是外部 viewpager 需要被锁定所以任务更现实一些,但是意外的
目标是根据屏幕方向(纵向或横向)以不同的布局在屏幕上显示两个 fragment ( fragment A、 fragment B)。 当设备处于纵向模式时,一次仅显示 Frag A 和 Frag B
我想禁用父 viewpager 中的子 viewpager 的滑动。 我目前使用这个自定义子 viewpager public class CustomViewPager extends ViewPa
我有两个 ViewPager - 一个在另一个下面。现在客户希望我们添加扩展底部 ViewPager(具有三个 ListView)以覆盖顶部 ViewPager 的可能性。当我将两个 ViewPage
我用谷歌搜索了这个问题很多天。找到一个解决方案,在Viewpager的开头和结尾添加一个空白View。当viewpager.getcurrentItem()==0时,则重新指向1。在我看来这种做法非常
我从适配器设置标题后,标题未出现在 PagerTabStrip 中 这是我的 Activity public class MainActivity extends AppCompatActivity
我有一个 ViewPager,其中包含多个 TextView,它们具有不同的字体大小。此外,我还获得了增加/减少字体大小的按钮,通过添加其默认大小加上一个名为 STEP 的值(该值通过 inc/dec
我有一个嵌套的 ViewPager,效果非常好。唯一的问题是,一旦子 ViewPager 位于最后一项并且我进一步滚动,父 ViewPager 就会滚动。我不想要这种行为。 我如何实现这一目标? 这是
我想显示一个带有滑动抽屉的 Viewpager。Viewpager 用于滚动图像,我想在该 viewpager 的顶部放置一个滑动抽屉(从顶部到按钮)。 我附上了我的示例代码。如果您对如何实现此屏幕有
我是一名优秀的程序员,十分优秀!