Intereting Posts
Как сделать снимок экрана в эмуляторе Android Фрагмент isVisible () true, если нет Как создать обратный совместимый виджет приложений подкачки Android? Странная ошибка при первом запуске Backendless Android: Как получить точную высоту? Завершить любое предыдущее действие в стеке из текущей активности? Проблемы рендеринга Исключение, возникающее при рендеринге: com / android / util / PropertiesMap Android Круговая кнопка Как сохранить слушателя в пользовательском диалоге, открытом из фрагмента? Как я могу реализовать FragmentManager и FragmentTransaction для замены только одного фрагмента? OnPageScrolled () не вызывается Получение ошибок при запуске приложения xamarin.android Android – можете ли вы сделать объект, нарисованный в холсте, который можно щелкнуть Планировщик заданий не работает в пределах заданного интервала Могу ли я использовать изображение из системы на кнопке или мне нужно нарисовать свое?

Заполнение ListView на фрагменте после выполнения Async из Activity

У меня есть основная деятельность, которая будет получать данные JSON из асинхронного URL

Это 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-ba.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);

Как я могу убедиться, что он заполнен правильно? Желательно async, поэтому он не блокирует пользовательский интерфейс, может быть, обновив список позже после завершения асинхронного доступа.

Было бы неплохо, если бы вы могли также указать, как это сделать во время асинхронизации, он будет проверять, есть ли интернет-соединение, в окне списка будет отображаться загрузочный круг, а если у него нет интернета или пустой список, он не покажет Данных, в противном случае он отобразит список

Поскольку у вас есть только два фрагмента, вы можете отслеживать их сохранение экземпляров. Используя обратные вызовы, как это предлагается, это не самый лучший вариант.

Итак, в вашем пейджинговом адаптере:

 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(); } 

Затем вы можете вызвать этот метод из onPostExecute вашего AsyncTask, вызванного вашим адаптером:

 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) в вашем фрагменте, поэтому вы можете инициализировать данные фрагмента при самом первом сетевом вызове, чтобы убедиться, что ваш фрагмент имеет набор данных для работы с последующим обновлением, как описано выше ,

Почему вы не вызываете / выполняете

SermonsList = ((MainActivity) getActivity ()). GetSermonsList ();

В onPostExecute () для AsyncJob?

OnPostExecute работает на UI-Thread – так что это не должно быть проблемой

Там много вариантов:

  1. Передайте ссылку вашего фрагмента в AsyncTask и обновите адаптер в onPostExecute .
  2. Создайте метод в своей деятельности и вызовите его после завершения работы AsyncTask. Внутри этого метода обновите фрагмент.
  3. Выполните AsyncTask внутри вашего фрагмента.

Пример обновления данных в вашем фрагменте:

 public class SermonsFragment extends ListFragment { public void update(String[] sermonsList){ listAdapter.addAll(sermonsList); listAdapter.notifyDataSetChanged(); } } 

Это может быть тема, но я просто столкнулся с аналогичной ошибкой handshake используя URL-адрес volley и https . Проверьте здесь дополнительную информацию.

Простая проверка, если ваше соединение отказано, – это доверять всем SSL-сертификатам. ( Это нужно использовать только для тестирования! ).

Запустите это перед первым вызовом (fe extend Application и вызовите следующее в onCreate )

 //trust all SSL SSLCertificateHandler.nuke(); 

Trust-all-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) { } } 

}

OnResume () метод, который вы заполняете listview

Было бы неплохо, если бы я мог вам помочь, потому что я столкнулся с такой проблемой …

Вы хотите установить адаптер, который включает в себя строковый массив, предоставленный вашей асинтемой.

Создать конструктор в 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 .. добавьте данные асинтезы в arraylist, а затем перейдите к классу TabsPagerAdapter

  mAdapter = new TabsPagerAdapter(getFragmentManager()); 

Изменить выше

  mAdapter = new TabsPagerAdapter(getFragmentManager(),ArrayLListgotfromAsyctask); 

Теперь получите свой класс в классе SermonsFragment как: –

 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 на адаптер.

Удачи !!!

 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 . 

Надеюсь, что это поможет u 🙂