![](/img/trans.png)
[英]ListView of a Fragment (of a ViewPager inside a Fragment) that implements LoaderCallbacks<Cursor> is empty when I return back to it
[英]How to update listview in fragment when back to previous fragment inside viewpager
好吧,考慮到我有兩個片段FragmentTab1和ShowAllContactFragment 。 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
更換FragmentTab1
從ViewPager
。 為此,您需要一個包裝器片段來保存兩個嵌套片段並啟用它們之間的通信。 例如包裝片段:
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();
}
請記住,您需要保存嵌套片段的數據。
我在不同的項目中使用了FragmentActivity
和ViewPager
,有兩種解決方案:
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.