Mapbox在片段上的膨胀视图

时间:2016-01-07 22:54:28

标签: java android xml android-fragments mapbox

我遇到了在Android片段上夸大Mapbox MapView的问题。当我在Activity上使用相同的代码时(除了Activity和Fragment之间的标准差异),我可以正确加载MapView,但不能在Fragment上加载。

Mapbox也有一个MapFragment类here,但我不确定如何在Fragment中正确使用它(该示例仍然在Activity中);使用Google Maps API,我可以在片段上使用MapView而不会出现问题。

以下logcat行:

at com.example.exampleapp.FragmentMap.onCreateView(FragmentMap.java:133)

指的是Java行:

fragmentLayout = inflater.inflate(R.layout.fragment_map, container, false);

以下是此问题的相关代码以及日志:

fragment_map.xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mapbox="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <com.mapbox.mapboxsdk.views.MapView
        android:id="@+id/mapview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        mapbox:access_token="@string/access_token"/>

    <android.support.v7.widget.CardView
        android:id="@+id/map_card"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="5dp">
        <com.mapbox.mapboxsdk.views.MapView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:id="@+id/mini_map"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            mapbox:access_token="@string/access_token"/>
    </android.support.v7.widget.CardView>

FragmentMap.java:

public class FragmentMap extends Fragment {
    private MapView mv, miniMap;
        View fragmentLayout;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        fragmentLayout = inflater.inflate(R.layout.fragment_map, container, false);

    mv = (MapView) fragmentLayout.findViewById(R.id.mapview);
    mv.onCreate(savedInstanceState);

    miniMap = (MapView) fragmentLayout.findViewById(R.id.mini_map);
    miniMap.onCreate(savedInstanceState);

    return fragmentLayout;
}


@Override
public void onStart() {
    super.onStart();
    mv.onStart();
    miniMap.onStart();
}
@Override
public void onStop() {
    super.onStop();
    mv.onStop();
    miniMap.onStop();
}


@Override
public void onDestroy() {
    super.onDestroy();
    mv.onDestroy();
    miniMap.onDestroy();
}

@Override
public void onResume() {
    super.onResume();
    mv.onResume();
    miniMap.onResume();
}

@Override
public void onPause() {
    super.onPause();
    mv.onPause();
    miniMap.onPause();
}
@Override
public void onLowMemory() {
    super.onLowMemory();
    mv.onLowMemory();
    miniMap.onLowMemory();
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mv.onSaveInstanceState(outState);
    miniMap.onSaveInstanceState(outState);
}

logcat的:

01-07 08:07:00.548 710-710/com.example.exampleapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.exampleapp, PID: 710
android.view.InflateException: Binary XML file line #13: Error inflating class com.mapbox.mapboxsdk.views.MapView
at android.view.LayoutInflater.createView(LayoutInflater.java:633)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at com.example.exampleapp.FragmentMap.onCreateView(FragmentMap.java:133)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:552)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:514)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:495)
at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.onTabSelected(TabLayout.java:1778)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:871)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:841)
at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1115)
at android.support.design.widget.TabLayout$1.onClick(TabLayout.java:665)
at android.view.View.performClick(View.java:4785)
at android.view.View$PerformClick.run(View.java:19884)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:607)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at com.example.exampleapp.FragmentMap.onCreateView(FragmentMap.java:133)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:552)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:514)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:495)
at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.onTabSelected(TabLayout.java:1778)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:871)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:841)
at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1115)
at android.support.design.widget.TabLayout$1.onClick(TabLayout.java:665)
at android.view.View.performClick(View.java:4785)
at android.view.View$PerformClick.run(View.java:19884)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
Caused by: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.exampleapp-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libmapbox-gl.so"
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:988)
at com.mapbox.mapboxsdk.views.NativeMapView.<clinit>(NativeMapView.java:42)
at com.mapbox.mapboxsdk.views.MapView.initialize(MapView.java:680)
at com.mapbox.mapboxsdk.views.MapView.<init>(MapView.java:621)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
at android.view.LayoutInflater.createView(LayoutInflater.java:607)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at com.example.exampleapp.FragmentMap.onCreateView(FragmentMap.java:133)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:552)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:514)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:495)
at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.onTabSelected(TabLayout.java:1778)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:871)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:841)
at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1115)
at android.support.design.widget.TabLayout$1.onClick(TabLayout.java:665)
at android.view.View.performClick(View.java:4785)
at android.view.View$PerformClick.run(View.java:19884)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

app gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
    }
}

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

repositories {
    mavenCentral()
    jcenter()
}

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.example.exampleapp"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
    }
    useLibrary 'org.apache.http.legacy'

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:cardview-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
    compile 'com.google.android.exoplayer:exoplayer:r1.5.2'
    compile 'com.google.android.gms:play-services-auth:8.3.0'
    compile 'com.google.android.gms:play-services-maps:8.3.0'
    compile('com.mapbox.mapboxsdk:mapbox-android-sdk:2.3.0@aar') {
        transitive = true
    }
    compile files('libs/commons-lang3-3.3.2.jar')
}

项目结构:

enter image description here

2 个答案:

答案 0 :(得分:2)

你讲的是通货膨胀,但请看堆栈跟踪:

  

引起:java.lang.UnsatisfiedLinkError:   dalvik.system.PathClassLoader [DexPathList [[zip文件   #&34; /data/app/com.example.exampleapp-2/base.apk"],nativeLibraryDirectories = [/供应商/ lib中,   / system / lib]]] 无法找到&#34; libmapbox-gl.so&#34; at   java.lang.Runtime.loadLibrary(Runtime.java:366)at   java.lang.System.loadLibrary(System.java:988)at   com.mapbox.mapboxsdk.views.NativeMapView。(NativeMapView.java:42)   在com.mapbox.mapboxsdk.views.MapView.initialize(MapView.java:680)at   com.mapbox.mapboxsdk.views.MapView。(MapView.java:621)

顺便说一句:

首先

你需要决定你是否每次{local variable}或者你重用它(全局变量)来扩展视图

示例:

if(_view==null) 
   _view = inflater.inflate(..);
return _view;

第二

不要手动调用onCreate onPause等活动或片段方法(os用于维护生命周期的方法)

第三

如果您使用viewpager和嵌套片段,则需要使用子片段管理器创建适配器

更多&amp;更多:

请记住,在子片段中设置一些数据和属性viewpager片段需要布局

  

&#34;首先:我每次都在膨胀,这通常不是问题(我的标签可以与我创建的任何其他片段一起使用,包括谷歌地图,而不是Mapbox)第二:是的,你手动调用活动生命周期方法。您必须使用onCreate来扩展视图。第三:我有一个适配器,我只是没有在这里包含它。这不是问题,我的标签可以与我创建的任何其他片段一起使用。最后:我不确定你在说什么,但我的其他标签中的我的片段工作正常。

     

请关注手头的问题......将Mapbox视图放入片段中,&gt;无论该片段在哪里(标签页面浏览器与否).. - TangoJLabs&#34;

/**
 * Called to do initial creation of a fragment.  This is called after
 * {@link #onAttach(Activity)} and before
 * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
 *
 * <p>Note that this can be called while the fragment's activity is
 * still in the process of being created.  As such, you can not rely
 * on things like the activity's content view hierarchy being initialized
 * at this point.  If you want to do work once the activity itself is
 * created, see {@link #onActivityCreated(Bundle)}.
 *
 * @param savedInstanceState If the fragment is being re-created from
 * a previous saved state, this is the state.
 */
public void onCreate(@Nullable Bundle savedInstanceState) {
    mCalled = true;
}

将此片段的onCreate移至onViewCreated(View,Bundle)

mv = (MapView) fragmentLayout.findViewById(R.id.mapview);
mv.onCreate(savedInstanceState);

miniMap = (MapView) fragmentLayout.findViewById(R.id.mini_map);
miniMap.onCreate(savedInstanceState);


/**
 * Called immediately after {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
 * has returned, but before any saved state has been restored in to the view.
 * This gives subclasses a chance to initialize themselves once
 * they know their view hierarchy has been completely created.  The fragment's
 * view hierarchy is not however attached to its parent at this point.
 * @param view The View returned by {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
 * @param savedInstanceState If non-null, this fragment is being re-constructed
 * from a previous saved state as given here.
 */
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
}

最后一句话:gradle文件

我不知道你的文件内容是包含gradle文件还是仅包含app文件,但这些行不应该在app gradle文件中 - 这些是顶级gradle:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
    }
}

repositories {
    mavenCentral()
    jcenter()
}

你应该考虑转移到最新的Android应用程序插件 - 但我看到你正在使用gms服务 - 所以你的顶级gradle文件包含其他插件,上面的内容被省略

  

我无法遵循您编辑的逻辑。我没有onCreate,我可以从中移动任何东西

/** inflate fragment  - this will create view */
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_map, container, false);
}

/** after view is created - set map view */
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    if(view!=null) {
       MapView mv = (MapView) view.findViewById(R.id.mapview);
       mv.onCreate(savedInstanceState);
    }
}

顺便说一下,我对其余生命周期方法有更多关注 - 片段是否可以保留状态这么简单的片段方法中的活动生命周期方法会产生更多问题:)

我没有使用&amp;知道MapView的源代码实现,所以我不能告诉你如何实现这个但是我可以给你一个提示,在你调用任何mapview方法之前检查片段是否附加到activity

  

@ ceph3us -1这里提到的一切都是错的,你的语法   可以改进。我没有答案,我在这里   同样的问题。第一个根视图不应该是一个字段,它应该是   每次调用onCreateView时都会膨胀,第二次是正确的调用,第三次调用   其余的都是主题,对主题没有帮助。 - 海登凯

@HaydenKai

  1. 首先请求为您审议 SOURCES
  2. 为什么你想重新创建视图?目的?浪费资源(比如你的代码和用户CPU和MEM的时间)? - 在那里你可以负担得起或需要一个新的,然后它可以,但在其他情况下 REUSE
  3. 视图根本不需要膨胀,它通常可以通过返回新的LinearLayout(Context)或FrameLayout或任何其他复杂视图来创建 - 这是开发人员选择使用xml或java - 我不喜欢使用xml - 我喜欢纯JAVA :)
  4. 所以在最后我可以说你的-1对我来说是空的
  5. enter image description here

答案 1 :(得分:1)

这个库看起来处于繁重的开发状态,并且可能存在一些问题,这些问题在GitHub上提到,尤其是在运行2.2.0版时。

尝试将版本更改为最新版本:

compile 'com.mapbox.mapboxsdk:mapbox-android-sdk:3.0.0'