2015-11-19 104 views
1

我有一個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

回答

0

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