【问题标题】:Updating android fragment inside an event在事件中更新 android 片段
【发布时间】:2016-05-24 14:51:45
【问题描述】:

我正在做一个基于信标的室内定位应用程序。在我的应用程序中,我在 ViewPager 中加载了 3 个选项卡。第二个选项卡是一个地图片段,它应该根据信标信号显示用户所在位置的地图。

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);
  }
}

此代码段仅在创建活动时一次加载所有选项卡。现在我需要的是仅在收到信标信号时才加载的第二个片段(mtcf,“MAP”)。

@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>`

我该如何实现呢?只有在收到蓝牙信标事件后,我才需要加载地图片段。

谢谢。

【问题讨论】:

    标签: android android-fragments bluetooth ibeacon ibeacon-android


    【解决方案1】:

    你必须通过你的TabPagerAdapter来处理它:

    1、在TabPagerAdapter中,添加一个参数,如:List&lt;Fragment&gt; mItems,首先在mItems中添加两个片段。

    像这样覆盖TabPagerAdaptergetItem 函数:

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

    2、当要显示MapFragment时,只需通过TabPagerAdapteraddItem函数,那么mItems就有了三个片段。您可以手动对片段进行排序。

    当您使用addItem 时,别忘了致电notifyDataSetChanged()。 希望能帮到你!

    【讨论】:

    • 过去两天一直在错误的方向搜索。再次感谢。
    • 还有一个问题。是否可以用旧片段替换新片段?我尝试过这样的事情。 mFragmentList.set(1,newFragment);但它没有得到更新。我也调用了 notifyDataSetChanged() 函数。有什么原因吗?
    • 是的,当您的适配器扩展 FragmentPagerAdapter 时,notifyDataSetChanged() 总是不起作用。您应该覆盖getItemPosition,并返回POSITION_NONE。您可以参考:this
    【解决方案2】:

    您需要在 "OnEvent" 中调用 notifyDataSetChanged 并实现 Viewpager 中的 getItemPosition(Object map)。

    这将在您每次调用 notifyDatasetChanged 时更新地图页面 Update Fragment from ViewPager

    【讨论】:

    • 将问题标记为已回答。
    • 您好,我选择了上面的最佳答案,因为他在您之前回答了同样的问题。感谢您的帮助。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    相关资源
    最近更新 更多