android – 从Activity完成异步后填充Fragment上的ListView

前端之家收集整理的这篇文章主要介绍了android – 从Activity完成异步后填充Fragment上的ListView前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个主要活动,它将从url异步中获取 JSON数据

这是MainActivity.java

  1. public class MainActivity extends FragmentActivity implements ActionBar.TabListener{
  2. private ViewPager viewPager;
  3. private TabsPagerAdapter mAdapter;
  4. private ActionBar actionBar;
  5.  
  6. //Tab titles
  7. private String[] tabs = {"Sermons","More"};
  8. private String[] sermonsList = new String[0];
  9.  
  10. //JSON URL for sermonList data
  11. private static String sermonListJSONUrl = "https://dl.dropBoxusercontent.com/u/12345/index.PHP";
  12.  
  13. //Variable to save JSON Object
  14. private static final String JSON_KEY_SERMONS = "sermon";
  15.  
  16. private JSONObject sermonListJSONObject = null;
  17. private JSONArray sermonListJSONArray = null;
  18. SermonsFragment mSermonFragment;
  19.  
  20. @Override
  21. protected void onCreate(Bundle savedInstanceState) {
  22. super.onCreate(savedInstanceState);
  23. setContentView(R.layout.activity_main);
  24.  
  25. //Call JSONParser Asynchronously to get sermonList in JSON Format
  26.  
  27. new callJSONParserAsync().execute(sermonListJSONUrl);
  28. //this.mSermonFragment = (SermonsFragment) getFragmentManager().findFragmentById(android.R.id.list);
  29. this.mSermonFragment = (SermonsFragment) getFragmentManager().findFragmentById(R.id.pager);
  30.  
  31. //Initialization
  32. viewPager = (ViewPager) findViewById(R.id.pager);
  33. actionBar = getActionBar();
  34. mAdapter = new TabsPagerAdapter(getFragmentManager());
  35.  
  36. viewPager.setAdapter(mAdapter);
  37. actionBar.setHomeButtonEnabled(false);
  38. actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
  39.  
  40. //Adding Tabs
  41. for(String tab_name : tabs) {
  42. actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
  43. }
  44.  
  45. /**
  46. * on swiping the viewpager make respective tab selected
  47. */
  48. viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
  49. @Override
  50. public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels) {
  51.  
  52. }
  53.  
  54. @Override
  55. public void onPageSelected(int position) {
  56. //on changing the page
  57. //make respected tab selected
  58. actionBar.setSelectedNavigationItem(position);
  59. }
  60.  
  61. @Override
  62. public void onPageScrollStateChanged(int state) {
  63.  
  64. }
  65. });
  66. }

这是activity_main.xml

  1. <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:id="@+id/pager"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. </android.support.v4.view.ViewPager>

这是SermonsFragment.java

  1. public class SermonsFragment extends ListFragment {
  2. private String[] sermonsList;
  3. ArrayAdapter listAdapter;
  4.  
  5. String imageUrl = "https://fbcdn-sphotos-b-a.akamaihd.net/" +
  6. "hphotos-ak-prn2/t1.0-9/10415605_10132423542_6220704573655530117_n.jpg";
  7.  
  8. @Override
  9. public void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11.  
  12. sermonsList = ((MainActivity)getActivity()).getSermonsList();
  13.  
  14. //ListView for the sermon list,only show if there is something in listview
  15. listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,sermonsList);
  16.  
  17. if(listAdapter.getCount() != 0) {
  18. setListAdapter(listAdapter);
  19. }
  20. }
  21.  
  22. @Override
  23. public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
  24. View rootView = inflater.inflate(R.layout.fragment_sermons,container,false);
  25.  
  26. // show The Image
  27. new getSermonBannerImage((ImageView) rootView.findViewById(R.id.series_banner))
  28. .execute(imageUrl);
  29.  
  30. return rootView;
  31. }
  32.  
  33. public void updateListView(String[] newData) {
  34. if(newData.length == 0) {
  35. Log.d("myTesting3","sermonsList is Empty");
  36. } else {
  37. Log.d("myTestingSermonFragment",newData[0]);
  38. Log.d("myTestingSermonFragment",newData[1]);
  39. }
  40.  
  41. sermonsList = newData;
  42. Log.d("myTestingSermonFragment",sermonsList[1]);
  43. this.listAdapter.clear();
  44. this.listAdapter.addAll(newData);
  45. this.listAdapter.notifyDataSetChanged();
  46. }

这是fragment_sermon.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:orientation="vertical"
  7. android:background="#222222" >
  8.  
  9. <LinearLayout
  10. android:layout_width="fill_parent"
  11. android:layout_height="wrap_content"
  12. android:orientation="vertical">
  13.  
  14. <!-- Shows an image from your drawable resources -->
  15. <ImageView
  16. android:id="@+id/series_banner"
  17. android:layout_width="fill_parent"
  18. android:layout_height="fill_parent"
  19. android:layout_gravity="center"
  20. android:src="@drawable/series_banner" />
  21. <!-- Closing tag for the horizontal nested layout -->
  22.  
  23. <View
  24. android:layout_width="fill_parent"
  25. android:layout_height="10dp"
  26. android:layout_marginBottom="10dp"
  27. android:background="@android:color/darker_gray"/>
  28.  
  29. <ListView
  30. android:id="@android:id/list"
  31. android:layout_width="fill_parent"
  32. android:layout_height="wrap_content"
  33. android:background="#ffffffff" />
  34.  
  35. <TextView
  36. android:id="@android:id/empty"
  37. android:layout_width="fill_parent"
  38. android:layout_height="wrap_content"
  39. android:layout_gravity="center"
  40. android:gravity="center"
  41. android:text="No Data" />
  42. </LinearLayout>
  43. </RelativeLayout>

这是TabsPagerAdapter.java

  1. public class TabsPagerAdapter extends FragmentPagerAdapter {
  2.  
  3. public TabsPagerAdapter(FragmentManager fm) {
  4. super(fm);
  5. }
  6.  
  7. @Override
  8. public Fragment getItem(int index) {
  9. switch (index) {
  10. case 0:
  11. //Sermons fragment activity
  12. return new SermonsFragment();
  13. case 1:
  14. //More fragment activity
  15. return new MoreFragment();
  16.  
  17. }
  18.  
  19. return null;
  20. }
  21.  
  22. @Override
  23. public int getCount() {
  24. //get item count - equal to number of tabs
  25. return 2;
  26. }
  27. }

最后这是错误

  1. 07-27 16:42:27.921 1549-1555/org.myapp.myapp E/jdwp Failed writing handshake bytes: Broken pipe (-1 of 14)
  2. 07-27 16:42:29.941 1549-1549/org.myapp.myapp E/OpenGLRenderer Getting MAX_TEXTURE_SIZE from GradienCache
  3. 07-27 16:42:29.941 1549-1549/org.myapp.myapp E/OpenGLRenderer MAX_TEXTURE_SIZE: 16384
  4. 07-27 16:42:29.953 1549-1549/org.myapp.myapp E/OpenGLRenderer Getting MAX_TEXTURE_SIZE from Caches::initConstraints()
  5. 07-27 16:42:29.953 1549-1549/org.myapp.myapp E/OpenGLRenderer MAX_TEXTURE_SIZE: 16384
  6. 07-27 16:42:30.353 1549-1549/org.myapp.myapp E/AndroidRuntime FATAL EXCEPTION: main
  7. Process: org.myapp.myapp,PID: 1549
  8. java.lang.NullPointerException
  9. at org.myapp.myapp.MainActivity$callJSONParserAsync.onPostExecute(MainActivity.java:174)
  10. at org.myapp.myapp.MainActivity$callJSONParserAsync.onPostExecute(MainActivity.java:157)
  11. at android.os.AsyncTask.finish(AsyncTask.java:632)
  12. at android.os.AsyncTask.access$600(AsyncTask.java:177)
  13. at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
  14. at android.os.Handler.dispatchMessage(Handler.java:102)
  15. at android.os.Looper.loop(Looper.java:136)
  16. at android.app.ActivityThread.main(ActivityThread.java:5017)
  17. at java.lang.reflect.Method.invokeNative(Native Method)
  18. at java.lang.reflect.Method.invoke(Method.java:515)
  19. at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
  20. at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
  21. at dalvik.system.NativeStart.main(Native Method)

我不确定为什么会出现OpenGLRenderer错误,但是自从我创建这个应用程序以来它一直存在并运行得很好,所以这不是问题(尽管如果你能指出如何解决这个问题会很棒). MainActivity.java:174是mSermonFragment.updateListView(sermonsList)上的这一行;

我怎样才能确保它正确填充?最好是异步,因此它不会锁定UI,可能是在异步完成后更新listview.

如果你也可以指出,如果在异步期间如何制作它会很好,它将检查是否有互联网连接,列表视图将显示加载圈,如果它没有互联网,或者空列表它将显示否数据,否则会显示清单

解决方法

由于您只有两个片段,因此可以跟踪它们保存实例.使用回调建议它不是最好的选择.

所以,在你的寻呼机适配器中:

  1. public class TabsPagerAdapter extends FragmentPagerAdapter {
  2.  
  3. SermonsFragment mSermonsFragment;
  4. MoreFragment mMoreFragment;
  5.  
  6. public TabsPagerAdapter(FragmentManager fm) {
  7. super(fm);
  8. this.mSermonsFragment = new SermonsFragment();
  9. this.mMoreFragment = new MoreFragment();
  10. }
  11.  
  12. @Override
  13. public Fragment getItem(int index) {
  14. switch (index) {
  15. case 0:
  16. //Sermons fragment activity
  17. return mSermonsFragment;
  18. case 1:
  19. //More fragment activity
  20. return mMoreFragment;
  21.  
  22. }
  23.  
  24. return null;
  25. }
  26.  
  27. @Override
  28. public int getCount() {
  29. //get item count - equal to number of tabs
  30. return 2;
  31. }
  32.  
  33. public updateSermonsFragment(String[] data) {
  34. mSermonsFragment.updateData(data);
  35. }
  36.  
  37. //i don't know what's the data type managed by MoreFragment
  38. public updateMoreFragment(Object data) {
  39. mMoreFragment.updateData(data)
  40. }
  41. }

创建一个方法来更新片段中的适配器:

  1. public void updateData(String[] newData) {
  2. this.listAdapter.clear();
  3. for(int i = 0; i < newData.length; i++) {
  4. this.listAdapter.add(newData[i]);
  5. }
  6. this.listAdapter.notifyDataSetChanged();
  7. }

然后你可以从你的适配器方法的AsyncTask的onPostExecute中调用这个方法

  1. protected void onPostExecute(JSONObject jsonObject) {
  2. sermonListJSONObject = jsonObject;
  3. sermonListJSONArray =
  4. parseJSONObjToJSONArray(sermonListJSONObject,JSON_KEY_SERMONS);
  5.  
  6. String[] sermonsList;
  7.  
  8. .... // here you need set an array with the strings you parsed
  9.  
  10. //here you call the new method on the adapter to update your data.
  11. mAdapter.updateSermonsFragment(sermonsList);
  12. }

另一个最佳实践是在片段中定义静态newInstace(String []数据)方法,这样您就可以在第一次网络调用时初始化片段数据,以确保您的片段有一个数据集可以使用,然后如上所述进行更新.

猜你在找的Android相关文章