2014-09-08 5 views
0

Я довольно новичок в Android (3 дня), но у меня довольно хороший фон в PHP (что может быть причиной моей путаницы в среде Java). Я начал создавать Android-приложение с помощью Android Studio (бета-версия). Я создал активность Android Studio по умолчанию с помощью Activity Navigation Drawer. Я редактировал фрагмент активности части, чтобы выглядеть следующим образом:Обновление списка фрагментов из активности

@Override 
public void onNavigationDrawerItemSelected(int position) { 
    Bundle bundle = new Bundle(); 
    bundle.putStringArrayList("contacts", arr); 
    bundle.putStringArrayList("messages", messages); 
    Fragment fragment = null; 
    switch (position) { 
     case 0: 
      fragment = new FriendsFragment(); 
      break; 
     case 1: 
      fragment = new ChatsFragment(); 
      break; 
     case 2: 
      fragment = new GroupsFragment(); 
      break; 
     case 3: 
      fragment = new LogoutFragment(); 
      break; 
     default: 
      break; 
    } 

    if (fragment != null) { 
     fragment.setArguments(bundle); 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     fragmentManager.beginTransaction() 
       .replace(R.id.container, fragment).addToBackStack(null).commit(); 
    } 
} 

Как вы можете видеть, Я передаю Bundle моих фрагментов называемых «сообщениями» и «контактами», когда элемент выбран в панели навигации. Пакет «Сообщения» - это сообщения XMPP, полученные библиотекой aSmack с сервера OpenFire. Так что в основном я пытаюсь создать клиент XMPP. Когда я запускаю приложение, я могу получать сообщения в «ChatsFragment».

Теперь моя проблема: я должен нажать «ChatsFragment» пункт на ящик, чтобы мои сообщения обновляются (повторно получить расслоение) каждый раз я чувствую, что есть новые сообщения, полученные от сервера. Но я хочу, чтобы это было сделано автоматически фрагментом.

Прежде всего я хотел бы знать, если моя процедура является правильной (Activity прослушивает сервер создает пакет, отправить пакет фрагмент, расслоение обновлений сообщений на получении **)

** = Эта часть у меня есть не были в состоянии понять, как реализовать.

1- Если процедура верна, скажите мне, как я должен получать сообщения, которые будут обновляться фрагментом через активность?

2 Если это не правильный способ сделать что-то в Android, рекомендую мне способ сделать это.

Мой код для отображения сообщений в фрагменте:

private void displayListView() { 

    // Messages array list 
    List<String> contacts = getArguments().getStringArrayList("messages"); 
    //System.out.println("arr: " + contacts); 

    //create an ArrayAdaptar from the String Array 
    ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getActivity(), 
      R.layout.url_list, contacts); 
    ListView listView = (ListView) getView().findViewById(R.id.listView); 
    // Assign adapter to ListView 
    listView.setAdapter(dataAdapter); 

    //enables filtering for the contents of the given ListView 
    listView.setTextFilterEnabled(true); 

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View view, 
           int position, long id) { 
      // Send the URL to the host activity 
      //mListener.onURLSelected(((TextView) view).getText().toString()); 

     } 
    }); 

} 

Спасибо заранее.

ответ

1

Обычно для длительных операций в фоновом режиме, таких как прослушивание сервера, входящих сообщений и т. Д., Вам необходимо использовать Службы. Вы делаете это путем подкласса класса Service в Android.

Теперь для вашей проблемы - подход к дизайну должен заключаться в том, что у вас есть фоновое обслуживание, слушая входящие сообщения. В любое время, когда принимается сообщение (входной поток в вашем операторе сокета), вы должны отправить «трансляцию» намерение получить сообщение. Пользовательский широковещательный приемник, который вы создаете, должен ждать этой трансляции. Внутри метода onReceive() этого ресивера вы должны инициировать создание пакета и обновление вашего сообщения.

Помните, что вы всегда должны делегировать свои длительные операции в Android для обслуживания. Это именно то, для чего они предназначены.

+0

После того, как я реализую этот подход к дизайну, и пакет создается при приеме сообщений, как я могу уведомить об этом Фрагмент, чтобы обновить себя, когда фрагмент отображается (активен), а когда нет? –

+1

Ваша трансляция будет приниматься объектом BroadcastReceiver в активности, которая содержит фрагмент. Если ваш фрагмент активен, вы можете напрямую передать объект Bundle. Если это не так, вы можете иметь что-то вроде установленного флага, чтобы фрагмент знал, что его нужно обновить при следующем запуске. – ucsunil

1

Итак, в основном, если вы уже слушаете новые сообщения, входящие в вашу деятельность, тогда у вас должен быть какой-то обратный вызов, например onMessageRecieved() или что-то в этом роде.

Если вы это сделаете, вы можете сообщить об этом фрагменту таким образом. Создать поле (идет под объявлением класса) называется curFrag, так что-то вроде этого:

public class MyActivity extends Activity { 

private Fragment curFrag; 

//other code... 

} 

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

public static final String CHATSTAG = "chatstag"; 

@Override 
public void onNavigationDrawerItemSelected(int position) { 
    Bundle bundle = new Bundle(); 
    bundle.putStringArrayList("contacts", arr); 
    bundle.putStringArrayList("messages", messages); 
    Fragment fragment = null; 
    String tag = null; 
    switch (position) { 
     case 0: 
      tag = FRIENDSTAG; 
      fragment = new FriendsFragment(); 
      break; 
     case 1: 
      tag = CHATSTAG;... and so on through the switch statement. 
      fragment = new ChatsFragment(); 
      break; 
     case 2: 
      fragment = new GroupsFragment(); 
      break; 
     case 3: 
      fragment = new LogoutFragment(); 
      break; 
     default: 
      break; 
    } 



    if (fragment != null) { 
     fragment.setArguments(bundle); 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
//remember to set the tag. 
     if(tag != null) { 
fragmentManager.beginTransaction() 
       .replace(R.id.container, fragment, tag).addToBackStack(null).commit(); 
     } else { 

fragmentManager.beginTransaction() 
       .replace(R.id.container,fragment,DEFAULTTAG).addToBackStack(null).commit(); 
} 
     //new code 
     curFrag = fragment; 
    } 
} 

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

public void onMessageRecieved() { 

if(curFrag.getTag().equalsIgnoreCase(CHATSTAG)) { 

ChatsFragment frag = (ChatsFragment) curFrag; 
frag.notifyDataRecieved(); 
} 
} 

Как только у вас есть ссылка на ваш фрагмент в действии, у вас есть доступ к любым общедоступным методам в этом фрагменте.

Если ваш фрагмент не может получить доступ к данным сам по себе, вам необходимо получить ссылку на активность и создать метод в действии, который возвращает новые данные.

Так что в вашей деятельности:

public String getMessageData() { 

String newData = ...//get stuff from server; 
return newData; 
} 

затем в вашем фрагменте

public void notifyNewMessage() { 
try { 
MyActivity activity = (MyActivity) getActivity(); 
} catch (ClassCastException e) { 
e.printStackTrace(); 
} catch (NullPointerException e) { 
e.printStackTrace(); 
} 

String message = activity.getMessageData(); 
//do something with the message. 
} 

Это не обязательно красивая, но она работает очень хорошо. Вы также должны проверить, чтобы ваши фрагменты были прикреплены, когда вы делаете это, чтобы избежать исключений из null.

Надеюсь, это поможет!

+0

Спасибо за совет, я прочитал его полностью, и я думаю, что это хороший способ сделать это. Мне нужно будет его реализовать и протестировать. Любые идеи о том, когда фрагмент не отображается, и я хочу обновить его с помощью полученных сообщений при его отображении? –

+0

Возможно, вам понадобится ссылка на вашу заднюю часть или как предыдущий фрагмент. Или вы можете что-то сделать в методе onResume() вашего фрагмента, чтобы обновить список сообщений, похожих на то, что я изложил выше. Кроме того, ответ Сунил выше о службах является правильным btw –

Смежные вопросы