Add / Delete pages to ViewPager dynamically

前端 未结 9 1112
囚心锁ツ
囚心锁ツ 2021-01-29 23:17

I would like to add or delete pages from my view pager dynamically. Is that possible?

9条回答
  •  一整个雨季
    2021-01-30 00:01

    Based on other answers and other resources I've ended with this code.

    CustomPagerAdapter:

    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentTransaction;
    import android.support.v4.view.PagerAdapter;
    import android.view.View;
    import android.view.ViewGroup;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class CustomPagerAdapter extends PagerAdapter {
    
      private List pages = new ArrayList<>();
      private Map fragmentsPosition = new HashMap<>();
    
      private Fragment currentPrimaryItem;
      private FragmentManager fragmentManager;
      private FragmentTransaction currentTransaction;
    
    
      public CustomPagerAdapter(FragmentManager fragmentManager) {
        this.fragmentManager = fragmentManager;
      }
    
      @Override
      public Object instantiateItem(ViewGroup container, int position) {
        if (currentTransaction == null) {
          currentTransaction = fragmentManager.beginTransaction();
        }
    
        Fragment pageFragment = pages.get(position);
        String tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG);
        Fragment fragment = fragmentManager.findFragmentByTag(tag);
    
        if (fragment != null) {
          if (fragment.getId() == container.getId()) {
            currentTransaction.attach(fragment);
          }
          else {
            fragmentManager.beginTransaction().remove(fragment).commit();
            fragmentManager.executePendingTransactions();
            currentTransaction.add(container.getId(), fragment, tag);
          }
        }
        else {
          fragment = pageFragment;
          currentTransaction.add(container.getId(), fragment, tag);
        }
    
        if (fragment != currentPrimaryItem) {
          fragment.setMenuVisibility(false);
          fragment.setUserVisibleHint(false);
        }
    
        return fragment;
      }
    
      @Override
      public int getCount() {
        return pages.size();
      }
    
      @Override
      public void destroyItem(ViewGroup container, int position, Object object) {
        if (currentTransaction == null) {
          currentTransaction = fragmentManager.beginTransaction();
        }
    
        currentTransaction.detach((Fragment) object);
      }
    
      @Override
      public void setPrimaryItem(ViewGroup container, int position, Object object) {
        Fragment fragment = (Fragment) object;
    
        if (fragment != currentPrimaryItem) {
          if (currentPrimaryItem != null) {
            currentPrimaryItem.setMenuVisibility(false);
            currentPrimaryItem.setUserVisibleHint(false);
          }
    
          if (fragment != null) {
            fragment.setMenuVisibility(true);
            fragment.setUserVisibleHint(true);
          }
    
          currentPrimaryItem = fragment;
        }
      }
    
      @Override
      public void finishUpdate(ViewGroup container) {
        if (currentTransaction != null) {
          currentTransaction.commitAllowingStateLoss();
          currentTransaction = null;
          fragmentManager.executePendingTransactions();
        }
      }
    
      @Override
      public boolean isViewFromObject(View view, Object object) {
        return ((Fragment) object).getView() == view;
      }
    
      @Override
      public int getItemPosition(Object o) {
        Integer result = fragmentsPosition.get(o);
    
        if (result == null) {
          return PagerAdapter.POSITION_UNCHANGED;
        }
    
        return result;
      }
    
      // ---------------------------------- Page actions ----------------------------------
    
      public void addPage(Fragment fragment) {
        fragmentsPosition.clear();
        pages.add(fragment);
        notifyDataSetChanged();
      }
    
      public void removePage(int position) {
        fragmentsPosition.clear();
    
        Fragment pageFragment = pages.get(position);
        String tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG);
    
        Fragment fragment = fragmentManager.findFragmentByTag(tag);
    
        if (fragment != null) {
          fragmentsPosition.put(fragment, PagerAdapter.POSITION_NONE);
        }
    
        for (int i = position + 1; i < pages.size(); i++) {
          pageFragment = pages.get(i);
          tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG);
          fragment = fragmentManager.findFragmentByTag(tag);
    
          if (fragment != null) {
            fragmentsPosition.put(fragment, i - 1);
          }
        }
    
        pages.remove(position);
        notifyDataSetChanged();
      }
    
    }
    

    MainActivity:

    import android.os.Bundle;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    
    public class MainActivity extends AppCompatActivity {
    
      public static final String FRAGMENT_TAG_ARG = "tag";
    
      private CustomPagerAdapter mCustomPagerAdapter;
    
      private ViewPager mViewPager;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mCustomPagerAdapter = new CustomPagerAdapter(getSupportFragmentManager());
        mCustomPagerAdapter.addPage(MainFragment.newInstance("Main_Title"));
        mCustomPagerAdapter.addPage(SecondaryFragment.newInstance("Secondary_Title"));
    
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mCustomPagerAdapter);
      }
    
    }
    

    To remove pages:

    mCustomPagerAdapter.removePage(1);
    

    MainFragment:

    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    public class MainFragment extends Fragment {
    
      public static final String FRAGMENT_TAG = "MainFragment";
    
      public static MainFragment newInstance(String text) {
        return newInstance(text, FRAGMENT_TAG);
      }
    
      public static MainFragment newInstance(String text, String tag) {
        MainFragment fragment = new MainFragment();
        Bundle args = new Bundle();
        args.putString("text", text);
        args.putString(MainActivity.FRAGMENT_TAG_ARG, tag + "_" + fragment.hashCode());
        fragment.setArguments(args);
        return fragment;
      }
    
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        TextView textView = (TextView) rootView.findViewById(R.id.section_label);
        textView.setText(getArguments().getString("text"));
        return rootView;
      }
    
    }
    

    SecondaryFragment has the same code.

    The layouts are simple ViewPager/Fragment layouts with android.support.v4.view.ViewPager with id container and Fragment TextView with id section_label.

    Resources:

    • dynamically add and remove view to viewpager
    • How to Remove Fragment from FragmentPagerAdapter?
    • https://github.com/takaaki7/ArrayPagerAdapter
    • https://github.com/commonsguy/cwac-pager

提交回复
热议问题