我有主要的活动,这将从一个网址异步获得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错误,但自从我创建这个应用程序以来,它一直都在那里,它运行得很好,所以这不是问题所在(尽管如果你能指出如何解决这个问题,那就太好了)。在mSermonFragment.updateListView(sermonsList);上,MainActivity.java:174是这一行
如何确保它已正确填充?最好是异步的,这样它就不会锁定UI,可能会在异步完成后更新listview。
这将是很好的,如果你也可以指出,如何使它在异步期间,它将检查是否有互联网连接,列表视图将显示加载循环,如果它没有互联网,或空的列表,它将不显示数据,否则它将显示列表
发布于 2014-07-22 05:22:30
由于您只有两个片段,因此您可以跟踪它们以保存实例。使用回调并不是最好的选择。
因此,在您的寻呼机适配器中:
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[] data)方法,这样您就可以在第一次网络调用时初始化片段数据,以确保您的片段有一个数据集可用,然后按上述方式进行更新。
发布于 2014-07-22 04:18:53
为什么不调用/执行
sermonsList = ((MainActivity)getActivity()).getSermonsList();
在AsyncJob的onPostExecute()中?
onPostExecute是在UI线程上运行的,所以应该没有问题
发布于 2014-07-22 04:19:18
有很多选择:
AsyncTask中,并在活动中的onPostExecute.AsyncTask。更新片段中数据的示例:
public class SermonsFragment extends ListFragment {
public void update(String[] sermonsList){
listAdapter.addAll(sermonsList);
listAdapter.notifyDataSetChanged();
}
}https://stackoverflow.com/questions/24873709
复制相似问题