2012-03-01 45 views
6

我在尝试构建一个将用作日历日视图的活动。当用户向左或向右滑动时,他们将在明天或昨天等日历中穿过。使用ViewPager,PagerAdapter和AsyncTask的活动导致空白视图

我决定使用ViewPager/PagerAdapter来处理视图并控制通过天的分页。

作为设置日视图的一部分,该应用程序将转到我的API并请求当天的任何约会。约会将在当天返回并显示。为了从API中检索数据,我使用了一个AsyncTask。所以基本上,instantiateItem()调用API并设置空的listView。然后BroadcastReceiver捕获响应,解析数据并显示它。

我遇到的问题是显示的第一个视图始终为空。左侧或右侧的视图已填充,如果我沿两个方向走两个位置,足以使原始视图被破坏,则返回到原始视图,它具有数据。 为什么?如何获得第一个视图,而不必移动两次?

这是我的活动。我目前还没有解析从API返回的数据,只是同时用一串字符串进行模拟。

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

感谢您花时间回顾这个问题!

+0

我们遇到了类似的问题,旧的结果仍然显示,直到向前或向后滑动1到3个位置。我们正在使用pageradapter/viewpager组合。是为每个页面使用片段的解决方案? – 2012-03-21 10:52:23

回答

4

默认情况下,ViewPager不仅加载当前可见的页面,而且加载页面到任一侧。这是offscreenPageLimit。最小值为1.

instantiateItem将为每个要创建的页面调用。在执行instantiateItem时,您将开始AsyncTask并将值指定为v。只有最后一次拨打instantiateItem(即最后一页到offscreenPageLimit)的电话才会有v的正确分配,因此第一个页面最初不会被填充。

您不能依靠最后一次致电instantiateItem来呼叫当前活动页面。我会切换到每个页面使用一个片段,该页面维护自己的HTTP请求和ListView

+0

可以请你检查问题这个类似的问题 - http://stackoverflow.com/questions/30555067/viewpager-not-displaying-content-of-first-view-that-is-being-opened – 2015-05-31 12:08:51

相关问题