2016-01-22 26 views
2

我試圖在java中創建的佈局內創建一個地圖(GoogleMap)。我不明白爲什麼我在從LinearLayout獲取ID時遇到與imageView相關的錯誤。如何在java中創建的Layout中創建地圖片段(GoogleMap)?

這裏是我的代碼:

 LinearLayout mapLayout = new LinearLayout(customToursActivity); 
     mapLayout.setId(rootView.generateViewId()); 
     mapLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 0.5f)); 
     layout.addView(mapLayout); 

     FragmentManager fm = getChildFragmentManager(); 
     SupportMapFragment supportMapFragment = SupportMapFragment.newInstance(); 
     fm.beginTransaction().replace(mapLayout.getId(), supportMapFragment).commit(); 

這裏是我得到的日誌:

 
01-22 15:04:28.034 19341-19341/abff.googlemapsappteste E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    Process: abff.googlemapsappteste, PID: 19341 
    java.lang.ClassCastException: android.widget.ImageView cannot be cast to android.view.ViewGroup 
      at android.support.v4.app.BackStackRecord.configureTransitions(BackStackRecord.java:1134) 
      at android.support.v4.app.BackStackRecord.beginTransition(BackStackRecord.java:1041) 
      at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:661) 
      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501) 
      at android.support.v4.app.Fragment.performStart(Fragment.java:1810) 
      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:989) 
      at android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:846) 
      at android.support.v4.app.FragmentManagerImpl.startPendingDeferredFragments(FragmentManager.java:1162) 
      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1518) 
      at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490) 
      at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141) 
      at android.support.v4.view.ViewPager.populate(ViewPager.java:1105) 
      at android.support.v4.view.ViewPager.populate(ViewPager.java:951) 
      at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1473) 
      at android.view.View.measure(View.java:17637) 
      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) 
      at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) 
      at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124) 
      at android.view.View.measure(View.java:17637) 
      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) 
      at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:444) 
      at android.view.View.measure(View.java:17637) 
      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) 
      at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) 
      at android.view.View.measure(View.java:17637) 
      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) 
      at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) 
      at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) 
      at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) 
      at android.view.View.measure(View.java:17637) 
      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) 
      at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) 
      at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2618) 
      at android.view.View.measure(View.java:17637) 
      at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2019) 
      at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1177) 
      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1383) 
      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1065) 
      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5901) 
      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) 
      at android.view.Choreographer.doCallbacks(Choreographer.java:580) 
      at android.view.Choreographer.doFrame(Choreographer.java:550) 
      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) 
      at android.os.Handler.handleCallback(Handler.java:739) 
      at android.os.Handler.dispatchMessage(Handler.java:95) 
      at android.os.Looper.loop(Looper.java:211) 
      at android.app.ActivityThread.main(ActivityThread.java:5389) 
      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:1020) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815) 
+0

我覺得這條線應該從'fm.beginTransaction()來改變替換(mapLayout.getId(),supportMapFragment).commit();''來fm.beginTransaction()代替((。 ViewGroup)mapLayout.getId(),supportMapFragment).commit();'進行正確的投射。 – gerardnimo

+1

我不明白爲什麼'rootView.generateViewId()'正在生成一個已經與另一個對象關聯的ID,所以我用aswer替換了它(http://stackoverflow.com/a/11615356/3140594)工作。 –

回答

0

我有完全相同的問題,但需要不同的修補程序。和你一樣,我有一個自定義的View,它以編程方式創建一個SupportMapFragment。但在我的情況下,這個視圖可能在一個RecyclerView項目內,因此使用您鏈接到的方法(在while循環中使用findViewById查找下一個可用Id的方法)生成一個新的Id將不起作用,因爲視圖得到相同每次都是Id,因爲它在自己的子視圖層次結構中調用findViewById。相同的Id是不好的,因爲當我在自定義視圖中使用片段管理器進行替換時,它每次只替換第一次出現,即第一個RecyclerView項目。

我發現this thread關於谷歌地圖庫中的一個錯誤,它似乎在內部使用一些生成的Ids,這與在View.generateViewId()中生成的第一個可用Ids衝突,這導致我嘗試使用它,問題:

int newViewId = -1; 
int loopCount = 0; 

// I tried starting at 70, actual number used internally in Google maps may be lower 
while (loopCount < 70) { 
    loopCount++; 
    if (ApiLevelHelper.SameOrNewer(17)) { 
     // using https://gist.github.com/omegasoft7/fdf7225a5b2955a1aba8 
     newViewId = ViewHelper.generateViewId(); 
    } else { 
     newViewId = View.generateViewId(); 
    } 
} 

FrameLayout mapFrameLayout = new FrameLayout(getContext()); 
mapFrameLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); 
mapFrameLayout.setId(newViewId); 

FrameLayout pnlMapFragment = (FrameLayout)findViewById(R.id.pnlMapFragment); 
pnlMapFragment.addView(mapFrameLayout); 

((AppCompatActivity) getContext()).getSupportFragmentManager().beginTransaction() 
        .replace(mapFrameLayout.getId(), this.mapFragment) 
        .commit(); 

this.mapFragment.getMapAsync(this);