我有一个主要活动,它将从url async
获取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。
如果您还可以指出,如果在异步期间如何制作它会很好,它将检查是否有互联网连接,列表视图将显示加载圈,如果它没有互联网,或者空列表它将不显示任何数据,否则将显示列表
答案 0 :(得分:4)
由于您只有两个片段,因此可以跟踪它们保存实例。使用回调建议它不是最好的选择。
所以,在你的寻呼机适配器中:
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)
方法,这样您就可以在第一次网络调用时初始化片段数据,以确保您的片段有一个数据集可以使用,然后按照描述进行更新上方。
答案 1 :(得分:2)
你为什么不打电话/执行
sermonsList =((MainActivity)getActivity())。getSermonsList();
在AsyncJob的onPostExecute()中?
onPostExecute在UI-Thread上运行 - 所以应该没问题
答案 2 :(得分:1)
有很多选择:
AsyncTask
并更新onPostExecute
。AsyncTask
。更新片段中数据的示例:
public class SermonsFragment extends ListFragment {
public void update(String[] sermonsList){
listAdapter.addAll(sermonsList);
listAdapter.notifyDataSetChanged();
}
}
答案 3 :(得分:1)
这可能是主题,但我刚使用handshake
和volley
网址遇到了类似的https
错误。请查看here以获取更多信息。
简单检查您的连接是否被拒绝是信任所有SSL证书。 (这应该仅用于测试!! )。
在第一次通话之前运行此功能(f.e.extend Application
并在onCreate
中调用以下内容)
//trust all SSL
SSLCertificateHandler.nuke();
The Trust-everything-class:
public class SSLCertificateHandler {
protected static final String TAG = "NukeSSLCerts";
public static void nuke() {
try {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] myTrustedAnchors = new X509Certificate[0];
return myTrustedAnchors;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
} catch (Exception e) {
}
}
}
答案 4 :(得分:0)
onResume()填充listview的方法
答案 5 :(得分:0)
如果我可以帮助你,那将是很好的,因为我也遇到过这样的问题......
你想设置包含你的asynctask提供的字符串数组的适配器。
在TabsPagerAdapter.class中创建构造函数.........
ArrayList<String> arrayList_Tab = new ArrayList<String>();
** Constructor of the class */
public TabsPagerAdapter(FragmentManager fm,
ArrayList<String> arrayList1) {
super(fm);
this.arrayList = arrayList1;
................
@Override
public Fragment getItem(int index) {
Bundle data = new Bundle();
switch (index) {
case 0:
SermonsFragment ment = new SermonsFragment ();
data.putStringArrayList("data", arrayList);
ment.setArguments(data);
return ment;
case 1:
//More fragment activity
return new MoreFragment();
}
return null;
}
我已经完成了这个arraylist但你可以通过传递数组作为参数来做到这一点。 在你的MainActivity .. 将您的asynctask数据添加到arraylist然后传递给TabsPagerAdapter类
mAdapter = new TabsPagerAdapter(getFragmentManager());
更改为
mAdapter = new TabsPagerAdapter(getFragmentManager(),ArrayLListgotfromAsyctask);
现在让你在SermonsFragment课上的arraylist: -
ArrayList<String> arrayList = new ArrayList<String>();
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
arrayList = getArguments().getStringArrayList("data");
}
现在您可以将arraylist设置为适配器。
祝你好运!!!答案 6 :(得分:0)
public void updateData(String[] newData) {
this.listAdapter.clear();
for(int i = 0; i < newData.length; i++) {
this.listAdapter.add(newData[i]);
}
this.listAdapter.notifyDataSetChanged();
}
// call this method in onPostExecute() method . By calling listAdapter.notifyDataSetChanged(); this adapter is updated with the data which comes from JSON object .
希望它能帮助你:)