我有一个主要活动,它将从url异步中获取
JSON数据
这是MainActivity.java
- public class MainActivity extends FragmentActivity implements ActionBar.TabListener{
- private ViewPager viewPager;
- private TabsPagerAdapter mAdapter;
- private ActionBar actionBar;
- //Tab titles
- private String[] tabs = {"Sermons","More"};
- private String[] sermonsList = new String[0];
- //JSON URL for sermonList data
- private static String sermonListJSONUrl = "https://dl.dropBoxusercontent.com/u/12345/index.PHP";
- //Variable to save JSON Object
- private static final String JSON_KEY_SERMONS = "sermon";
- private JSONObject sermonListJSONObject = null;
- private JSONArray sermonListJSONArray = null;
- SermonsFragment mSermonFragment;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //Call JSONParser Asynchronously to get sermonList in JSON Format
- new callJSONParserAsync().execute(sermonListJSONUrl);
- //this.mSermonFragment = (SermonsFragment) getFragmentManager().findFragmentById(android.R.id.list);
- this.mSermonFragment = (SermonsFragment) getFragmentManager().findFragmentById(R.id.pager);
- //Initialization
- viewPager = (ViewPager) findViewById(R.id.pager);
- actionBar = getActionBar();
- mAdapter = new TabsPagerAdapter(getFragmentManager());
- viewPager.setAdapter(mAdapter);
- actionBar.setHomeButtonEnabled(false);
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
- //Adding Tabs
- for(String tab_name : tabs) {
- actionBar.addTab(actionBar.newTab().setText(tab_name).setTabListener(this));
- }
- /**
- * on swiping the viewpager make respective tab selected
- */
- viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
- @Override
- public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels) {
- }
- @Override
- public void onPageSelected(int position) {
- //on changing the page
- //make respected tab selected
- actionBar.setSelectedNavigationItem(position);
- }
- @Override
- public void onPageScrollStateChanged(int state) {
- }
- });
- }
这是activity_main.xml
- <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/pager"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- </android.support.v4.view.ViewPager>
这是SermonsFragment.java
- public class SermonsFragment extends ListFragment {
- private String[] sermonsList;
- ArrayAdapter listAdapter;
- String imageUrl = "https://fbcdn-sphotos-b-a.akamaihd.net/" +
- "hphotos-ak-prn2/t1.0-9/10415605_10132423542_6220704573655530117_n.jpg";
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- sermonsList = ((MainActivity)getActivity()).getSermonsList();
- //ListView for the sermon list,only show if there is something in listview
- listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,sermonsList);
- if(listAdapter.getCount() != 0) {
- setListAdapter(listAdapter);
- }
- }
- @Override
- public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
- View rootView = inflater.inflate(R.layout.fragment_sermons,container,false);
- // show The Image
- new getSermonBannerImage((ImageView) rootView.findViewById(R.id.series_banner))
- .execute(imageUrl);
- return rootView;
- }
- public void updateListView(String[] newData) {
- if(newData.length == 0) {
- Log.d("myTesting3","sermonsList is Empty");
- } else {
- Log.d("myTestingSermonFragment",newData[0]);
- Log.d("myTestingSermonFragment",newData[1]);
- }
- sermonsList = newData;
- Log.d("myTestingSermonFragment",sermonsList[1]);
- this.listAdapter.clear();
- this.listAdapter.addAll(newData);
- this.listAdapter.notifyDataSetChanged();
- }
这是fragment_sermon.xml
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:background="#222222" >
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <!-- Shows an image from your drawable resources -->
- <ImageView
- android:id="@+id/series_banner"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_gravity="center"
- android:src="@drawable/series_banner" />
- <!-- Closing tag for the horizontal nested layout -->
- <View
- android:layout_width="fill_parent"
- android:layout_height="10dp"
- android:layout_marginBottom="10dp"
- android:background="@android:color/darker_gray"/>
- <ListView
- android:id="@android:id/list"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="#ffffffff" />
- <TextView
- android:id="@android:id/empty"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:gravity="center"
- android:text="No Data" />
- </LinearLayout>
- </RelativeLayout>
这是TabsPagerAdapter.java
- public class TabsPagerAdapter extends FragmentPagerAdapter {
- public TabsPagerAdapter(FragmentManager fm) {
- super(fm);
- }
- @Override
- public Fragment getItem(int index) {
- switch (index) {
- case 0:
- //Sermons fragment activity
- return new SermonsFragment();
- case 1:
- //More fragment activity
- return new MoreFragment();
- }
- return null;
- }
- @Override
- public int getCount() {
- //get item count - equal to number of tabs
- return 2;
- }
- }
最后这是错误
- 07-27 16:42:27.921 1549-1555/org.myapp.myapp E/jdwp﹕ Failed writing handshake bytes: Broken pipe (-1 of 14)
- 07-27 16:42:29.941 1549-1549/org.myapp.myapp E/OpenGLRenderer﹕ Getting MAX_TEXTURE_SIZE from GradienCache
- 07-27 16:42:29.941 1549-1549/org.myapp.myapp E/OpenGLRenderer﹕ MAX_TEXTURE_SIZE: 16384
- 07-27 16:42:29.953 1549-1549/org.myapp.myapp E/OpenGLRenderer﹕ Getting MAX_TEXTURE_SIZE from Caches::initConstraints()
- 07-27 16:42:29.953 1549-1549/org.myapp.myapp E/OpenGLRenderer﹕ MAX_TEXTURE_SIZE: 16384
- 07-27 16:42:30.353 1549-1549/org.myapp.myapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
- Process: org.myapp.myapp,PID: 1549
- java.lang.NullPointerException
- at org.myapp.myapp.MainActivity$callJSONParserAsync.onPostExecute(MainActivity.java:174)
- at org.myapp.myapp.MainActivity$callJSONParserAsync.onPostExecute(MainActivity.java:157)
- at android.os.AsyncTask.finish(AsyncTask.java:632)
- at android.os.AsyncTask.access$600(AsyncTask.java:177)
- at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
- at android.os.Handler.dispatchMessage(Handler.java:102)
- at android.os.Looper.loop(Looper.java:136)
- at android.app.ActivityThread.main(ActivityThread.java:5017)
- at java.lang.reflect.Method.invokeNative(Native Method)
- at java.lang.reflect.Method.invoke(Method.java:515)
- at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
- at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
- at dalvik.system.NativeStart.main(Native Method)
我不确定为什么会出现OpenGLRenderer错误,但是自从我创建这个应用程序以来它一直存在并运行得很好,所以这不是问题(尽管如果你能指出如何解决这个问题会很棒). MainActivity.java:174是mSermonFragment.updateListView(sermonsList)上的这一行;
我怎样才能确保它正确填充?最好是异步,因此它不会锁定UI,可能是在异步完成后更新listview.
如果你也可以指出,如果在异步期间如何制作它会很好,它将检查是否有互联网连接,列表视图将显示加载圈,如果它没有互联网,或者空列表它将显示否数据,否则会显示清单
解决方法
由于您只有两个片段,因此可以跟踪它们保存实例.使用回调建议它不是最好的选择.
所以,在你的寻呼机适配器中:
- public class TabsPagerAdapter extends FragmentPagerAdapter {
- SermonsFragment mSermonsFragment;
- MoreFragment mMoreFragment;
- public TabsPagerAdapter(FragmentManager fm) {
- super(fm);
- this.mSermonsFragment = new SermonsFragment();
- this.mMoreFragment = new MoreFragment();
- }
- @Override
- public Fragment getItem(int index) {
- switch (index) {
- case 0:
- //Sermons fragment activity
- return mSermonsFragment;
- case 1:
- //More fragment activity
- return mMoreFragment;
- }
- return null;
- }
- @Override
- public int getCount() {
- //get item count - equal to number of tabs
- return 2;
- }
- public updateSermonsFragment(String[] data) {
- mSermonsFragment.updateData(data);
- }
- //i don't know what's the data type managed by MoreFragment
- public updateMoreFragment(Object data) {
- mMoreFragment.updateData(data)
- }
- }
创建一个方法来更新片段中的适配器:
- public void updateData(String[] newData) {
- this.listAdapter.clear();
- for(int i = 0; i < newData.length; i++) {
- this.listAdapter.add(newData[i]);
- }
- this.listAdapter.notifyDataSetChanged();
- }
然后你可以从你的适配器方法的AsyncTask的onPostExecute中调用这个方法:
- protected void onPostExecute(JSONObject jsonObject) {
- sermonListJSONObject = jsonObject;
- sermonListJSONArray =
- parseJSONObjToJSONArray(sermonListJSONObject,JSON_KEY_SERMONS);
- String[] sermonsList;
- .... // here you need set an array with the strings you parsed
- //here you call the new method on the adapter to update your data.
- mAdapter.updateSermonsFragment(sermonsList);
- }
另一个最佳实践是在片段中定义静态newInstace(String []数据)方法,这样您就可以在第一次网络调用时初始化片段数据,以确保您的片段有一个数据集可以使用,然后如上所述进行更新.