【问题标题】:How to render UI controls in Xamarin Forms equivalent to Android native controls?如何在 Xamarin Forms 中呈现与 Android 本机控件等效的 UI 控件?
【发布时间】:2019-04-16 01:52:41
【问题描述】:

我计划将 Phunware 地图集成到 Xamarin Forms 应用程序中。我能够创建 Android Binding 项目,因此我可以获得与 Phunware Android 原生 SDK 等效的包。通过这个,我可以访问 Phunware SDK 的所有方法和类。现在的挑战是我必须遵循 Phunware Android 原生示例应用程序源代码,在 Xamarin Forms 中编写等效代码并带上地图。我已经给出了 Android UI xml 和活动文件作为示例。

 <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.phunware.java.sample.LoadBuildingActivity">

        <fragment xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/map"
            android:name="com.phunware.mapping.MapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignTop="@id/map"
            android:background="@color/white"
            android:orientation="vertical"
            android:padding="6dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/switch_floors" />

            <Spinner
                android:id="@+id/floorSpinner"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>

    </RelativeLayout>

    package com.landt.ismartphunware2;

    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.Spinner;

    import com.google.android.gms.maps.CameraUpdate;
    import com.google.android.gms.maps.CameraUpdateFactory;
    import com.phunware.core.PwCoreSession;
    //import com.phunware.java.sample.R;
    import com.phunware.mapping.MapFragment;
    import com.phunware.mapping.OnPhunwareMapReadyCallback;
    import com.phunware.mapping.PhunwareMap;
    import com.phunware.mapping.manager.Callback;
    import com.phunware.mapping.manager.PhunwareMapManager;
    import com.phunware.mapping.model.Building;
    import com.phunware.mapping.model.FloorOptions;

    public class LoadBuildingActivity extends AppCompatActivity implements OnPhunwareMapReadyCallback {
        private static final String TAG = LoadBuildingActivity.class.getSimpleName();
        private PhunwareMapManager mapManager;
        private Building currentBuilding;
        private ArrayAdapter<FloorOptions> spinnerAdapter;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.load_building);

            Spinner floorSpinner = findViewById(R.id.floorSpinner);
            spinnerAdapter = new FloorAdapter(this);
            floorSpinner.setAdapter(spinnerAdapter);
            floorSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    FloorOptions floor = spinnerAdapter.getItem((int) id);
                    if (currentBuilding != null && floor != null) {
                        currentBuilding.selectFloor(floor.getLevel());
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                }
            });

            // Create the map manager used to load the building
            mapManager = PhunwareMapManager.create(this);

            // Register the Phunware API keys
            PwCoreSession.getInstance().registerKeys(this);

            MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
            if (mapFragment != null) {
                mapFragment.getPhunwareMapAsync(this);
            }
        }

        @Override
        public void onPhunwareMapReady(final PhunwareMap phunwareMap) {
            // Retrieve buildingId from integers.xml
            int buildingId = getResources().getInteger(R.integer.buildingId);

            mapManager.setPhunwareMap(phunwareMap);
            mapManager.addBuilding(buildingId,
                    new Callback<Building>() {
                        @Override
                        public void onSuccess(Building building) {
                            Log.d(TAG, "Building loaded successfully");
                            currentBuilding = building;

                            // Populate floor spinner
                            spinnerAdapter.clear();
                            spinnerAdapter.addAll(building.getBuildingOptions().getFloors());

                            // Set building to initial floor value
                            FloorOptions initialFloor = building.initialFloor();
                            building.selectFloor(initialFloor.getLevel());

                            // Animate the camera to the building at an appropriate zoom level
                            CameraUpdate cameraUpdate = CameraUpdateFactory
                                    .newLatLngBounds(initialFloor.getBounds(), 4);
                            phunwareMap.getGoogleMap().animateCamera(cameraUpdate);
                        }

                        @Override
                        public void onFailure(Throwable throwable) {
                            Log.d(TAG, "Error when loading building -- " + throwable.getMessage());
                        }
                    });
        }
    }

在这里,他们将 UI 控件转换为 MapFragment 并调用 getPhunwareMapAsync() 方法。我只想知道在 Xamarin Forms 中我们可以将哪些控件映射到这个 MapFragment?如果我们要在 Xamarin Android 项目的 MainActivity 中编写等效代码,我们如何在 PCL 项目和 Android 项目之间建立连接并将地图带到 View 中?我只是想弄清楚如何开始以及将什么放在哪里,因为我在 Xamarin Forms 方面拥有出色的经验,但在 Android Native 方面的经验较少。

【问题讨论】:

    标签: android xamarin.forms binding


    【解决方案1】:

    建议一:

    你可以试试Xamarin.Forms.Maps:

    Xamarin.Forms.Maps 提供了一种跨平台抽象,用于显示在每个平台上使用本机地图 API 的地图,从而为用户提供快速和熟悉的地图体验。

    建议二:

    自定义 ContentPage 以显示带有地图和其他一些控件的 Android 原生页面:

    ContentPage 是显示单个视图并占据大部分屏幕的可视元素。本文演示了如何为 ContentPage 页面创建自定义渲染器,使开发人员能够使用自己的特定于平台的自定义来覆盖默认的原生渲染。

    【讨论】:

    • 谢谢。我将遵循建议 2
    • PhunwareMapManager.create(this);此方法以 Context 作为参数。我不确定应该如何在 Xamarin Android MainActivity 中完成。你能帮助如何在活动类中获取上下文并传递给这个方法吗?
    • @Ramesh,你可以安装CurrentActivityPlugin,然后,当你需要访问当前活动时,你可以调用CrossCurrentActivity.Current.ActivityContext CurrentContext =&gt; CrossCurrentActivity.Current.Activity
    • 沉,太好了。有用。此外,我还可以在 metadata.xml 中为 Android 绑定类、接口和方法。您能否指导我如何在 metadata.xml 中为泛型类进行绑定,例如上面代码中的 Callback 类。如果我能够绑定这个泛型类,我将能够完成绑定并将地图引入 Xamarin 应用程序。我问你是因为我无法在互联网上和互联网上找到参考/帮助。
    • @Ramesh,您可以创建一个新问题并发布有关它的更多详细信息,我会在那里为您提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    相关资源
    最近更新 更多