Updating a ListView inside a Fragment placed on a ViewPager on DialogFragment dismiss

Title says all. We’ll see today how to proceed in order to update a ListView that is placed inside a Fragment (not a ListFragment) placed on a ViewPager just after dismissing aDialogFragment. Seems complicated, huh?

When may we need this?

Well, imagine that you have an Activity which layout uses tabs (represented by Fragments) and you want to use a ViewPager so it feels better to users. With a ViewPager you can swipe tabs, and that make users happy. Now, think about your Activity’s tabs: you may have three or four and one of them may be a ListView.

Finally, imagine that this ListView is updated every time user inputs data that is stored into a database. The user inputs data using a button that presents a Dialog with buttons or whatever the app needs to show. When the user pushes the OK button, the Dialog will call onDismiss(). And the ListView should update here, but it won’t do unless you notify it that there are changes.

Nice. How do we do that?

It’s really easy, but it may be confusing sometimes. We will consider that you created a project using Android Studio wizards and that you selected “Tabs+Swipe” navigation option. Take a look at your main Activity, there should be a custom FragmentPagerAdapter. We’ll make it “remember” your fragments. You can achieve this saving all yourFragments as individual objects or use an array. For example:

 1 public class MyPagerAdapter extends FragmentPagerAdapter {
 2 
 3         SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();      
 4 
 5         ...
 6 
 7         @Override
 8         public Fragment getItem(int position) {
 9             // getItem is called to instantiate the fragment for the given
10             // page.
11             Fragment fragment = new MyFragment();
12             Bundle args = new Bundle();
13             args.putInt(SectionFragment.ARG_SECTION_NUMBER, position + 1);
14             fragment.setArguments(args);
15             registeredFragments.put(position, fragment);
16             return fragment;
17         }
18 
19 
20         @Override
21         public void destroyItem(ViewGroup container, int position, Object object) {
22             registeredFragments.remove(position);
23             super.destroyItem(container, position, object);
24         }
25 
26         public Fragment getRegisteredFragment(int position) {
27             return registeredFragments.get(position);
28         }
29 
30         ...
31 
32     }

You just have to override destroyItem() and edit getItem() to handle when we modify the array. Also add getRegisteredFragment() so we can access the fragment array.

Now, on your DialogFragment, declare a new interface and use it on the onDismiss() method. Like this:

 1 public class MyDialogFragment extends DialogFragment implements
 2 DialogInterface.OnDismissListener{
 3 
 4 
 5     private OnDBChangedListener mCallback;   
 6 
 7     ...
 8     
 9     @Override
10     public void onDismiss(DialogInterface dialog) {
11         mCallback.onDBChanged();
12         super.onDismiss(dialog);
13     }
14 
15     // Container Activity must implement this interface
16     public interface OnDBChangedListener {
17         public void onDBChanged();
18     }
19 
20     @Override
21     public void onAttach(Activity activity) {
22         super.onAttach(activity);
23 
24         // This makes sure that the container activity has implemented
25         // the callback interface. If not, it throws an exception
26         try {
27             mCallback = (OnDBChangedListener) activity;
28         } catch (ClassCastException e) {
29             throw new ClassCastException(activity.toString() + " must implement
30                 OnDBChangedListener");
31         }
32     }
33 } 

Call it whatever you want and don’t forget to use onAttach() to be sure that your Activity is acting correctly. For this to happen you have to implement it on your Activity. So, add implements DialogFragmentName.OnDBChangedListener to your Activity declaration. Also, implement your interface method and use it to call a (yet to write) public method of your ListView fragment.

 1 public class MainActivity extends Activity implements ActionBar.TabListener,
 2 MyDialogFragment.OnDBChangedListener{
 3     ...
 4     @Override
 5     public void onDBChanged() {
 6         SectionFragment sFrag =
 7 (SectionFragment)mSectionsPagerAdapter.getRegisteredFragment(1);
 8          sFrag.updateDB();
 9     }
10 }

Finally, add a public method to your ListView fragment or the Activity will not be able to finish the job : ) Something like this will work if you are using SQLite databases:

 1     public void updateDB() {
 2         if(dataSource!=null) {
 3             ListView lView = (ListView)rootView.findViewById(R.id.listView);
 4             dataSource.open();
 5 
 6             List<Foo> foos = dataSource.getAllFoos();
 7             adapter = new ArrayAdapter<Foo>(context,
 8                     android.R.layout.simple_list_item_1,
 9                     foos);
10             lView.setAdapter(adapter);
11             dataSource.close();
12         }
13 
14     }

That’s it! Hope it helped someone : )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值