SectionsPagerAdapter不能正确加载片段

SectionsPagerAdapter不能正确加载片段

问题描述:

我有一个android活动,使用SectionsPagerAdapter显示3个选项卡,其中一个用于接收好友请求,一个用于发送好友请求,另一个用于当前好友。SectionsPagerAdapter不能正确加载片段

当我打开该活动时,它默认为选项卡0,接收到的请求,而是加载来自属于朋友片段的查询(使用parse.com)的结果。朋友片段通常不会显示任何内容,但会在后台运行“发送请求”查询。当转到发送选项卡时,它会显示正确的。但是,当我回到其他选项卡时,有时它会向我显示其他选项卡下的“已发送请求”列表,或者根本不显示任何内容,或者看似随机选择的三个选项卡中的一个。现在,这是我第一次使用标签片段,所以我的问题可能在那里,但是,我似乎无法找到它。

下面是友的活动,包含标签的代码:

public class FriendsActivity extends AppCompatActivity { 


    private SectionsPagerAdapter mSectionsPagerAdapter; 


    private ViewPager mViewPager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_friends); 

     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     // Create the adapter that will return a fragment for each of the three 
     // primary sections of the activity. 
     mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 

     // Set up the ViewPager with the sections adapter. 
     mViewPager = (ViewPager) findViewById(R.id.container); 
     mViewPager.setAdapter(mSectionsPagerAdapter); 

     TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); 
     tabLayout.setupWithViewPager(mViewPager); 


    } 

    /** 
    * A {@link FragmentPagerAdapter} that returns a fragment corresponding to 
    * one of the sections/tabs/pages. 
    */ 
    public class SectionsPagerAdapter extends FragmentPagerAdapter { 

     public SectionsPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      // getItem is called to instantiate the fragment for the given page. 
      // Return a PlaceholderFragment (defined as a static inner class below). 
      switch(position){ 
       case 0 : return ReceivedFragment.newInstance(); 
       case 1 : return ConnectionsFragment.newInstance(); 
       case 2 : return SentFragment.newInstance(); 
      } 
      return null; 
     } 

     @Override 
     public int getCount() { 
      // Show 3 total pages. 
      return 3; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      switch (position) { 
       case 0: 
        return getText(R.string.received); 
       case 1: 
        return getText(R.string.friends); 
       case 2: 
        return getText(R.string.sent); 
      } 
      return null; 
     } 
    } 

    /** 
    * A placeholder fragment containing a simple view. 
    */ 
    public static class PlaceholderFragment extends Fragment { 
     /** 
     * The fragment argument representing the section number for this 
     * fragment. 
     */ 
     private static final String ARG_SECTION_NUMBER = "section_number"; 

     /** 
     * Returns a new instance of this fragment for the given section 
     * number. 
     */ 
     public static PlaceholderFragment newInstance(int sectionNumber) { 
      PlaceholderFragment fragment = new PlaceholderFragment(); 
      Bundle args = new Bundle(); 
      args.putInt(ARG_SECTION_NUMBER, sectionNumber); 
      fragment.setArguments(args); 
      return fragment; 
     } 

     public PlaceholderFragment() { 
     } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
           Bundle savedInstanceState) { 
      View rootView = inflater.inflate(R.layout.fragment_friends, container, false); 
      TextView textView = (TextView) rootView.findViewById(R.id.section_label); 
      textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER))); 
      return rootView; 
     } 
    } 
} 

编辑:这是我的好友列表中的片段代码:

public class ConnectionsFragment extends Fragment{ 

    public static ConnectionsFragment newInstance() { 
     ConnectionsFragment fragment = new ConnectionsFragment(); 
     return fragment; 
    } 

    public ConnectionsFragment() 
    { 

    } 

    private SwipeMenuListView friendsListView; 
    private ParseUser currentUser; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_connections, container, false); 

     currentUser = ParseUser.getCurrentUser(); 
     friendsListView = (SwipeMenuListView) rootView.findViewById(R.id.friendsList); 


     final ArrayList<SearchResults> searchResults = new ArrayList<SearchResults>(); 
     final ListAdapter listAdapter = new ListAdapter(getActivity(), searchResults); 
     friendsListView.setAdapter(listAdapter); 

     ParseQuery<ParseObject> senderQuery = ParseQuery.getQuery("FriendRequest"); 
     senderQuery.whereEqualTo("sender_id", currentUser.getObjectId()); 
     senderQuery.whereEqualTo("status", "accepted"); 
     ParseQuery<ParseObject> receiverQuery = ParseQuery.getQuery("FriendRequest"); 
     receiverQuery.whereEqualTo("receiver_id", currentUser.getObjectId()); 
     receiverQuery.whereEqualTo("status", "accepted"); 

     List<ParseQuery<ParseObject>> queries = new ArrayList<ParseQuery<ParseObject>>(); 
     queries.add(senderQuery); 
     queries.add(receiverQuery); 

     final ParseQuery<ParseObject> friendsQuery = ParseQuery.or(queries); 

     friendsQuery.findInBackground(new FindCallback<ParseObject>() { 
      @Override 
      public void done(List<ParseObject> objects, ParseException e) { 
       if (e == null) { 
        Log.d("USERS", "Retrieved " + objects.size() + " Users"); 
        if (objects.size() > 0) { 

         for (ParseObject dealsObject : objects) { 
          ParseUser foundUser = null; 
          ParseQuery<ParseUser> query = ParseUser.getQuery(); 
          try { 
           if (dealsObject.get("receiver_id") == currentUser.getObjectId()) 
           { 
            foundUser = query.get(dealsObject.getString("receiver_id")); 
           } 
           else 
           { 
            foundUser = query.get(dealsObject.getString("sender_id")); 
           } 
           Log.i("NAME IN FRIENDSLIST", foundUser.getString("name")); 
          } catch (ParseException err) { 
           Log.e("ERROR", err.getMessage()); 
          } 

          Log.i("NAME", foundUser.getString("name")); 
          final SearchResults sr1 = new SearchResults(); 
          sr1.setName(foundUser.getString("name")); 
          sr1.setSurname1(foundUser.getString("surname1")); 
          sr1.setSurname2(foundUser.getString("surname2")); 
          sr1.setUid(foundUser.getObjectId()); 
          Log.d("UID", foundUser.getObjectId()); 

          sr1.setPhone(foundUser.getString("username")); 
          sr1.setEmail(foundUser.getString("email")); 

          ParseFile fileObject = (ParseFile) foundUser.get("thumbnail"); 
          try { 
           byte[] imageBytes = fileObject.getData(); 
           sr1.setImage(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length)); 
          } catch (ParseException e1) { 
           Log.e("ERROR", e.getMessage()); 
          } 

          searchResults.add(sr1); 
         } 
         listAdapter.notifyDataSetChanged(); 
        } else if (objects.size() == 0) { 
         //Toast.makeText(getActivity(), R.string.no_search_results, Toast.LENGTH_LONG).show(); 
        } else { 
         Log.e("USERS", "Error: " + e.getMessage()); 
        } 
       } 
      } 
     }); 

     friendsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       Object o = friendsListView.getItemAtPosition(position); 
       SearchResults fullObject = (SearchResults) o; 
       Intent i = new Intent(getActivity(), 
         UserDetailActivity.class); 
       i.putExtra("uid", fullObject.getUid()); 
       startActivity(i); 
      } 
     }); 

     return rootView; 
    } 
} 
+0

可能与问题无关,但是您进行后台加载的方式可能导致内存泄漏,因为碎片一旦不再可见就会尝试销毁它们的视图。您可能会在长时间生活的ParseQuery实例中引用它,然后阻止适配器被垃圾收集。 – k0bin

public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a PlaceholderFragment (defined as a static inner class below). 
     switch(position){ 
      case 0 : return ReceivedFragment.newInstance(); 
      case 1 : return ConnectionsFragment.newInstance(); 
      case 2 : return SentFragment.newInstance(); 
     } 
     return null; 

你每次你刷新它们时都会创建每个片段的新实例。我建议在每个片段中使用onResume(),并在其中解析信息以避免不必要的活动创建。

public static class RecievedFragment extends Fragment{ 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){} 

    public void onResume(){ 
     super.onResume(); 
     //Parse Info to this frag here 
    } 
} 

和删除.newInstance()中的getItem()

public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a PlaceholderFragment (defined as a static inner class below). 
     switch(position){ 
      case 0 : return ReceivedFragment; 
      case 1 : return ConnectionsFragment; 
      case 2 : return SentFragment; 
     } 
     return null; 

我怀疑你的问题可能是你如何分析数据,以每个片段。你在使用一个共享变量吗?你可以发布你的代码,显示你在解析中如何处理?

+0

我使用3个片段,每个选项卡一个,以及每个片段(其实只包含一个ListView)的一个布局文件。我将用一个片段更新原始问题(因为三个片段非常相似,只有一部分解析请求发生变化) – iVikD

+0

如果我删除.newInstance(),那么我在哪里调用片段的构造函数? – iVikD

+0

实际上,只有在适配器需要实例化给定的页面片段时,才会调用getItem,以便您可以不断返回新实例,因为每个页面只能调用一次。 PagerAdapter将所有片段保存在内存中并自行处理实例。 – k0bin