Activity using ViewPager, PagerAdapter and AsyncTask causes empty view

I am trying to create an Activity that will serve as a daily calendar view. When a user clicks left or right, they will be sent tomorrow or yesterday and so on through the calendar.

I decided to use ViewPager / PagerAdapter to process the views and control the paging in days.

As part of setting Day View, the application will go to my API and request any meetings for that day. Appointments will be returned and displayed on that day. To get data from the API, I use AsyncTask. So instantiateItem() calls the API and sets an empty listView. BroadcastReceiver then captures the response, analyzes the data and displays it.

The problem I am facing is that the first displayed view is always empty. The views on the left or on the right are filled, and if I go with two positions in any direction, it’s enough for the original to scan to destroy, and then return to the original view, it has data. Why? How to make the first submission complete without moving 2 spaces?

Here is my activity. Currently, I don't parse the data returned from the API, just modeling with a list of strings on average.

 public class MyPagerActivity extends Activity { private ViewPager myPager; private static int viewCount = 1000; private Context ctx; private MyPagerAdapter myAdapter; private static final String tag = "MyPagerActivity"; private static final String apiAction = "getAppointmentsForDate"; private static final String apiUri = "https://myAPI.com/api.php"; private static final String resource = "appointments"; private static final String action = "getappointmentsfordate"; private static final String date = "20120124"; private ProgressDialog progress; private SharedPreferences loginPreferences; private SharedPreferences.Editor loginPreferencesEditor; private ListView v; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ctx = this; myAdapter = new MyPagerAdapter(); myPager = (ViewPager) findViewById(R.id.myPager); myPager.setAdapter(myAdapter); myPager.setCurrentItem(500); } private class MyPagerAdapter extends PagerAdapter { @Override public int getCount() { return viewCount; } @Override public Object instantiateItem(View collection, int position) { try { Log.d(tag, "trying http connection"); loginPreferences = getSharedPreferences("loginPrefs", MODE_PRIVATE); loginPreferencesEditor = loginPreferences.edit(); String authToken = loginPreferences.getString("authToken", ""); String staffOrRoomsId = loginPreferences.getString("staffOrRoomsId", ""); String staffOrRoomsIdName = loginPreferences.getString("staffOrRoomsIdName", ""); HttpPost apiRequest = new HttpPost(new URI(apiUri)); List<NameValuePair> parameters = new ArrayList<NameValuePair>(); parameters.add(new BasicNameValuePair("authToken", authToken)); parameters.add(new BasicNameValuePair("resource", resource)); parameters.add(new BasicNameValuePair("action", action)); parameters.add(new BasicNameValuePair("date", date)); parameters.add(new BasicNameValuePair(staffOrRoomsIdName, staffOrRoomsId)); apiRequest.setEntity(new UrlEncodedFormEntity(parameters)); RestTask task = new RestTask(ctx, apiAction); task.execute(apiRequest); //Display progress to the user // progress = ProgressDialog.show(ctx, "Searching", "Waiting For Results...", true); } catch (Exception e) { e.printStackTrace(); } Log.d(tag, "Creating another view! Position: " + position); myPager.setTag(collection); v = new ListView(ctx); ((ViewPager) collection).addView(v, 0); return v; } @Override public void destroyItem(View collection, int position, Object view) { Log.d(tag, "Destroying position: " + position + "!"); ((ViewPager) collection).removeView((ListView) view); } @Override public boolean isViewFromObject(View view, Object object) { return view==((ListView)object); } @Override public void finishUpdate(View arg0) {} @Override public void restoreState(Parcelable arg0, ClassLoader arg1) {} @Override public Parcelable saveState() { return null; } @Override public void startUpdate(View arg0) {} } @Override public void onResume() { super.onResume(); registerReceiver(receiver, new IntentFilter(apiAction)); } @Override public void onPause() { super.onPause(); unregisterReceiver(receiver); } private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //Clear progress indicator if (progress != null) { progress.dismiss(); } Log.d(tag, "Broadcast received"); String[] from = new String[] { "str" }; int[] to = new int[] { android.R.id.text1 }; List<Map<String, String>> items = new ArrayList<Map<String, String>>(); for (int i = 0; i < 20; i++) { Map<String, String> map = new HashMap<String, String>(); map.put("str", String.format("Item %d", i + 1)); items.add(map); } SimpleAdapter adapter = new SimpleAdapter(ctx, items, android.R.layout.simple_list_item_1, from, to); v.setAdapter(adapter); } }; } 

Thanks for taking the time to review this issue!

+6
source share
1 answer

By default, a ViewPager not only loads the current visible page, but also the page in both directions. This is offscreenPageLimit . The minimum value is 1.

instantiateItem will be invoked for every page he wants to create. In your instantiateItem implementation, you start AsyncTask and set the value to v . Only the last call to instantiateItem (i.e., the last page before offscreenPageLimit ) will have the correct destination v , and therefore the first page will not be filled initially.

You cannot count on the last call to instantiateItem to point to the current active page. I would switch to using a snippet for each page that supports its own HTTP request and ListView .

+4
source

Source: https://habr.com/ru/post/909785/


All Articles