动态添加和删除视图到 viewpager [英] dynamically add and remove view to viewpager

查看:14
本文介绍了动态添加和删除视图到 viewpager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我想出了一个解决方案 - 请在下面的答案部分查看我的帖子.)

在我的应用中,用户将从其数据的单一视图开始.我想添加一个 ViewPager 并允许用户根据需要添加更多视图.我该怎么做呢?(我不想使用 FragmentPagerAdapter.)

In my app, the user will start with a single view of his data. I'd like to add a ViewPager and allow the user to add more views as desired. How do I do this? (I dont' want to use the FragmentPagerAdapter.)

我已经阅读了无数的帖子和概述,但仍然缺少一些东西.以下是我认为我理解的:

I've read countless posts and overviews but am still missing something. Here's what I think I understand:

MainActivity 创建一个 ViewPager 和 PagerAdapter:

MainActivity creates a ViewPager and PagerAdapter:

ViewPager pager = null;
MainPagerAdapter adapter = null;
public void onCreate (Bundle savedInstanceState)
{
  super.onCreate (savedInstanceState);
  pager = new ViewPager (this);
  setContentView (pager);

  adapter = new MainPagerAdapter();
  pager.setAdapter (adapter); 

  View v0 = code_to_create_initial_view();
  adapter.add (v0, 0);      
}

使用 PagerAdapter 来提供视图集.为此,我似乎需要添加和删除视图的方法,就像这样;显然需要更多的信息来告诉 ViewPager 的内容发生了变化以及如何显示变化:

Use a PagerAdapter to provide the sets of view. For this it seems I need methods to add and remove views, something like this; obviously more is needed to tell the ViewPager stuff has changed and how to show the change:

class MainPagerAdapter extends PagerAdapter
{
  // This holds all the currently displayable views, in order from left to right.
  private ArrayList<View> views = new ArrayList<View>();

  public void addView (View v, int position)
  {
    views.add (position, v);
  }

  public void removeView (int position)
  {
    views.remove (position);
  }
}

此外,我需要实现以下虚拟方法.我在这里迷路了 - 什么叫他们,他们应该做什么(好吧,getCount 很明显)?

In addition, I need to implement the following vitual methods. I'm lost here - what calls them and what are they supposed to do (ok, getCount is obvious)?

  public object instantiateItem (ViewGroup pager, int position);
  public void destroyItem (ViewGroup, int, Object);
  public int getCount ();
  public boolean isViewFromObject (View, Object);

  • ViewGroup 参数有什么用 - 包含组不是 ViewPager 本身吗?
  • isViewFromObject 有什么作用 - 对象首先如何与视图关联?
  • 添加或删除视图时是否应该调用 startUpdate 和 finishUdate?
  • 谢谢.

    推荐答案

    在弄清楚 ViewPager 调用了哪些 ViewPager 方法以及用于其他目的之后,我想出了一个解决方案.我在这里介绍它,因为我看到很多人都在为此苦苦挣扎,而我没有看到任何其他相关的答案.

    After figuring out which ViewPager methods are called by ViewPager and which are for other purposes, I came up with a solution. I present it here since I see a lot of people have struggled with this and I didn't see any other relevant answers.

    首先,这是我的适配器;希望代码中的注释就足够了:

    First, here's my adapter; hopefully comments within the code are sufficient:

    public class MainPagerAdapter extends PagerAdapter
    {
      // This holds all the currently displayable views, in order from left to right.
      private ArrayList<View> views = new ArrayList<View>();
    
      //-----------------------------------------------------------------------------
      // Used by ViewPager.  "Object" represents the page; tell the ViewPager where the
      // page should be displayed, from left-to-right.  If the page no longer exists,
      // return POSITION_NONE.
      @Override
      public int getItemPosition (Object object)
      {
        int index = views.indexOf (object);
        if (index == -1)
          return POSITION_NONE;
        else
          return index;
      }
    
      //-----------------------------------------------------------------------------
      // Used by ViewPager.  Called when ViewPager needs a page to display; it is our job
      // to add the page to the container, which is normally the ViewPager itself.  Since
      // all our pages are persistent, we simply retrieve it from our "views" ArrayList.
      @Override
      public Object instantiateItem (ViewGroup container, int position)
      {
        View v = views.get (position);
        container.addView (v);
        return v;
      }
    
      //-----------------------------------------------------------------------------
      // Used by ViewPager.  Called when ViewPager no longer needs a page to display; it
      // is our job to remove the page from the container, which is normally the
      // ViewPager itself.  Since all our pages are persistent, we do nothing to the
      // contents of our "views" ArrayList.
      @Override
      public void destroyItem (ViewGroup container, int position, Object object)
      {
        container.removeView (views.get (position));
      }
    
      //-----------------------------------------------------------------------------
      // Used by ViewPager; can be used by app as well.
      // Returns the total number of pages that the ViewPage can display.  This must
      // never be 0.
      @Override
      public int getCount ()
      {
        return views.size();
      }
    
      //-----------------------------------------------------------------------------
      // Used by ViewPager.
      @Override
      public boolean isViewFromObject (View view, Object object)
      {
        return view == object;
      }
    
      //-----------------------------------------------------------------------------
      // Add "view" to right end of "views".
      // Returns the position of the new view.
      // The app should call this to add pages; not used by ViewPager.
      public int addView (View v)
      {
        return addView (v, views.size());
      }
    
      //-----------------------------------------------------------------------------
      // Add "view" at "position" to "views".
      // Returns position of new view.
      // The app should call this to add pages; not used by ViewPager.
      public int addView (View v, int position)
      {
        views.add (position, v);
        return position;
      }
    
      //-----------------------------------------------------------------------------
      // Removes "view" from "views".
      // Retuns position of removed view.
      // The app should call this to remove pages; not used by ViewPager.
      public int removeView (ViewPager pager, View v)
      {
        return removeView (pager, views.indexOf (v));
      }
    
      //-----------------------------------------------------------------------------
      // Removes the "view" at "position" from "views".
      // Retuns position of removed view.
      // The app should call this to remove pages; not used by ViewPager.
      public int removeView (ViewPager pager, int position)
      {
        // ViewPager doesn't have a delete method; the closest is to set the adapter
        // again.  When doing so, it deletes all its views.  Then we can delete the view
        // from from the adapter and finally set the adapter to the pager again.  Note
        // that we set the adapter to null before removing the view from "views" - that's
        // because while ViewPager deletes all its views, it will call destroyItem which
        // will in turn cause a null pointer ref.
        pager.setAdapter (null);
        views.remove (position);
        pager.setAdapter (this);
    
        return position;
      }
    
      //-----------------------------------------------------------------------------
      // Returns the "view" at "position".
      // The app should call this to retrieve a view; not used by ViewPager.
      public View getView (int position)
      {
        return views.get (position);
      }
    
      // Other relevant methods:
    
      // finishUpdate - called by the ViewPager - we don't care about what pages the
      // pager is displaying so we don't use this method.
    }
    

    这里有一些代码片段展示了如何使用适配器.

    And here's some snips of code showing how to use the adapter.

    class MainActivity extends Activity
    {
      private ViewPager pager = null;
      private MainPagerAdapter pagerAdapter = null;
    
      //-----------------------------------------------------------------------------
      @Override
      public void onCreate (Bundle savedInstanceState)
      {
        super.onCreate(savedInstanceState);
        setContentView (R.layout.main_activity);
    
        ... do other initialization, such as create an ActionBar ...
    
        pagerAdapter = new MainPagerAdapter();
        pager = (ViewPager) findViewById (R.id.view_pager);
        pager.setAdapter (pagerAdapter);
    
        // Create an initial view to display; must be a subclass of FrameLayout.
        LayoutInflater inflater = context.getLayoutInflater();
        FrameLayout v0 = (FrameLayout) inflater.inflate (R.layout.one_of_my_page_layouts, null);
        pagerAdapter.addView (v0, 0);
        pagerAdapter.notifyDataSetChanged();
      }
    
      //-----------------------------------------------------------------------------
      // Here's what the app should do to add a view to the ViewPager.
      public void addView (View newPage)
      {
        int pageIndex = pagerAdapter.addView (newPage);
        // You might want to make "newPage" the currently displayed page:
        pager.setCurrentItem (pageIndex, true);
      }
    
      //-----------------------------------------------------------------------------
      // Here's what the app should do to remove a view from the ViewPager.
      public void removeView (View defunctPage)
      {
        int pageIndex = pagerAdapter.removeView (pager, defunctPage);
        // You might want to choose what page to display, if the current page was "defunctPage".
        if (pageIndex == pagerAdapter.getCount())
          pageIndex--;
        pager.setCurrentItem (pageIndex);
      }
    
      //-----------------------------------------------------------------------------
      // Here's what the app should do to get the currently displayed page.
      public View getCurrentPage ()
      {
        return pagerAdapter.getView (pager.getCurrentItem());
      }
    
      //-----------------------------------------------------------------------------
      // Here's what the app should do to set the currently displayed page.  "pageToShow" must
      // currently be in the adapter, or this will crash.
      public void setCurrentPage (View pageToShow)
      {
        pager.setCurrentItem (pagerAdapter.getItemPosition (pageToShow), true);
      }
    }
    

    最后,您可以将以下内容用于您的 activity_main.xml 布局:

    Finally, you can use the following for your activity_main.xml layout:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.view.ViewPager
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
    </android.support.v4.view.ViewPager>
    

    这篇关于动态添加和删除视图到 viewpager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆