How to delete item from viewpager and pageradapter
Asked Answered
K

2

7

I am using pageradapter and viewpager to display imageview array,textview array .But how do I delete pager on button click .Entire code in the code below ,but I have added button in xml onclick should delete the page.

https://www.swipetips.com/android-viewpager-gallery-images-and-texts-tutorial/

 package com.androidbegin.viewpagertutorial;

    import android.content.Context;
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.RelativeLayout;
    import android.widget.TextView;

    public class ViewPagerAdapter extends PagerAdapter {
        // Declare Variables
        Context context;
        String[] rank;
        String[] country;
        String[] population;
        int[] flag;
        LayoutInflater inflater;

        public ViewPagerAdapter(Context context, String[] rank, String[] country,
                String[] population, int[] flag) {
            this.context = context;
            this.rank = rank;
            this.country = country;
            this.population = population;
            this.flag = flag;
        }

        @Override
        public int getCount() {
            return rank.length;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == ((RelativeLayout) object);
        }

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

            // Declare Variables
            TextView txtrank;
            TextView txtcountry;
            TextView txtpopulation;
            ImageView imgflag;

            Button b;

            inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View itemView = inflater.inflate(R.layout.viewpager_item, container,
                    false);

            // Locate the TextViews in viewpager_item.xml
            txtrank = (TextView) itemView.findViewById(R.id.rank);
            txtcountry = (TextView) itemView.findViewById(R.id.country);
            txtpopulation = (TextView) itemView.findViewById(R.id.population);
            b=(Button)itemView.findViewById(R.id.button1);


            b.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {



                }
            });

            // Capture position and set to the TextViews
            txtrank.setText(rank[position]);
            txtcountry.setText(country[position]);
            txtpopulation.setText(population[position]);

            // Locate the ImageView in viewpager_item.xml
            imgflag = (ImageView) itemView.findViewById(R.id.flag);
            // Capture position and set to the ImageView
            imgflag.setImageResource(flag[position]);

            // Add viewpager_item.xml to ViewPager
            ((ViewPager) container).addView(itemView);

            return itemView;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // Remove viewpager_item.xml from ViewPager
            ((ViewPager) container).removeView((RelativeLayout) object);

        }
    }

////////////////////

// Locate the ViewPager in viewpager_main.xml
        viewPager = (ViewPager) findViewById(R.id.pager);
        // Pass results to ViewPagerAdapter Class
        adapter = new ViewPagerAdapter(MainActivity.this, rank, country, population, flag);
        // Binds the Adapter to the ViewPager
        viewPager.setAdapter(adapter);
Koala answered 28/9, 2014 at 1:39 Comment(0)
G
17

first you need to use List because of dynamically deleting objects. second you need

    @Override
    public int getItemPosition(Object object){
        return PagerAdapter.POSITION_NONE;
    }

to force the adapter to create new page each time and not using in memory pages.

 public class ViewPagerAdapter extends PagerAdapter {
    // Declare Variables
    Context context;
    List<String> rank;
    List<String> country;
    List<String> population;
    List<Integer> flag = new ArrayList<Integer>();
    LayoutInflater inflater;

    public ViewPagerAdapter(Context context, String[] rank, String[] country,
            String[] population, int[] flag) {
        this.context = context;
        this.rank = new ArrayList<String>(Arrays.asList(rank));
        this.country = new ArrayList<String>(Arrays.asList(country));
        this.population = new ArrayList<String>(Arrays.asList(population));
        for (int i : flag){ 
            this.flag.add(i);
        }

    }

    @Override
    public int getCount() {
        return rank.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == ((RelativeLayout) object);
    }

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

        // Declare Variables
        TextView txtrank;
        TextView txtcountry;
        TextView txtpopulation;
        ImageView imgflag;

        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View itemView = inflater.inflate(R.layout.viewpager_item, container,
                false);

        // Locate the TextViews in viewpager_item.xml
        txtrank = (TextView) itemView.findViewById(R.id.rank);
        txtcountry = (TextView) itemView.findViewById(R.id.country);
        txtpopulation = (TextView) itemView.findViewById(R.id.population);
         Button b=(Button)itemView.findViewById(R.id.button1);

         final int delPosition = position;

         b.setOnClickListener(new OnClickListener() {

             @Override
             public void onClick(View v) {
                 rank.remove(delPosition);
                 country.remove(delPosition);
                 population.remove(delPosition);
                 flag.remove(delPosition);
                 notifyDataSetChanged();
             }
         });
        // Capture position and set to the TextViews
        txtrank.setText(rank.get(position));
        txtcountry.setText(country.get(position));
        txtpopulation.setText(population.get(position));

        // Locate the ImageView in viewpager_item.xml
        imgflag = (ImageView) itemView.findViewById(R.id.flag);
        // Capture position and set to the ImageView
        imgflag.setImageResource(flag.get(position));

        // Add viewpager_item.xml to ViewPager
        ((ViewPager) container).addView(itemView);

        return itemView;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        // Remove viewpager_item.xml from ViewPager
        ((ViewPager) container).removeView((RelativeLayout) object);

    }
    @Override
    public int getItemPosition(Object object){
        return PagerAdapter.POSITION_NONE;
    }
}
Gaussmeter answered 28/9, 2014 at 5:24 Comment(4)
I have a question, my app crashes when I try to delete the last item of my list. It says, "java.lang.IndexOutOfBoundsException: Invalid index 6, size is 6". It points to this line: imageView.setImageResource(regionImages.get(position));Solnit
@KalaJ post your code as a question on the SO. then tell me the link!Gaussmeter
actually, I have a new viewpager question: #26632719 Can you take a look if you have time? Thank you.Solnit
Kala you're trying to access the 7th item in the array, although there are only 6 items in the array. The 6th index is the 7th item, which doesn't exist. Arrays start from index 0.Jeffcott
C
1

The Selected answer will quickly hit a performance knock.

True you need to implement the getItemPosition() method of your Adaptor but you should override it as intended.

The getItemPosition() method tells the ViewPager whether or not to delete viewItem, to redraw or not redraw viewItem when the adapter.notifyDataSetChanged() is called.

Basically your implementation of getItemPosition() method is called to answer a simple question when adapter.notifyDataSetChanged() is called.

The question is "For each of the viewItems we have, has the position changed?"

There are two answers to this question

  1. PagerAdapter.POSITION_UNCHANGED //nothing changed save resources use cached viewitem
  2. PagerAdapter.POSITION_NONE //we don't have that view any more recreate it or delete it.

This question determines weather ViewPager recreates a new viewItem or uses one that was cached. Also it's from this answer that a decision is made to Remove a ViewItem deemed to be deleted or removed.

If ViewPager has to create a new viewitem for every data item in your items list every time adapter.notifyDataSetChanged() is called. Imagine if you had a list of thousands of data from database; performance will be hit. That's exactly what just returning PagerAdapter.POSITION_NONE; from getItemPosition() does. You are bypassing a crucial performance mechanism.

It's your responsibility as a developer to figure out how you answer that question. But remember the way you answer that question impacts performance of your app.

How I implement it

In Your PagerAdapter, instantiateItem(@NonNull ViewGroup container, int position). Set a tag on your view after instantiation. give it a unique name. I use the name of the image that I am showing in that view.

public MyAdaptorPagerAdaptor(Context context, ArrayList<MyMedia> myMedias) {
    this.context = context;
    this.myMedias = myMedias;
    this.authCode = authCode;
}

public Object instantiateItem(@NonNull ViewGroup container, int position) {
    
    mageView imageView = new ImageView(context);
    imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
    mageView.setTag(myMedia.getName()); //the most important part

    //....... do your stuff
    return imageView;
}

Then Override the getItemPosition(@NonNull Object object)

super.getItemPosition(object); in that message return answer no.1 above PagerAdapter.POSITION_UNCHANGED //nothing changed save resources use cached viewitem that's the default behavior.

But we want to iterate through our data items to see if the viewItem passed to us as an object from getItemPosition(@NonNull Object object) still exists in out Adapter items array or not.

We are interested in when it does not exists. that's when we return answer no.2. PagerAdapter.POSITION_NONE

The viewItem passed to us as an Object, is exactly the Object we returned in our public Object instantiateItem(@NonNull ViewGroup container, int position) method. In my case it's the ImageView.

@Override
public int getItemPosition(@NonNull Object object) {
    int res = super.getItemPosition(object);
    ImageView imageView = (ImageView) object;
    final String tag = (String) imageView.getTag();

    // look for an item with our tag from our items list.
    MyMedia myMedia = null;
    for (MyMedia item : myMedias) {
        if (item.getName().equals(tag)) {
            myMedia = item;
            break;
        }
    }

    //if this item is null, then it does not exist in my items list
    // so I tell View pager I don't have that item.
    if (myMedia == null) {
        res = PagerAdapter.POSITION_NONE;
    }
    return res;
}

Last part. Now from your activity of fragment, just remove data from the Adapter array or ArrayList which you pass to your adapter as a data source.

//remove deleted item from myMedias ArrayList
myMedias.remove(position);

//tell your adapter instance data changed
pagerAdapter.notifyDataSetChanged();  
Colchicum answered 11/6, 2020 at 15:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.