簡體   English   中英

回到viewpager中的上一個片段時如何更新片段中的列表視圖

[英]How to update listview in fragment when back to previous fragment inside viewpager

好吧,考慮到我有兩個片段FragmentTab1ShowAllContactFragment FragmentTab1包含一個列表視圖& 和一個按鈕 單擊該按鈕時,我將替換我的 viewpager 中的 ShowAllContactFragment。 當顯示ShowAllContactFragment 時,用戶可以通過在列表視圖中選擇復選框來選擇多個聯系人,它還有一個添加聯系人按鈕。

我需要什么:我想更新 FragmentTab1 中現有的列表視圖,當用戶在 ShowAllContactFragment 中按下ADD按鈕時,在此列表視圖中選擇一些聯系人后。 我還刪除了 ShowAllContactFragment,並在發生這種情況時顯示 FragmentTab1。

我的解決狀態:我關注android 開發者論壇,通過 Activity 在片段之間交流數據。 我就快完成了。 我在 ShowAllContactFragment 中創建接口 OnContactSelectedListener 並在 MainActivity 中實現。 一切都好! . 調試后,我檢查了我的回調方法,我在MainActivity 中有數據,但我無法替換 ShowAllContactFragment 並且無法顯示前一個片段 FragmentTab1 並更新它的列表視圖。

要從 FragmentTab1 打開 ShowAllContactFragment,我寫道:

ShowAllContactFragment allContactsFragment = new ShowAllContactFragment();

            FragmentTransaction transaction = getFragmentManager()
                    .beginTransaction();
            transaction.addToBackStack(null);
            transaction.add(R.id.fragmentTabLayout1, allContactsFragment);
            transaction.commit();

我的 MainActivity & FragmentAdapter 看起來:

public class MainActivity extends SherlockFragmentActivity implements
        ShowAllContactFragment.OnContactSelectedListener {

    ActionBar.Tab Tab1, Tab2, Tab3, Tab4;
    private Context context = this;
    // view pager
    // Declare Variables
    ActionBar actionBar;
    ViewPager mPager;
    Tab tab;
    FragmentAdapter mAdapter;
    List<Fragment> fragmentList = new ArrayList<Fragment>();
    ArrayList<Person> blackListPersonList;

    private final static String TAG_FRAGMENT = "TAG_FRAGMENT";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // set application in portrait mode
        ActivityHelper.initialize(this);

        actionBar = getSupportActionBar();
        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        addFragmentsInList();
        // Locate ViewPager in activity_main.xml
        mPager = (ViewPager) findViewById(R.id.pager);
        // add an adapter to pager
        mAdapter = new FragmentAdapter(getSupportFragmentManager(), mPager,
                actionBar, fragmentList);
        mPager.setAdapter(mAdapter);
        addActionBarTabs();

    }

    public void addFragmentsInList() {

        FragmentTab1 aFragmentTab1 = new FragmentTab1();

        fragmentList.add(new FragmentTab1());
        fragmentList.add(new FragmentTab2());
        fragmentList.add(new FragmentTab3());

    }

    private void addActionBarTabs() {

        String[] tabs = { "Tab 1", "Tab 2", "Tab 3" };
        for (String tabTitle : tabs) {
            ActionBar.Tab tab = actionBar.newTab().setText(tabTitle)
                    .setTabListener(tabListener);
            actionBar.addTab(tab);

        }

    }

    private ActionBar.TabListener tabListener = new ActionBar.TabListener() {
        @Override
        public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
            mPager.setCurrentItem(tab.getPosition());
        }

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

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // add action menu here
        MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.activity_itemlist, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle presses on the action bar items
        switch (item.getItemId()) {
        case R.id.add_item:
            // openSearch();
            Toast.makeText(context, " add_item  ", Toast.LENGTH_SHORT).show();
            return true;
        case R.id.about:
            // composeMessage();
            Toast.makeText(context, "   about", Toast.LENGTH_SHORT).show();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    class FragmentAdapter extends FragmentPagerAdapter implements
            ViewPager.OnPageChangeListener {

        private ViewPager mViewPager;
        final int TOTAL_PAGES = 3;
        private List<Fragment> fragments;
        SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

        public FragmentAdapter(FragmentManager fm, ViewPager pager,
                ActionBar actionBar, List<Fragment> fragmentsList) {
            super(fm);
            this.mViewPager = pager;
            this.mViewPager.setOnPageChangeListener(this);
            this.fragments = fragmentsList;
        }

        @Override
        public Fragment getItem(int position) {
            // switch (position) {
            // case 0:
            // return FragmentTab1.newInstance();
            // case 1:
            // return FragmentTab2.newInstance();
            // case 2:
            // return FragmentTab3.newInstance();
            // default:
            // throw new IllegalArgumentException(
            // "The item position should be less or equal to:"
            // + TOTAL_PAGES);
            // }

            return this.fragments.get(position);
        }

        @Override
        public int getCount() {
            // return TOTAL_PAGES;
            return this.fragments.size();

        }

        public ViewPager getViewPager() {

            return mViewPager;
        }

        // added newly
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Fragment fragment = (Fragment) super.instantiateItem(container,
                    position);
            registeredFragments.put(position, fragment);
            return fragment;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            registeredFragments.remove(position);
            super.destroyItem(container, position, object);
        }

        public Fragment getRegisteredFragment(int position) {
            return registeredFragments.get(position);
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

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

    @Override
    public void onBackPressed() {

        Log.e(TAG_FRAGMENT, "onBackPressed");

        FragmentManager fm = getSupportFragmentManager();
        if (fm.getBackStackEntryCount() > 0) {
            Log.i("MainActivity", "popping backstack");
            fm.popBackStack();
        } else {
            Log.i("MainActivity", "nothing on backstack, calling super");
            super.onBackPressed();
        }

    }


    @Override
    public void onContactSelected(ArrayList<Person> contactNumberlist) {
        // data comes here, no problem.
        this.blackListPersonList = contactNumberlist;
        Log.d("onContactSelected", "onContactSelected");

        // get error here
        FragmentTab1 aFragmentTab1 = (FragmentTab1) mAdapter.getItem(0);

        if (aFragmentTab1 != null) {
            aFragmentTab1.updateFragment1(blackListPersonList);
        }
        FragmentTransaction transaction = getSupportFragmentManager()
                .beginTransaction();

        transaction.add(R.id.fragment_all_contacts_layout, aFragmentTab1);
        transaction.commit();

    }

    public ArrayList<Person> getBlackListContacts() {

        return blackListPersonList;
    }

    // public Fragment getFragment(ViewPager pager){
    // Fragment theFragment = fragments.get(pager.getCurrentItem());
    // return theFragment;
    // }

}

FragmentTab1 看起來:

  public class FragmentTab1 extends SherlockFragment implements OnClickListener {

    Button btnTest;
    ViewPager pager;
    LinearLayout layoutBlockNumbers;
    LinearLayout layoutContact, layoutCallLog, layoutSMSLog, layoutManually;
    public Context mContext;
    CustomizedDialog dialog;
    private static final int CONTACT_PICKER_RESULT = 1001;
    private static final String DEBUG_TAG = "Contact List";
    private static final double RESULT_OK = -1;

    ListView listViewOnlyBlackListNumber;
    ArrayList<Person> personList;
    BlackListAdapter aBlackListAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragmenttab1, container,
                false);

        layoutBlockNumbers = (LinearLayout) rootView
                .findViewById(R.id.layoutAddBlockNumbers);
        layoutBlockNumbers.setOnClickListener(this);

        listViewOnlyBlackListNumber = (ListView) rootView
                .findViewById(R.id.listViewOnlyBlackListNumber);

        personList = ((MainActivity) getActivity()).getBlackListContacts();

        if (personList != null) {
            aBlackListAdapter = new BlackListAdapter(getActivity(), personList,
                    m_onSelectedEventCalender);
            listViewOnlyBlackListNumber.setAdapter(aBlackListAdapter);

        } else {
            listViewOnlyBlackListNumber.setEmptyView(container);
        }

        return rootView;

    }

    public void updateFragment1(ArrayList<Person> personList) {

        // trying to update when came back here
        aBlackListAdapter = new BlackListAdapter(getActivity(), personList,
                m_onSelectedEventCalender);

        listViewOnlyBlackListNumber.setAdapter(aBlackListAdapter);
        aBlackListAdapter.notifyDataSetChanged();
    }
}

在 MainActivity 內的 onContactSelected 中獲取錯誤

       10-30 00:22:29.674: E/AndroidRuntime(26834): FATAL EXCEPTION: main
     java.lang.IllegalStateException: Can't change container ID of fragment FragmentTab1{42d27380 #0 id=0x7f040032 android:switcher:2130968626:0}: was 2130968626 now 2130968638
   E/AndroidRuntime(26834):     at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:407)
     E/AndroidRuntime(26834):   at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:384)
     E/AndroidRuntime(26834):   at com.mobigic.callblocker.MainActivity.onContactSelected(MainActivity.java:240)

希望,有人幫助我。

你的問題不是很清楚,尤其是關於你如何處理這些片段的部分。 就像當你展示ShowAllContactFragment片段時,你把它放在哪個布局中? 從您發布的代碼來看,您似乎是在包含不正確的ViewPager的布局中直接盲目地添加ShowAllContactFragment片段。

與錯誤相關的是,您通過ViewPager的適配器獲得對FragmentManager已經管理的FragmentManager之一的ViewPager ,然后您重試將其添加到事務中,該操作將失敗。 如果您嘗試顯示之前顯示的FragmentTab1片段,在顯示並使用ShowAllContactFragment片段后,您應該嘗試通過其中一個popBackStack...()方法簡單地刪除FragmentManager的最后記錄的操作。

編輯:我查看了您的代碼,但您在做什么仍然不明確。 我已經查看了主要活動的布局,但您沒有 id 為R.id.fragment_all_contacts_layout的容器,所以我假設您正以某種方式嘗試在舊FragmentTab1的布局中插入新的FragmentTab1真的沒有任何意義(更不用說您將ShowAllContactFragment添加到一個我也看不到 ID 為R.id.fragmentTabLayout1的容器中)。 無論如何,我假設你想要的ShowAllContactFragment更換FragmentTab1ViewPager 為此,您需要一個包裝器片段來保存兩個嵌套片段並啟用它們之間的通信。 例如包裝片段:

public static class WrapperFragment extends Fragment implements
        OnContactSelectedListener {

    private static final String TAG_FIRST = "tag_first";
    private static final String TAG_SECOND = "tag_second";
    private static final int CONTENT_ID = 1000;
    private FragmentTab1 mFrag1;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        FrameLayout content = new FrameLayout(getActivity());
        content.setId(CONTENT_ID);
        if (getChildFragmentManager().findFragmentByTag(TAG_SECOND) == null) {
            mFrag1 = (FragmentTab1) getChildFragmentManager()
                    .findFragmentByTag(TAG_FIRST);
            if (mFrag1 == null) {
                mFrag1 = new FragmentTab1();
                getChildFragmentManager().beginTransaction()
                        .add(CONTENT_ID, mFrag1, TAG_FIRST).commit();
            }
        }
        return content;
    }

    @Override
    public void onContactSelected(List<Person> contactNumberlist) {
        getChildFragmentManager().popBackStackImmediate();
        mFrag1.updateFragment1(contactNumberlist);
    }

    public void showPickerfragment() {
        getChildFragmentManager().beginTransaction()
                .replace(CONTENT_ID, new ShowAllContactFragment())
                .addToBackStack(null).commit();
    }

}

這將是您將在ViewPager的適配器中使用的片段,而不是FragmentTab1片段。 請注意,它實現了OnContactSelectedListener接口。 您還需要對代碼的其他部分進行一些更改:

@Override
public void onClick(View v) {
     if (v == layoutCallLog) {
     dialog.dismiss();
             // make the wrapper fragment to open the ShowAllContactFragment fragment
            ((WrapperFragment) getParentFragment()).showPickerfragment();
            // rest of the code

ShowAllContactFragment需要修改以將選擇事件發送到實現其接口的包裝器片段:

@Override
public void onClick(View v) {
    if (v == btnAdd) {
        Toast.makeText(getActivity(), "" + blockListedPersonList.size(),
                Toast.LENGTH_SHORT).show();
            ((OnContactSelectedListener) getParentFragment())
                .onContactSelected(blockListedPersonList);
    }
}

ShowAllContactFragment顯示在ViewPager時,在處理 BACK 按鈕的主要活動中:

@Override
public void onBackPressed() {
    if (mViewPager.getCurrentItem() == 0) { // I assumed 0 is the position in the adapter where the WrapperFragment will be used
        Fragment targetPage = getSupportFragmentManager()
                .findFragmentByTag("android:switcher:" + PAGER_ID + ":" + 0); // PAGER_ID is the id of the ViewPager
        if (targetPage.getChildFragmentManager().getBackStackEntryCount() > 0) {
            targetPage.getChildFragmentManager().popBackStack();
        }
        return;
    }
    super.onBackPressed();
}

請記住,您需要保存嵌套片段的數據。

我在不同的項目中使用了FragmentActivityViewPager ,有兩種解決方案:

1:您可以在FragmentTab1上使用onHiddenChanged(boolean hidden)方法。

override fun onHiddenChanged(hidden: Boolean) {
    // TODO Auto-generated method stub
    if (!hidden) {
        // check if personList size is changed 
        // and then call updateFragment1() methode
    }
    super.onHiddenChanged(hidden)
}

2:使用靜態方法:您可以將updateFragment1()方法updateFragment1() static因此當用戶按下“ADD”時,調用updateFragment1()

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM