2014-01-03 2 views
0

Я пишу приложение, использующее bluetooth-соединение для чтения некоторых данных из COM-порта через Bluetooth. Я использую ViewPager для отображения нескольких фрагментов, которые я использую для отображения некоторых данных (каждый фрагмент по-другому). Приложение имеет 2 вида деятельности:Инициализация и обновление фрагментов в ViewPager

  1. MainActivity - инициализация соединения Bluetooth и управление ими упоминалось фрагменты
  2. Activity, используемые для поиска устройств Bluetooth

Когда MainActivity начинается, он активирует Bluetooth в случае, если это выкл и отображает первый фрагмент. Я могу сканировать устройства, нажав кнопку на панели действий.

Моя проблема довольно проста: я хотел бы подтолкнуть некоторые исходные данные (о соединении) к фрагментам после инициализации MainActivity, а после создания BT-соединения я хочу нажать некоторые данные (около 10 раз/сек) только к видимому фрагменту.

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

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

класс Mainactivity:

@Override 
protected void onStart() { 
    super.onStart(); 

    if (!bluetoothAdapter.isEnabled()) { 
     Intent enableBluetoothIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
     startActivityForResult(enableBluetoothIntent, REQUEST_ENABLE_BLUETOOTH); 
    } else { 
     if (btService == null) { 
      btService = new BluetoothConnectionService(this, msgHandler); 
     } 
    } 
} 

private final Handler msgHandler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
     Intent intent = new Intent(STATUS_EVENT); 
     switch (msg.what) { 
      case MESSAGE_STATE_CHANGE: 
       switch (msg.arg1) { 
        case BluetoothConnectionService.STATE_CONNECTED: 
         intent.putExtra("status", "Connected"); 
         // tell fragments about the state change 
         break; 
        case BluetoothConnectionService.STATE_CONNECTING: 
         intent.putExtra("status", "Connecting"); 
         // tell fragments about the state change 
         break; 
        case BluetoothConnectionService.STATE_NONE: 
         intent.putExtra("status", "Not connected"); 
         // tell fragments about the state change 
         break; 
        default: 
         intent.putExtra("status","Unknown state"); 
         break; 
       }     
     LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent); 
     } 
    } 
}; 

BTService часть:

public void setCurrentConnectionState(int currentConnectionState) { 
    this.currentConnectionState = currentConnectionState; 

    msgHandler.obtainMessage(MainActivity.MESSAGE_STATE_CHANGE, currentConnectionState, -1).sendToTarget(); 
} 

public BluetoothConnectionService(Context context, Handler handler){ 
    this.context = context; 
    this.msgHandler = handler; 
    setCurrentConnectionState(STATE_NONE); 
} 

Один из фрагментов:

public class ConnectionStatusFragment extends Fragment { 

TextView connectionStatus; 

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

    View rootView = inflater.inflate(R.layout.fragment_connection_info, container, false); 
    connectionStatus = (TextView) rootView.findViewById(R.id.connectionStatus); 
    LocalBroadcastManager.getInstance(getActivity()).registerReceiver(broadcastReceiver, new IntentFilter(MainActivity.STATUS_EVENT)); 
    return rootView; 
} 

private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) {   
     connectionStatus.setText(intent.getStringExtra("status")); 
    } 

}; 

}

+0

Что мешает вам добавить функцию к Фрагмент и передача данных через параметры функции? – BVB

+0

Это на самом деле довольно сложный вопрос, потому что вы спрашиваете, что является лучшим способом поговорить с фрагментом. Я бы порекомендовал проверить библиотеку otto squareup. Ваши фрагменты могут стать позиционируемыми, добавив свою позицию в пакет и фрагмент.setArguments (bundle) в ViewPager.getView(). Затем вы можете опубликовать событие с информацией и информацией, которую вы хотите обновить. Другое предложение - установить тег на фрагмент. Таким образом, вы можете найти его из FragmentManager (FragmentSupportManager) и посмотреть, является ли он нулевым или нет, а затем обновлять данные. – MinceMan

+0

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

ответ

0

Пересмотрите свой дизайн вместе MVC линий и применить его в droid для Data-Model, которая сотрудничает с моделями MVC с адаптерами/представлениями, используемыми фрагментами. Адаптеры внутри ваших фрагментов подключены к событиям с изменением данных, которые исходят из модели ...

В фоновом режиме, вне пользовательского интерфейса и ортогонально к вашим фрагментам, установите соединения и обновите модель данных. Не нужно передавать информацию о соединениях BT с вашими фрагментами. Зачем нарушать разделение проблем? Его модель, которая должна знать о соединениях BT, а не ваш взгляд!

Все подключения и ввод-вывод для обновления вашей модели данных инкапсулированы в действия/процессы МОДЕЛИ. Ваш вид не должен знать ничего, кроме «измененной модели данных». Все, что должен иметь ваш фрагмент, - это событие (с изменением данных), чтобы он мог активировать «А-измененный» для вашего адаптера, который затем позаботится об обновлении пользовательского интерфейса в соответствующем фрагменте.

Применяя это практически к андроиду/фрагментам и немного угадывая о вашем дизайне, я думаю, что разработчики для ваших фрагментов могут использовать интерфейс, который позволяет вам создавать View/Fragment независимо от состояния вашей реальной модели данных ,Во время создания экземпляра фрагмент и его адаптер не знают все о состоянии данных, поступающих в BT-соединение в другом модуле. Фрагмент просто должен использовать интерфейс для размещения события «с измененной моделью».

Я думаю, вы можете использовать «петлитель» и обработчик для этого сотрудничества вокруг события. Это может означать, что модели потребуется ссылка на объект обработчика в классе View/fragment. Этот обработчик предназначен для сообщений, содержащих изменения состояния от модели. не

модуль координации ступенчато:

  1. конструкт фрагмент/View - объект существует, просматривать скрытые, никакие данные

1.a. построить обработчик в фрагменте, создав ссылку на объект-приемник для сообщений на петлере

2.a. Построить модель, включая ссылку на обработчик выше.

2.b. Сделайте вещи BT и IO в модели. Когда «изменена модель», получите сообщение, содержимое которого сигнализирует о том, что ваше мнение должно знать о «измененной модели».

2.c. Отправьте сообщение, которое будет получено обработчиком в слое/фрагменте представления (см. 1.a.).

Пример:

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

+0

Это действительно полезный ответ. Я пытался с самого начала реализовать правильный путь MVC, но я не мог придумать правильный способ следовать. Тем временем мне удалось решить мои проблемы, используя шину событий и регистрацию/отмена регистрации моих фрагментов. Я знаю, что это не самое лучшее решение, но сейчас я должен придерживаться его, поскольку появились другие проблемы. Я уверен, что вернусь к вашему сообщению через некоторое время, когда буду пытаться переделать часть приложения с помощью фрагментов. Большое спасибо. – Berben

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