ghanan2000 ghanan2000 - 6 months ago 22
Android Question

Updating android fragment inside an event

I am doing an indoor localization app which is based on beacons. In my application, I have loaded 3 tabs in a ViewPager. The 2nd tab is a Map fragment which should display the map of the location the user is in based on the beacon signal.

public class Shop extends AppCompatActivity implements IndoorsLocationListener, ProximityManager.ProximityListener {

private static final String TAG = Shop.class.getSimpleName();

private IndoorsSurfaceFragment indoorsFragment;

private ProximityManagerContract proximityManager;
private ScanContext scanContext;

TabPagerAdapter adapter;
ViewPager viewPager;


// TODO : Add more event types like devices updated
private List<EventType> eventTypes = new ArrayList<EventType>() {{
// add(EventType.DEVICES_UPDATE);
add(EventType.DEVICE_DISCOVERED);
}};

private IBeaconScanContext beaconScanContext = new IBeaconScanContext.Builder()
.setEventTypes(eventTypes) //only specified events we be called on callback
.setRssiCalculator(RssiCalculators.newLimitedMeanRssiCalculator(5))
.build();

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

proximityManager = new KontaktProximityManager(this);

setContentView(R.layout.activity_shop);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setTitle("Shopping");

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();


viewPager = (ViewPager) findViewById(R.id.tab_content);

MapTabContentFragment mtcf = new MapTabContentFragment();
adapter = new TabPagerAdapter(getSupportFragmentManager());

IndoorsFactory.Builder indoorsBuilder = new IndoorsFactory.Builder();
IndoorsSurfaceFactory.Builder surfaceBuilder = new IndoorsSurfaceFactory.Builder();
indoorsBuilder.setContext(this);

// Set the API Key for Indoo.rs
indoorsBuilder.setApiKey(getResources().getString(R.string.indoors_api_key));

// Set the building's ID
indoorsBuilder.setBuildingId((long)762751544);
// Log.d(TAG+ " Building ID: ", Long.toString(pBuildingID));

// callback for indoo.rs-events
indoorsBuilder.setUserInteractionListener(this);
surfaceBuilder.setIndoorsBuilder(indoorsBuilder);
indoorsFragment = surfaceBuilder.build();

adapter.addFragment(new ListTabContentFragment(), "LIST");
adapter.addFragment(indoorsFragment, "MAP");
adapter.addFragment(new ARTabContentFragment(), "AR");

viewPager.setAdapter(adapter);


This code segment just loads all the tabs at once when the activity is created. Now what I need is the 2nd fragment (mtcf, "MAP") to load only when the beacons signal is received.

`@Override
public void onEvent(BluetoothDeviceEvent bluetoothDeviceEvent) {
List<? extends RemoteBluetoothDevice> deviceList = bluetoothDeviceEvent.getDeviceList();
long timestamp = bluetoothDeviceEvent.getTimestamp();
DeviceProfile deviceProfile = bluetoothDeviceEvent.getDeviceProfile();
switch (bluetoothDeviceEvent.getEventType()) {
case SPACE_ENTERED:
Log.d(TAG, "namespace or region entered");
break;
case DEVICE_DISCOVERED:
Log.d(TAG, "found new beacon");
Log.d(TAG, ((Integer.toString(deviceList.size()))));

String nameOfBeacon = deviceList.get(0).getName();

if(nameOfBeacon.equals("Entrance")) {
long buildingMapID = lookupBuilding(deviceList.get(0).getName());
IndoorsSurfaceFragment indoorsSurfaceFragment = createIndoorFragment(buildingMapID);

getSupportFragmentManager().beginTransaction().replace(R.id.indoorslayout,indoorsSurfaceFragment).commit();
}
break;


MapFragment.xml

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<FrameLayout
android:id="@+id/indoorslayout"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>

</android.support.v4.widget.NestedScrollView>`


How can I implement this?? I need the map fragment to load only after the Bluetooth beacon event is received.

Thanks.

Answer

You must handle it by your TabPagerAdapter:

1, In TabPagerAdapter, add a param, like : List<Fragment> mItems, first you add two fragments into mItems.

override TabPagerAdaptergetItem function like this:

 public Fragment getItem(int position){
     return mItems.get(position);
}

2, When you want to show MapFragment, just by TabPagerAdapter addItem function, then mItems have three fragments. You can manually sort fragments.

When you use addItem, don't forget to call notifyDataSetChanged(). Hope to help you!

Comments