Android InvalidStateException on ViewPager when setting page limit too small - android

I have a problem with my ViewPager Image slider gallery. I am setting my page limit to 3 but then my app craches on the third image because the child has already a parent. I set the limit to this number because I want to avoid large memory leaks, event with 3 images it uses up like 150Mb of allocated memory which is incredibly huge ammount. Maybe if I resize the image before uploading I can get them to work with more pages ? Anyways, here is my code for the viewPager:
ViewPager mViewPager = (ViewPager) findViewById(R.id.imagepager);
ViewerAdapter adapter = new ViewerAdapter(this);
//adapter.notifyDataSetChanged();
mViewPager.setAdapter(adapter);
mViewPager.setOffscreenPageLimit(3);
mViewPager.setCurrentItem(number);
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
time.setText(caluculateTimeAgo(MainActivity.time[position]));
if (MainActivity.distances[position] < 1000) {
dist.setText(String.valueOf(MainActivity.distances[position]) + "m");
} else {
long f = (long) (MainActivity.distances[position] / 1000);
dist.setText(String.valueOf(f) + "km");
}
author.setText(MainActivity.users[position]);
text.setText(MainActivity.text1[position]+MainActivity.tags[position]);
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
and here is my adapter definition:
public class ViewerAdapter extends PagerAdapter {
Context mContext;
public ViewerAdapter(Context context) {
mContext = context;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
LayoutInflater mLayoutInflater;
#Override
public int getCount() {
return MainActivity.imgLink.length;
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == (View) arg1;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
Picasso.with(container.getContext()).cancelRequest((ImageView) object);
}
#Override
public CharSequence getPageTitle(int position) {
return (position + "/" + getCount());
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
final View itemView = mLayoutInflater.inflate(R.layout.pager_item,container,false);
final ImageView photo = (ImageView) itemView.findViewById(R.id.photoSlide);
photo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fullscreen = ((BitmapDrawable)photo.getDrawable()).getBitmap();
Intent intent = new Intent(ShowMarkerContent.this, FullScreenImageActivity.class);
startActivity(intent);
}
});
Picasso.with(container.getContext()).load("MyWebsite" + MainActivity.imgLink[position]).into(photo);
container.addView(photo);
return photo;
}
}

Well, I managed to make a work-around for this problem. I forgot to set the cropping of the photo and therefore the photos were too large for this. And also, I set the offScreenPageLimit to 30 to avoid this error (This is that work-around because with large quantity of image it will come to out of memory error) So now, here is my adapter code:
#Override
public Object instantiateItem(ViewGroup container, int position) {
final View itemView = mLayoutInflater.inflate(R.layout.pager_item,container,false);
final ImageView photo = (ImageView) itemView.findViewById(R.id.photoSlide);
photo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fullscreen = ((BitmapDrawable)photo.getDrawable()).getBitmap();
Intent intent = new Intent(ShowMarkerContent.this, FullScreenImageActivity.class);
startActivity(intent);
}
});
Picasso.with(container.getContext()).load("MyWebsite" + MainActivity.imgLink[position]).fit().centerCrop().into(photo);
container.addView(itemView);
return itemView;
}

Related

Create a slideshow of all images in android

I am working on an image gallery, where I fetch all the images stored in the Android phone gallery into my application. Please find the link that I followed to develop that image gallery.
Get all images from Gallery into android application Programmatically
I have trying for hours to figure out how to create a full screen slideshow of images. I am able to achieve the full screen image, but it shows the same image all and always, even though the gallery has 3 images. I am using a ViewPagerAdapter to set the image in the adapter for showing the full screen preview. The image slider isn't working and I don't have an idea of why its not working. Please find the source code of what I have tried so far.
Model_images.java
public class Model_images{
String str_folder;
ArrayList<String> al_imagepath;
public String getStr_folder() {
return str_folder;
}
public void setStr_folder(String str_folder) {
this.str_folder = str_folder;
}
public ArrayList<String> getAl_imagepath() {
return al_imagepath;
}
public void setAl_imagepath(ArrayList<String> al_imagepath) {
this.al_imagepath = al_imagepath;
}
}
I followed the same exact tutorial, where I have given a link to the original source code. Even though I have given a link, I'm posting the source code of the ViewPager I tried.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
gridView = (GridView)findViewById(R.id.gv_folder);
int_position = getIntent().getIntExtra("value", 0);
adapter = new GridViewAdapter(this, GalleryFragment.al_images,int_position);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Bundle bundle = new Bundle();
bundle.putInt("position", int_position);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
SlideshowDialogFragment newFragment = SlideshowDialogFragment.newInstance();
newFragment.setArguments(bundle);
newFragment.show(ft, "slideshow");
}
});
}
Here is the SlideshowFragmentDialog to show the images in a slideview.
SLideShowFragmentDialog.java
public class SlideshowDialogFragment extends DialogFragment {
private String TAG = SlideshowDialogFragment.class.getSimpleName();
private ViewPager viewPager;
private MyViewPagerAdapter myViewPagerAdapter;
private int selectedPosition = 0;
static SlideshowDialogFragment newInstance() {
SlideshowDialogFragment frag = new SlideshowDialogFragment();
return frag;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_image_slider, container, false);
viewPager = (ViewPager) v.findViewById(R.id.viewpager);
//images = (ArrayList<Image>) getArguments().getSerializable("images");
selectedPosition = getArguments().getInt("position");
myViewPagerAdapter = new MyViewPagerAdapter();
viewPager.setAdapter(myViewPagerAdapter);
viewPager.addOnPageChangeListener(viewPagerPageChangeListener);
setCurrentItem(selectedPosition);
return v;
}
private void setCurrentItem(int position) {
viewPager.setCurrentItem(position, false);
displayMetaInfo(selectedPosition);
}
// page change listener
ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
displayMetaInfo(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
};
private void displayMetaInfo(int position) {
Model_images imagePath = GalleryFragment.al_images.get(position);
Toast.makeText(getContext(), imagePath.toString(), Toast.LENGTH_SHORT).show();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(android.support.v4.app.DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
}
// adapter
public class MyViewPagerAdapter extends PagerAdapter {
private LayoutInflater layoutInflater;
public MyViewPagerAdapter() {
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.activity_full_screen, container, false);
ImageView imageViewPreview = (ImageView) view.findViewById(R.id.fullScreenImageView);
Model_images image = GalleryFragment.al_images.get(position);
Glide.with(getContext()).load(image.getAl_imagepath().get(position))
.thumbnail(0.5f)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(imageViewPreview);
container.addView(view);
return view;
}
#Override
public int getCount() {
return GalleryFragment.al_images.size();
}
#Override
public boolean isViewFromObject(View view, Object obj) {
return view == ((View) obj);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
I am not posting the source code for the MainActivity and the Adapter classes, since I have given a link to the project directly. I followed the exact same link. If you still want me to post the source codes, I can edit the question and post the missing stuffs. I don't wanna make this post big with all the code base.
Thanks in advance. Any help is appreciated. Please help me on how to achieve full screen slideshow of images.

android ViewPager starts at a wrong random location after reload

I am writing a simple view pager test app that loads a bunch of data from a website and creates pages to display them.
For the most part the displaying is pretty much all works. However, it falls apart when I load a new set of data to display. When I get a new set, it loads all the data perfectly well however, instead of starting from view 0 it starts at a random location. It could start at the end or somewhere in the middle.
I want all the data to load from page 1, like a book. If you load a new book the book should start from page 1 not a random page.
Reloading calls
I've tried using GotCampDetails() which sets the local variable in the class.
viewPager.setCurrentItem(0);
in my fragment but it doesn't work. Also called notifydatasetchanged() on my adapter, still didn't work.
What am I missing?
public class ViewPagerFragment extends Fragment implements WebReadResultsListener {
private ArrayList<HashMap<String, String>> campDetails;
CustomPagerAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.camp_viewpager, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
if (campDetails != null && ! campDetails.isEmpty()) {
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
adapter = new CustomPagerAdapter(getActivity(), campDetails, viewPager);
viewPager.setAdapter(adapter);
viewPager.setPageTransformer(true, new ZoomOutPageTransformer());
}
}
#Override
public boolean GotCampDetails(ArrayList<HashMap<String, String>> campDetails) {
this.campDetails = campDetails;
return true;
}
#Override
public boolean GotCampList(ArrayList<HashMap<String, String>> campDetails) {
return false;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getFragmentManager().putFragment(outState,"fragmentInstanceSaved",getFragmentManager().findFragmentById(R.id.content));
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Handle orientation changes here
}
}
Adapter:
public class CustomPagerAdapter extends PagerAdapter implements ColorChangeListener {
private ArrayList<HashMap<String, String>> campDetails;
private ViewGroup collection;
private Context mContext;
private boolean isRunning = false;
private ColorChangeListener colorChangeListener;
private int color= pink;
private int currentposition;
private ViewPager viewPager;
public CustomPagerAdapter(Context context, final ArrayList<HashMap<String, String>> campDetails, ViewPager viewPager) {
this.campDetails=campDetails;
this.mContext = context;
this.viewPager = viewPager;
colorChangeListener = (ColorChangeListener) mContext;
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int pos) {
currentposition = pos;
if (campDetails.get(currentposition).get("color").equals("green")) {
color = green;
} else {
color = pink;
}
ColorAppBar(color);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public Object instantiateItem(ViewGroup collection, final int position) {
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.child_item, collection, false);
if (campDetails.size() <= 0) {
Toast.makeText(mContext, "Error in getting camp details", Toast.LENGTH_SHORT).show();
return null;
}
if (campDetails.get(position).get("description").equals("RD") ) {
layout.setBackgroundColor(mContext.getResources().getColor(green));
} else {
layout.setBackgroundColor(mContext.getResources().getColor(pink));
}
collection.addView(layout);
this.collection = collection;
TextView eName = (TextView) layout.findViewById(R.id.en);
TextView nEName= (TextView) layout.findViewById(R.id.nen);
TextView textView6 = (TextView) layout.findViewById(R.id.textView6);
// ImageView nextImg = (ImageView) groupLayout.get(index).findViewById(R.id.nextImg);
eName.setText(campDetails.get(position).get("name"));
if (position+1 < campDetails.size()) {
nEName.setText(campDetails.get(position+1).get("name"));
textView6.setVisibility(View.VISIBLE);
} else {
nEName.setText("You are DONE!!");
textView6.setVisibility(View.INVISIBLE);
}
return layout;
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
#Override
public int getCount() {
return campDetails.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public CharSequence getPageTitle(int position) {
return campDetails.get(position).get("name");
}
#Override
public void ColorAppBar(int color) {
colorChangeListener.ColorAppBar(color);
}
}
I finally managed to get it done.
I had to delay the function call setCurrentItem by a few milliseconds. Race condition? I don't know why this is the case but now it works perfectly.
Here is what I added in case someone else may find it useful:
pager.postDelayed(new Runnable() {
#Override
public void run() {
pager.setCurrentItem(pos);
}
}, 100);
I'm having trouble following the details well enough to pinpoint the problem, but this guy seems to have accomplished what you're trying to do: dynamically add and remove view to viewpager
hope it helps

How can i know swipe viewPager in android

In my application I have viewPager and into this viewPager I show Video and I set this video into ViewPagerAdaper.
I want when swipe right o left, stop video!
I write below codes in adapter for show video :
#Override
public Object instantiateItem(ViewGroup container, final int position) {
View view = this.inflater.inflate(R.layout.row_coming_soon, container, false);
ButterKnife.bind(this, view);
final ImageView comingSoonCover = (ImageView) view.findViewById(R.id.row_comingSoonCoverImg);
final ImageView comingSoonPlayBtn = (ImageView) view.findViewById(R.id.row_comingSoonPlayBtn);
final VideoView comingSoonVideoPlayer = (VideoView) view.findViewById(R.id.row_comingSoon_videoPlayer);
final RelativeLayout comingSoonImagesLay = (RelativeLayout) view.findViewById(R.id.row_comingSoonImagesLay);
comingSoonPlayBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
comingSoonVideoPlayer.setVideoURI(Uri.parse(model.get(position).getTrailerDirectLink()));
comingSoonVideoPlayer.start();
comingSoonImagesLay.setVisibility(View.GONE);
}
});
I want when swipe viewPager, if comingSoonVideoPlayer.isPlaying(); , stop it and swipe viewPager.
How can I it?
I think this listener can halp you
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Now it's deprecated. Must using instead addOnPageChangeListener / removeOnPageChangeListener
You can try to create stop and star method in your adapter , for example
private void start(int position) {
if(comingSoonVideoPlayer != null {
comingSoonVideoPlayer.setVideoURI(Uri.parse(model.get(position).getTrailerDirectLink()));
comingSoonVideoPlayer.start();
}
}
private void stop() {
if(comingSoonVideoPlayer != null) {
comingSoonVideoPlayer.stop();
}
}
then in your fragment
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mViewPager.getAdapter().stop();
mViewPager.getAdapter().start(position);
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
EDIT:
Make comingSoonVideoPlayer as a class field :
final VideoView comingSoonVideoPlayer;
#Override
public Object instantiateItem(ViewGroup container, final int position) {
View view = this.inflater.inflate(R.layout.row_coming_soon, container, false);
ButterKnife.bind(this, view);
final ImageView comingSoonCover = (ImageView) view.findViewById(R.id.row_comingSoonCoverImg);
final ImageView comingSoonPlayBtn = (ImageView) view.findViewById(R.id.row_comingSoonPlayBtn);
comingSoonVideoPlayer = (VideoView) view.findViewById(R.id.row_comingSoon_videoPlayer);
final RelativeLayout comingSoonImagesLay = (RelativeLayout) view.findViewById(R.id.row_comingSoonImagesLay);
comingSoonPlayBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
comingSoonVideoPlayer.setVideoURI(Uri.parse(model.get(position).getTrailerDirectLink()));
comingSoonVideoPlayer.start();
comingSoonImagesLay.setVisibility(View.GONE);
}
});
}
Hope this helps.
Sorry for my english.

Swipe image views left and right like a drag and drop

I have an image view. I want to touch the image and drag it to left or right. When the image is dragged to the left, the new image should appear from the array. When i drag it to right it should be saved in another activity. How can i possibly do this, if somebody could guide me to a tutorial or example. Thank-you
You can use ViewPager and PageAdapter.
protected class ImagePagerAdapter extends PagerAdapter {
public ImagePagerAdapter() {
}
#Override
public int getCount() {
return getImages().size();
}
#Override
public boolean isViewFromObject(View view, Object o) {
return view == o;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = (LayoutInflater) container.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.image_page_view, null);
String url = getImages().get(position);
if (url != null) {
ImageLoader.getInstance().displayImage(url, (ImageView) view.findViewById(R.id.image_page_view));
}
container.addView(view, 0);
return view;
}
}
...
imagePager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i2) {
}
#Override
public void onPageSelected(int i) {
//logic to open activity or other action..;
}
#Override
public void onPageScrollStateChanged(int i) {
}
});
...
imagePager.setAdapter(new ImagePagerAdapter());

(AndroidTouchGallery) How to start with 2,3,4.. image. How to set position

I`m trying to implement ImageGallery on Android. I use AndroidTouchGallery library. In MainActyvity I have list of images and by clicking on them open AndroidTouchGallery. Everything work, but when open the image gallery starts with the first one.
There need to set the image position, in which to start. In this stage I have a problem. Maybe someone how to make it.
int pos ; //Picture Position
UrlPagerAdapter pagerAdapter = new UrlPagerAdapter(Full_Image_Activity.this, ArrayImgBig);
mViewPager = (GalleryViewPager)findViewById(R.id.viewer);
mViewPager.setOffscreenPageLimit(3);
mViewPager.setAdapter(pagerAdapter);
The code of UrlPageAdapter. I try to set the position in setPrimaryItem, but it still open the first image.
/**
Class wraps URLs to adapter, then it instantiates {#link UrlTouchImageView} objects to paging up through them.
*/
public class UrlPagerAdapter extends BasePagerAdapter {
public UrlPagerAdapter(Context context, List<String> resources)
{
super(context, resources);
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
((GalleryViewPager)container).mCurrentView = ((UrlTouchImageView)object).getImageView();
}
#Override
public Object instantiateItem(ViewGroup collection, int position){
final UrlTouchImageView iv = new UrlTouchImageView(mContext);
iv.setUrl(mResources.get(position));
iv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
collection.addView(iv, 0);
return iv;
}
}
BasePagerAdapter
/**
Class wraps URLs to adapter, then it instantiates <b>UrlTouchImageView</b> objects to paging up through them.
*/
public class BasePagerAdapter extends PagerAdapter {
protected final List<String> mResources;
protected final Context mContext;
protected int mCurrentPosition = -1;
protected OnItemChangeListener mOnItemChangeListener;
public BasePagerAdapter()
{
mResources = null;
mContext = null;
}
public BasePagerAdapter(Context context, List<String> resources)
{
this.mResources = resources;
this.mContext = context;
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (mCurrentPosition == position) return;
GalleryViewPager galleryContainer = ((GalleryViewPager)container);
if (galleryContainer.mCurrentView != null) galleryContainer.mCurrentView.resetScale();
mCurrentPosition = position;
if (mOnItemChangeListener != null) mOnItemChangeListener.onItemChange(mCurrentPosition);
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view){
collection.removeView((View) view);
}
#Override
public int getCount()
{
return mResources.size();
}
#Override
public boolean isViewFromObject(View view, Object object){
return view.equals(object);
}
#Override
public void finishUpdate(ViewGroup arg0){
}
#Override
public void restoreState(Parcelable arg0, ClassLoader arg1){
}
#Override
public Parcelable saveState(){
return null;
}
#Override
public void startUpdate(ViewGroup arg0) { }
public int getCurrentPosition() { return mCurrentPosition; }
public void setOnItemChangeListener(OnItemChangeListener listener) { mOnItemChangeListener = listener; }
public static interface OnItemChangeListener
{
public void onItemChange(int currentPosition);
}
}
Olso I have some other queston.
*is the "setPrimaryItem" set up the main Item(Image) witch is open first?
*is the "instantiateItem" initialise every item from the array, whitch is shows?
I made it by this:
mViewPager = (GalleryViewPager)findViewById(R.id.viewer);
mViewPager.setOffscreenPageLimit(3);
mViewPager.setAdapter(pagerAdapter);
//set position
mViewPager.setCurrentItem(pos);

Categories

Resources