2017-01-05 7 views
0

Я нашел несколько вопросов об этом, ни один из которых не помог мне. Каждый вопрос относится к другим функциям и представлениям, которые я не реализую в своих фрагментах, и проблема заключается не в том, что мне нужно поменять мой метод на получение FragmentManager на getChildFragmentManager() где-нибудь в моих фрагментах, потому что мне не нужно получать Там есть FragmentManager.Фрагментные адаптеры FragmentTabHost пустые после возврата на вкладку, фрагмент/просмотры остаются

Я предполагаю, что моя проблема связана с фрагментами, а не с FragmentTabHost в основном действии, но я не уверен. Вообще. Все, что я знаю, это то, что при переходе между вкладками содержимое адаптера исчезает, но не сам фрагмент. Все представления все еще функционируют, поэтому функциональность каждого фрагмента остается неповрежденной.

Эта проблема возникла только после того, как я добавил слушателя изменений табуляции для того, чтобы инициализировать адаптер для моего фрагмента чата.

Обратите внимание, что содержимое вкладок в порядке их первоначальной инициализации, но когда вы вернетесь на вкладку, содержимое в адаптерах пусто. Это означает, что вкладка, которая еще не инициализирована при создании FragmentTabHost, скрытые вкладки еще не инициализированы, поэтому они будут работать при первом запуске страницы.

С помощью отладки я вижу, что эта проблема возникает, когда происходит переход, и все адаптеры остаются пустыми в течение всего сеанса использования. Я поставил этот Snippit кода до первоначальной проверки в моем tabHost.setOnTabChangedListener вызова:

//Before paging back to an initialized tab for the first time, the adapters of the initialized tab is populated. 
Log.d("test", "pre"); 
new Handler().postDelayed(new Runnable() { 
    @Override 
    public void run() { 
     //At this point, the adapter is empty. 
     Log.d("test", "post"); 
    } 
}, 50); 

двух фрагментов следующим образом:

public class GroupTasksFragment extends Fragment { 

public ArrayAdapter<String> adapter; 
private Context context; 
public ListView taskListView; 

public GroupTasksFragment() { 
    // Required empty public constructor 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View rootView = inflater.inflate(R.layout.fragment_group_tasks, container, false); 
    taskListView = (ListView) rootView.findViewById(R.id.tasksList); 
    adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, new ArrayList<String>()); 
    taskListView.setAdapter(adapter); 
    return rootView; 
} 

@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    this.context = context; 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
} 
} 

public class GroupChatFragment extends Fragment{ 

public ArrayAdapter<String> adapter; 
private Context context; 
public ListView chatListView; 

public GroupChatFragment() { 
    // Required empty public constructor 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View rootView = inflater.inflate(R.layout.fragment_group_chat, container, false); 
    chatListView = (ListView) rootView.findViewById(R.id.chatList); 
    adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, new ArrayList<String>()); 
    chatListView.setAdapter(adapter); 
    return rootView; 
} 

@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    this.context = context; 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
} 
} 

Основная деятельность с FragmentTabHost (я исключенные методы, просто взять ввод и передачу контента в PubNub):

public class GroupContentActivity extends AppCompatActivity { 

private GroupChatFragment chatFrag; 
private GroupTasksFragment taskFrag; 
private FragmentTabHost tabHost; 
private PubNub connection; 
private String groupName; 
private String nickName; 
private boolean chatFragInitialized = false; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_group_content); 
    tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); 
    tabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent); 

    tabHost.addTab(tabHost.newTabSpec("tasks").setIndicator("Tasks"), 
      GroupTasksFragment.class, null); 

    tabHost.addTab(tabHost.newTabSpec("chat") 
      .setIndicator("Chat"), GroupChatFragment.class, null); 

    groupName = getIntent().getStringExtra("groupName"); 
    nickName = getIntent().getStringExtra("nickName"); 
    PNConfiguration config = new PNConfiguration(); 
    config.setPublishKey(Constants.publishKey); 
    config.setSubscribeKey(Constants.subscribeKey); 
    connection = new PubNub(config); 



    tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() { 
     @Override 
     public void onTabChanged(String tabId) { 
      if (!chatFragInitialized && tabId.equals("chat")) { 
       chatFragInitialized = true; 
       new Handler().postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         chatFrag = (GroupChatFragment) getSupportFragmentManager().findFragmentByTag("chat"); 
         connection.history() 
           .channel(groupName) 
           .count(50) 
           .async(new PNCallback<PNHistoryResult>() { 
            @Override 
            public void onResponse(PNHistoryResult result, PNStatus status) { 
             for (PNHistoryItemResult item : result.getMessages()) { 
              final String[] sForm = item.getEntry().getAsString().split(">>>>"); 
              String m = ""; 
              if (sForm.length > 2) { 
               for (int x = 1; x < sForm.length; x++) { 
                m += sForm[x]; 
               } 
              } else { 
               m = sForm[1]; 
              } 

              final String mCopy = m; 

              runOnUiThread(new Runnable() { 
               @Override 
               public void run() { 
                switch (sForm[0]) { 
                 case "groupCreated": 
                  chatFrag.adapter.clear(); 
                  break; 
                 case "chat": 
                  chatFrag.adapter.add(mCopy); 
                } 
               } 
              }); 

             } 
            } 
           }); 
        } 
       }, 50); 
      } 
     } 
    }); 

    new Handler().postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      taskFrag = (GroupTasksFragment) getSupportFragmentManager().findFragmentByTag("tasks"); 

      connection.history() 
        .channel(groupName) 
        .count(50) 
        .async(new PNCallback<PNHistoryResult>() { 
         @Override 
         public void onResponse(PNHistoryResult result, PNStatus status) { 
          for (PNHistoryItemResult item : result.getMessages()) { 
           final String[] sForm = item.getEntry().getAsString().split(">>>>"); 
           String m = ""; 
           if (sForm.length > 2) { 
            for (int x = 1; x < sForm.length; x++) { 
             m += sForm[x]; 
            } 
           } else { 
            m = sForm[1]; 
           } 

           final String mCopy = m; 

           runOnUiThread(new Runnable() { 
            @Override 
            public void run() { 
             switch (sForm[0]) { 
              case "addTask": 
               if (taskFrag.adapter.getPosition(mCopy) < 0) { 
                taskFrag.adapter.add(mCopy); 
               } 
               break; 
              case "deleteTask": 
               if (taskFrag.adapter.getPosition(mCopy) >= 0) { 
                taskFrag.adapter.remove(mCopy); 
               } 
               break; 
              case "groupCreated": 
               taskFrag.adapter.clear(); 
               break; 
             } 
            } 
           }); 

          } 
         } 
        }); 

      connection.addListener(new SubscribeCallback() { 
       @Override 
       public void status(PubNub pubnub, PNStatus status) { 
        if (status.getCategory() == PNStatusCategory.PNUnexpectedDisconnectCategory) { 
         Toast.makeText(getApplicationContext(), "You were disconnected!", Toast.LENGTH_SHORT).show(); 
        } else if (status.getCategory() == PNStatusCategory.PNConnectedCategory) { 
         if (status.getCategory() == PNStatusCategory.PNConnectedCategory) { 
          pubnub.publish().channel(groupName).message("chat>>>><ADMIN> User '" + nickName + "' Connected").async(new PNCallback<PNPublishResult>() { 
           @Override 
           public void onResponse(PNPublishResult result, PNStatus status) { 
           } 
          }); 
         } 
        } else if (status.getCategory() == PNStatusCategory.PNReconnectedCategory) { 
         Toast.makeText(getApplicationContext(), "You were reconnected!", Toast.LENGTH_SHORT).show(); 
        } 
       } 

       @Override 
       public void message(PubNub pubnub, PNMessageResult message) { 
        final String[] sForm = message.getMessage().getAsString().split(">>>>"); 
        String m = ""; 
        if (sForm.length > 2) { 
         for (int x = 1; x < sForm.length; x++) { 
          m += sForm[x]; 
         } 
        } else { 
         m = sForm[1]; 
        } 

        final String mCopy = m; 

        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          switch (sForm[0]) { 
           case "chat": 
            if (chatFragInitialized) { 
             chatFrag.adapter.add(mCopy); 
             runOnUiThread(new Runnable() { 
              @Override 
              public void run() { 
               chatFrag.chatListView.setSelection(chatFrag.adapter.getCount() - 1); 
              } 
             }); 
            } 
            break; 
           case "addTask": 
            taskFrag.adapter.add(mCopy); 
            connection.publish().channel(groupName).message("chat>>>><ADMIN> Task '" + mCopy + "' added.").async(new PNCallback<PNPublishResult>() { 
             @Override 
             public void onResponse(PNPublishResult pnPublishResult, PNStatus pnStatus) { 
             } 
            }); 
            break; 
           case "deleteTask": 
            taskFrag.adapter.remove(mCopy); 
            connection.publish().channel(groupName).message("chat>>>><ADMIN> Task '" + mCopy + "' deleted.").async(new PNCallback<PNPublishResult>() { 
             @Override 
             public void onResponse(PNPublishResult pnPublishResult, PNStatus pnStatus) { 
             } 
            }); 
            break; 
          } 
         } 
        }); 
       } 

       @Override 
       public void presence(PubNub pubnub, PNPresenceEventResult presence) { 
       } 
      }); 
      connection.subscribe().channels(java.util.Collections.singletonList(groupName)).execute(); 
     } 
    }, 100); 
} 

@Override 
public void onDestroy(){ 
    super.onDestroy(); 
    connection.publish().channel(groupName).message("chat>>>><ADMIN> User '" + nickName + "' Logged Out.").async(new PNCallback<PNPublishResult>() { 
     @Override 
     public void onResponse(PNPublishResult pnPublishResult, PNStatus pnStatus) { 
     } 
    }); 
    connection.disconnect(); 
    Toast.makeText(getApplicationContext(), "Logged out", Toast.LENGTH_SHORT).show(); 
} 

//More Methods 
} 

также обратите внимание, что этот вопрос не то, что мне нужно хранить экземпляр FragmentManager, так как это не Делать что-нибудь.

ответ

0

Я нашел свою проблему. Оказывается, каждый раз, когда фрагмент выгружается в FragmentTabHost, метод createView вызывается снова и только этот метод, поэтому, устанавливая адаптер в фрагменте для пустого в этом представлении, который, как я думал, был только в начале, Я каждый раз меняю адаптер.

Я исправил это, сохранив содержимое адаптера в качестве объекта списка переменных экземпляра, который я добавляю или удаляю строки в/из, когда я хочу изменить адаптер. НЕ ТАКЖЕ НАПРАВЛЯЙТЕ СТРОКИ В АДАПТЕРЕ, обновление списка достаточно. Список добавит его прямо к адаптеру.

Также обратите внимание, что если вы установите начальное содержимое вне фрагмента, оно может не отображаться, когда вкладки сначала инициализируются. Просто будьте осторожны с заказом вашего заявления и когда все будет вызвано. Фрагментное строительство - фанк-бизнес.

Затем я устанавливаю адаптер на все, что есть в списке, каждый раз, когда вызывается метод createView.