10

ページの追加と削除を許可するために を使用してViewpagerいます。FragmentPagerAdapter各ページには、インターネットから取得したデータが表示されます。

新しいページが追加されると、新しいフラグメントがそのページに関連付けられます。データは AsyncTask を介して取得され、フラグメントに表示されます。ユーザーがページを削除することを選択すると、そのページと関連する Fragment が破棄されます。

一般に、これはすべてうまく機能します。私が見ている問題は次のとおりです。

  1. データを含む 3 つのページがあります。

    [1ページ] [2ページ] [3ページ]

  2. 最後のページ以外のページ、たとえばページ 2 を削除します。必要に応じてページ 2 が消えます。

    【1ページ目】 【3ページ目】

  3. 新しいページを追加します。ただし、空白の新しいページの代わりに、新しいページには 3 ページのデータ (ビュー) が表示されます。

    [ページ 1] [ページ 3] [ページ 4、ただしページ 3 のビュー/データを表示、空白にする必要があります]


私のアクティビティのページ削除コードは次のとおりです。

   // Destroy fragment for this page
   DataListFragment curFrag = getFragmentByName(currentPage);
   FragmentManager fm = getSupportFragmentManager();
   fm.beginTransaction().remove(curFrag).commit();
   fm.executePendingTransactions();
   curFrag = null;

   // Remove page and update adapter
   mPageTitles.remove(position);        
   mAdapter.notifyDataSetChanged();

デバッガーを使用して、呼び出しFragmentManager後にフラグメントが削除されたことを示します。executePendingTransactions()しかし、FrampePagerAdapters呼び出しでmAdapter.notifyDataSetChanged()は、フラグメントが再び追加され、新しいページが作成されたときに表示されます。

フラグメントを破棄できるようにする必要があるため、FrameStatePagerAdapter を使用してみましたが、機能しませんでした。FragmentPagerAdapter のgetItemPosition()メソッドでは、return FragmentAdapter.POSITION_NONE;私が遭遇した別の SO 記事で指摘されているように使用します。

そのページのビューは破棄されていないように見えますが、新しいページに追加されます。新しいページのビューでメソッドを使用しようとしましたremoveViewAt()が、うまくいきませんでした。


これに慣れていないので、明らかな何かが欠けていると確信しています...

4

3 に答える 3

1

FragmentStatePagerAdapterアクティビティから Fragment を削除しようとするのではなく、対応するアイテムをそのアダプターのアイテムのリストから拡張して削除する必要があります。adapter.notifyDataSetChanged()アダプターのアイテムを取り外した後は、忘れずに電話してください。完了ViewPagerしたらFragmentStatePagerAdapter、残りの処理を行います。

于 2013-08-17T12:53:07.543 に答える
0

getCount() メソッドが viewPager 内の正確な数のアイテムを返していることを確認してください。はい、FragmentStatePagerAdapter もカウントされます。

于 2013-10-28T05:55:56.120 に答える
0

経験に基づいて、次の知識を組み合わせたソリューションになりました。

  • Fragment問題なく末尾に新規追加できます。
  • Fragment以前に削除されたファイルを読み込めないjava.lang.IllegalStateException: Can't change tag of fragment場合があるため、クローンを作成する必要があります。
  • a を削除するには、メソッドでFragment戻り、からを削除する必要があります。PagerAdapter.POSITION_NONEgetItemPosition(Object object)FragmentFragmentManager
  • テール以外の場所で追加/削除/交換している場合は、変更している位置から最後まですべてを削除し、作業を行ってから、削除した (複製された) Fragments を再読み込みする必要があります。

これは、タブを追加、削除、および置換するための 3 つのメソッドを持つ完全なFragmentActivityコードです。FragmentPagerAdapter

public class TabTestActivity extends FragmentActivity implements
        ActionBar.TabListener {
    private SectionsPagerAdapter mSectionsPagerAdapter;
    private ViewPager mViewPager;
    private static int tabCount = 0;
    private static String labelString = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        labelString = getString(R.string.title_section);
        setContentView(R.layout.activity_tab_test);
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        mSectionsPagerAdapter = new SectionsPagerAdapter(
                getSupportFragmentManager());
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(final int position) {
                        (new Handler()).postDelayed(new Runnable() {

                            @Override
                            public void run() {
                                actionBar.setSelectedNavigationItem(position);
                            }

                        }, 1);
                    }
                });

        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            actionBar.addTab(actionBar.newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(i))
                    .setTabListener(this));
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.tab_test, menu);
        return true;
    }

    public void addNewTab() {
        int position = (mSectionsPagerAdapter.getCount() > 0 ? mViewPager.getCurrentItem() : 0);
        mSectionsPagerAdapter.insertFragment(position);
        mViewPager.setCurrentItem(position, true);
    }

    public void removeTab() {
        if (mSectionsPagerAdapter.getCount() > 0) {
            int position = mViewPager.getCurrentItem();
            mSectionsPagerAdapter.removeFragment(position);
        }
    }

    public void replaceTab() {
        if (mSectionsPagerAdapter.getCount() > 0) {
            int position = mViewPager.getCurrentItem();
            mSectionsPagerAdapter.replaceFragment(position);            
            mViewPager.setCurrentItem(position, false);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_add_tab:
            addNewTab();
            return true;
        case R.id.action_remove_tab:
            removeTab();
            return true;
        case R.id.action_replace_tab:
            replaceTab();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab,
            FragmentTransaction fragmentTransaction) {
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab,
            FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab,
            FragmentTransaction fragmentTransaction) {
    }

    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        private List<Fragment> currentFragments;
        private FragmentManager fragmentManager;

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
            fragmentManager = fm;
            currentFragments = new ArrayList<Fragment>();
        }

        public void insertFragment(int position) {
            // Remove fragments from position
            List<Fragment> fragmentsToRemove = new ArrayList<Fragment>(currentFragments.subList(position, currentFragments.size()));
            int i = currentFragments.size() - 1;
            int j = -1;
            int k = i;
            while (i >= position) {
                currentFragments.remove(i);
                i--;
                j++;
            }
            notifyDataSetChanged();
            final ActionBar actionBar = getActionBar();
            while (k >= position) {
                actionBar.removeTabAt(k);
                k--;
            }
            android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
            while (j >= 0) {
                Fragment fragmentToRemove = fragmentsToRemove.get(j);
                transaction.detach(fragmentToRemove);
                transaction.remove(fragmentToRemove);
                j--;
            }
            transaction.commit();
            fragmentManager.executePendingTransactions();
            notifyDataSetChanged();
            // Add new fragment
            Fragment fragment = new DummySectionFragment();
            currentFragments.add(position, fragment);
            notifyDataSetChanged();
            actionBar.addTab(actionBar.newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(position))
                    .setTabListener(TabTestActivity.this), position);
            // Readd fragments
            if (fragmentsToRemove.size() > 0) {
                i = 1;
                for (Fragment fragmentToRemove : fragmentsToRemove) {
                    currentFragments.add(DummySectionFragment.cloneExistingFragment((DummySectionFragment)fragmentToRemove));
                    notifyDataSetChanged();
                    actionBar.addTab(actionBar.newTab()
                            .setText(mSectionsPagerAdapter.getPageTitle(position + i))
                            .setTabListener(TabTestActivity.this), position + i);
                    i++;
                }
            }
        }

        public void removeFragment(int position) {
            // Remove fragments from position
            List<Fragment> fragmentsToRemove = new ArrayList<Fragment>(currentFragments.subList(position, currentFragments.size()));
            int i = currentFragments.size() - 1;
            int j = -1;
            int k = i;
            while (i >= position) {
                currentFragments.remove(i);
                i--;
                j++;
            }
            notifyDataSetChanged();
            final ActionBar actionBar = getActionBar();
            while (k >= position) {
                actionBar.removeTabAt(k);
                k--;
            }
            android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
            while (j >= 0) {
                Fragment fragmentToRemove = fragmentsToRemove.get(j);
                transaction.detach(fragmentToRemove);
                transaction.remove(fragmentToRemove);
                j--;
            }
            transaction.commitAllowingStateLoss();
            fragmentManager.executePendingTransactions();
            notifyDataSetChanged();
            // Readd fragments (except one)
            if (fragmentsToRemove.size() > 1) {
                i = 0;
                for (Fragment fragment : fragmentsToRemove.subList(1, fragmentsToRemove.size())) {
                    currentFragments.add(DummySectionFragment.cloneExistingFragment((DummySectionFragment)fragment));
                    notifyDataSetChanged();
                    actionBar.addTab(actionBar.newTab()
                            .setText(mSectionsPagerAdapter.getPageTitle(position + i))
                            .setTabListener(TabTestActivity.this), position + i);
                    i++;
                }
            }
        }

        public void replaceFragment(int position) {
            // Remove fragments from position
            List<Fragment> fragmentsToRemove = new ArrayList<Fragment>(currentFragments.subList(position, currentFragments.size()));
            int i = currentFragments.size() - 1;
            int j = -1;
            int k = i;
            while (i >= position) {
                currentFragments.remove(i);
                i--;
                j++;
            }
            notifyDataSetChanged();
            final ActionBar actionBar = getActionBar();
            while (k >= position) {
                actionBar.removeTabAt(k);
                k--;
            }
            android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
            while (j >= 0) {
                Fragment fragmentToRemove = fragmentsToRemove.get(j);
                transaction.detach(fragmentToRemove);
                transaction.remove(fragmentToRemove);
                j--;
            }
            transaction.commit();
            fragmentManager.executePendingTransactions();
            notifyDataSetChanged();
            // Add new fragment
            Fragment fragment = new DummySectionFragment();
            currentFragments.add(position, fragment);
            notifyDataSetChanged();
            actionBar.addTab(actionBar.newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(position))
                    .setTabListener(TabTestActivity.this), position);
            // Readd fragments (except one)
            if (fragmentsToRemove.size() > 0) {
                i = 1;
                for (Fragment fragmentToRemove : fragmentsToRemove.subList(1, fragmentsToRemove.size())) {
                    currentFragments.add(DummySectionFragment.cloneExistingFragment((DummySectionFragment)fragmentToRemove));
                    notifyDataSetChanged();
                    actionBar.addTab(actionBar.newTab()
                            .setText(mSectionsPagerAdapter.getPageTitle(position + i))
                            .setTabListener(TabTestActivity.this), position + i);
                    i++;
                }
            }
        }

        @Override
        public Fragment getItem(int position) {
            if (currentFragments == null) {
                currentFragments = new ArrayList<Fragment>();
            }
            while (currentFragments.size() <= position) {
                currentFragments.add(null);
            }
            if (currentFragments.get(position) != null) {
                return currentFragments.get(position);
            }
            Fragment fragment = new DummySectionFragment();
            currentFragments.set(position, fragment);
            return fragment;
        }

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

        @Override
        public int getItemPosition(Object object) {
            int position = currentFragments.indexOf(object);
            if (position == -1) {
                return PagerAdapter.POSITION_NONE;
            }
            return position;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return ((DummySectionFragment)getItem(position)).getTitle();
        }
    }

    public static class DummySectionFragment extends Fragment {
        private int sectionNumber;

        public DummySectionFragment() {
            super();
            sectionNumber = ++tabCount;
        }

        public static DummySectionFragment cloneExistingFragment(DummySectionFragment fragment) {
            DummySectionFragment cloned = new DummySectionFragment();
            // Hack for avoiding autoincrement
            --tabCount;
            cloned.sectionNumber = fragment.getSectionNumber();
            return cloned;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_tab_test_dummy,
                    container, false);
            TextView dummyTextView = (TextView) rootView
                    .findViewById(R.id.section_label);
            dummyTextView.setText(String.format(labelString, sectionNumber));
            return rootView;
        }

        public int getSectionNumber() {
            return sectionNumber;
        }

        public String getTitle() {
            return String.format(labelString, sectionNumber);
        }
    }

}
于 2013-11-11T03:29:22.010 に答える