【问题标题】:How to delete item from viewpager and pageradapter如何从 viewpager 和 pageradapter 中删除项目
【发布时间】:2014-09-28 01:39:28
【问题描述】:

我正在使用 pageradapter 和 viewpager 来显示 imageview 数组,textview 数组。但是如何在按钮单击时删除寻呼机。下面代码中的整个代码,但是我在 xml 中添加了按钮 onclick 应该删除页面。

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);

【问题讨论】:

    标签: android android-viewpager android-pageradapter


    【解决方案1】:

    首先您需要使用List,因为动态删除对象。 第二个你需要

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

    强制适配器每次都创建新页面,而不是在内存页面中使用。

     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;
        }
    }
    

    【讨论】:

    • 我有一个问题,当我尝试删除列表的最后一项时,我的应用程序崩溃了。它说,“java.lang.IndexOutOfBoundsException:索引 6 无效,大小为 6”。它指向这一行:imageView.setImageResource(regionImages.get(position));
    • @KalaJ 将您的代码作为问题发布在 SO 上。然后告诉我链接!
    • 其实我有一个新的viewpager问题:stackoverflow.com/questions/26632219/…你有时间可以看看吗?谢谢。
    • Kala 您尝试访问数组中的第 7 项,尽管数组中只有 6 项。第 6 个索引是第 7 项,不存在。数组从索引 0 开始。
    【解决方案2】:

    选定的答案将很快达到性能冲击

    确实,您需要实现适配器的 getItemPosition() 方法,但您应该按预期覆盖它。

    getItemPosition() 方法告诉 ViewPager 在调用 adapter.notifyDataSetChanged() 时是否删除 viewItem,是否重绘 viewItem。

    adapter.notifyDataSetChanged() 被调用时,基本上你的getItemPosition() 方法的实现被调用来回答一个简单的问题。

    问题是“对于我们拥有的每个viewItem,位置是否发生了变化?”

    这个问题有两个答案

    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.

    这个问题决定天气 ViewPager 重新创建一个新的 viewItem 还是使用一个被缓存的。也正是从这个答案中,决定删除一个被认为被删除或删除的 ViewItem。

    如果每次调用adapter.notifyDataSetChanged() 时,ViewPager 都必须为项目列表中的每个数据项创建一个新的视图项。想象一下,如果您有一个包含数千个数据库数据的列表;性能会受到打击。这正是从getItemPosition() 返回PagerAdapter.POSITION_NONE; 所做的事情。您正在绕过一个关键的性能机制。

    作为开发人员,您有责任弄清楚您如何回答这个问题。但请记住,您回答该问题的方式会影响应用的性能。

    我如何实现它

    在您的 PagerAdapter 中,instantiateItem(@NonNull ViewGroup container, int position)。实例化后在视图上设置标签。给它一个唯一的名字。我使用在该视图中显示的图像的名称。

    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;
    }
    

    然后覆盖getItemPosition(@NonNull Object object)

    super.getItemPosition(object); 在该消息中返回高于PagerAdapter.POSITION_UNCHANGED //nothing changed save resources use cached viewitem 的答案 1,这是默认行为。

    但是我们想遍历我们的数据项,看看作为对象从getItemPosition(@NonNull Object object) 传递给我们的 viewItem 是否仍然存在于适配器项数组中。

    我们感兴趣的是什么时候它不存在。那是我们返回答案 2 的时候。 PagerAdapter.POSITION_NONE

    作为对象传递给我们的 viewItem 正是我们在public Object instantiateItem(@NonNull ViewGroup container, int position) 方法中返回的对象。就我而言,它是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;
    }
    

    最后一部分。现在从您的片段活动中,只需从适配器数组或 ArrayList 中删除数据,您将其作为数据源传递给适配器。

    //remove deleted item from myMedias ArrayList
    myMedias.remove(position);
    
    //tell your adapter instance data changed
    pagerAdapter.notifyDataSetChanged();  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多