[解決済み] com.google.android.gms.maps.MapFragment の ID、タグ null、または親 ID が別のフラグメントと重複しています。
質問
3つのタブを持つアプリケーションを持っています。
各タブは独自のレイアウト.xmlファイルを持っています。main.xml は独自のマップフラグメントを持っています。これは、アプリケーションが最初に起動したときに表示されるものです。
タブを切り替えたときを除いて、すべてうまくいきます。マップフラグメントのタブに戻ろうとすると、このエラーが発生します。他のタブに切り替えたり、他のタブの間を移動するのは問題なく動作します。
何が問題なのでしょうか?
これは私のメインクラスとmain.xml、そして私が使用している関連クラスです(一番下にエラーログもあります)。
メインクラス
package com.nfc.demo;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.widget.Toast;
public class NFCDemoActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.addTab(bar
.newTab()
.setText("Map")
.setTabListener(
new TabListener<MapFragment>(this, "map",
MapFragment.class)));
bar.addTab(bar
.newTab()
.setText("Settings")
.setTabListener(
new TabListener<SettingsFragment>(this, "settings",
SettingsFragment.class)));
bar.addTab(bar
.newTab()
.setText("About")
.setTabListener(
new TabListener<AboutFragment>(this, "about",
AboutFragment.class)));
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
// setContentView(R.layout.main);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}
public static class TabListener<T extends Fragment> implements
ActionBar.TabListener {
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private Fragment mFragment;
public TabListener(Activity activity, String tag, Class<T> clz) {
this(activity, tag, clz, null);
}
public TabListener(Activity activity, String tag, Class<T> clz,
Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
// Check to see if we already have a fragment for this tab,
// probably from a previously saved state. If so, deactivate
// it, because our initial state is that a tab isn't shown.
mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
FragmentTransaction ft = mActivity.getFragmentManager()
.beginTransaction();
ft.detach(mFragment);
ft.commit();
}
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(),
mArgs);
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(mFragment);
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
ft.detach(mFragment);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
Toast.makeText(mActivity, "Reselected!", Toast.LENGTH_SHORT)
.show();
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapFragment"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
関連するクラス ( MapFragment.java )
package com.nfc.demo;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MapFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.main, container, false);
}
public void onDestroy() {
super.onDestroy();
}
}
エラー
android.view.InflateException: Binary XML file line #7:
Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at com.nfc.demo.MapFragment.onCreateView(MapFragment.java:15)
at android.app.Fragment.performCreateView(Fragment.java:1695)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
at android.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1255)
at android.app.BackStackRecord.run(BackStackRecord.java:672)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException:
Binary XML file line #7: Duplicate id 0x7f040005, tag null, or
parent id 0xffffffff with another fragment for
com.google.android.gms.maps.MapFragment
at android.app.Activity.onCreateView(Activity.java:4722)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
... 19 more
解決方法は?
Mattが提案する答えは有効ですが、マップを再作成して再描画することになり、常に望ましいとは言えません。 多くの試行錯誤の末、私は自分にとって有効な解決策を見つけました。
private static View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.map, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
}
return view;
}
念のため、R.id.mapFragment (android:id"@+id/mapFragment") を含む "map.xml" (R.layout.map) を以下に示します。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</LinearLayout>
お役に立てれば幸いですが、悪影響がないことを保証するものではありません。
編集する
アプリケーションを終了して再度起動した場合など、いくつか弊害がありました。アプリケーションは必ずしも完全にシャットダウンしているわけではないので(バックグラウンドでスリープしているだけ)、私が以前提出したコードは、アプリケーションの再起動時に失敗してしまうのです。私はこのコードを、マップに入ったり出たり、アプリケーションを終了して再起動したりするときに動作するものに更新しました。
さらに編集。 結局、try-catchが必要なことがわかりました。マップフラグメントをチェックするだけでは、結局うまくいかないことがわかった。残念。
関連
-
java.lang.NullPointerException: NULLオブジェクト参照で仮想メソッド......を呼び出そうとしました。
-
[解決済み] Android Fragment no view found for ID?
-
IllegalStateException。ArrayAdapter は、リソース ID が TextView である必要があります。
-
アプリケーションがメインスレッドで過剰に作業している可能性があります。
-
GoogleMapと連携し、位置情報の取得が可能
-
Windowsのadbシェルでデータディレクトリにアクセスするとパーミッションが拒否される
-
ConstraintLayoutのいくつかのプロパティの概要(RelativeLayoutの強化版、LinearLayoutの比例プロパティを含む、階層ツールの削減)。
-
Android Bluetooth 開発の基本プロセス
-
[解決済み] 新しいAndroid Fragmentをインスタンス化するためのベストプラクティス
-
[解決済み】フラグメントの上に別のフラグメントが重なる問題
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
cygwinのダウンロード、インストールチュートリアル、およびCDTの「makeプログラムがパスに見つからない」バグの解消
-
ArrayAdapter は、リソース ID が TextView であることが必要です。
-
Google PlayデバイスはPlay保護機構の認証を受けていません。
-
アンドロイドスタジオのエラーを解決する --> Error:(1, 0) id 'com.android.application' を持つプラグインが見つかりません。
-
Androidで、onTouchEventでダブルクリックを実装し、ダブルクリックイベントとして判定する方法
-
Android TextViewにandroid:ellipsize=endのバグがある。
-
WeChatとQQは、他のアプリのオープンリストに自分のアプリを追加し、ファイルパスを取得することができます
-
view.getRootView()の本当の意味とテストについて
-
アンドロイドリストビュー
-
Android Studio常见错误之:Rendering Problems/The following classes could not be instantiated