2016-07-22 117 views
0

我有一個包含RecyclerView的片段(SearchResultsFragment)。搜索結果被加載到RecyclerView(這是一系列CardViews)。Android錯誤充氣視圖

當用戶選擇一個CardView,它們被帶到其中從所選擇的卡數據被加載的另一片段(EventDetailsFragment)。所有這些工作正常,我現在唯一的問題是,當用戶選擇手機上的後退按鈕,應用程序崩潰,給我一個錯誤,該XML文件不能被誇大。

我懷疑這可能是一個與我RecyclerView。

E/UncaughtException: android.view.InflateException: Binary XML file line #18: Binary XML file line #18: Error inflating class fragment 

我也收到此錯誤:

Caused by: java.lang.IllegalArgumentException: Binary XML file line #18: Duplicate id 0x7f0f0159, tag null, or parent id 0x7f0f0158 with another fragment for com.google.android.gms.location.places.ui.PlaceAutocompleteFragment 

這裏是我的SearchResultsFragment代碼:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View currentView = inflater.inflate(R.layout.fragment_start_search, container, false); 
    resolvingError = savedInstanceState != null && savedInstanceState.getBoolean(RESOLVING_ERROR, false); 
    initializeComponents(currentView); 
    buildGoogleApi(); 
    handlePermissions(); 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 
     getDeviceSuggestedLocations(); 
    } 
    return currentView; 
} 

private void initializeComponents(final View currentView) { 
    searchResultsRecyclerView = (RecyclerView) currentView.findViewById(R.id.EventSearchResultsRecyclerView); 
    searchResultsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
    autoCompleteFragment = (PlaceAutocompleteFragment) getChildFragmentManager().findFragmentById(R.id.GoogleSearchFragment); 
    autoCompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() { 
     @Override 
     public void onPlaceSelected(Place place) { 
      currentLocation = place.getName().toString(); 
      selectedPlace = place; 
      processSearch(); 
     } 
     @Override 
     public void onError(Status status) { 
      displayMessage("Error Getting Location", status.getStatusMessage()); 
     } 
    }); 

} 

這是一個失敗,按下後退按鈕時,膨脹的XML文件:

<LinearLayout 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="Fragments.StartSearchFragment" 
      android:orientation="vertical" 
      > 
<android.support.v7.widget.CardView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_margin="5dp" 
    > 
    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id ="@+id/SearchLinearLayout" 
     android:orientation="vertical"> 
     <fragment 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:id = "@+id/GoogleSearchFragment" 
      android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"></fragment> 
    </LinearLayout> 
</android.support.v7.widget.CardView> 
    <android.support.v7.widget.RecyclerView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id = "@+id/EventSearchResultsRecyclerView" 
     android:layout_margin="5dp"> 
    </android.support.v7.widget.RecyclerView> 
</LinearLayout> 

編輯:這是片段得到熱插撥活動(MainActivity) - 根據什麼選擇的是:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{ 
private Toolbar mainActivityToolbar; 
private TextView toolbarTextView; 
private ImageView toolbarImage; 
private FragmentManager mgr; 
private NavigationView navigationView; 
private DrawerLayout drawerLayout; 
private ActionBarDrawerToggle drawerToggle; 
private SharedPreferences activityPreferences; 
private SharedPreferences appSharedPreferences; 
private SharedPreferences.Editor editor; 

protected void onCreate(Bundle savedInstanceState) { 
    if (savedInstanceState == null) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     initializeControls(); 
     loadLandingScreenFragment(); 
    } else { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     initializeControls(); 
    } 
} 

public void initializeControls() 
{ 
    mainActivityToolbar = (Toolbar) findViewById(R.id.MainActivityToolbar); 
    toolbarTextView = (TextView) findViewById(R.id.MainActivityTextView); 
    toolbarImage = (ImageView) findViewById(R.id.MainActivityImageView); 
    drawerLayout = (DrawerLayout) findViewById(R.id.menuDrawerLayout); 
    navigationView = (NavigationView) findViewById(R.id.mainActivityNavigationView); 
    setSupportActionBar(mainActivityToolbar); 
    getSupportActionBar().setTitle(null); 
    getSupportActionBar().setHomeButtonEnabled(true); 
    getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true); 
    drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, mainActivityToolbar, R.string 
      .app_name, R 
      .string 
      .app_name); 
    drawerLayout.setDrawerListener(drawerToggle); 
    navigationView.inflateHeaderView(R.layout.navigation_menu_header); 
    navigationView.inflateMenu(R.menu.athlete_navigation_menu); 
    toolbarImage.setOnClickListener(this); 
    appSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 
    activityPreferences = getSharedPreferences("iBaleka", MODE_PRIVATE); 
    editor = activityPreferences.edit(); 
    NavigationMenuOnItemSelectedListener listener = new NavigationMenuOnItemSelectedListener 
      (this); 
    navigationView.setNavigationItemSelectedListener(listener); 
    toolbarImage.setImageResource(R.drawable.ibaleka_logo); 
    mgr = getFragmentManager(); 
    mapComponents(); 

} 
public void loadLandingScreenFragment() 
{ 
    AthleteLandingFragment landingFragment = new AthleteLandingFragment(); 
    FragmentTransaction transaction = mgr.beginTransaction(); 
    transaction.replace(R.id.MainActivityContentArea, landingFragment, "UserStats"); 
    transaction.addToBackStack("UserStats"); 
    transaction.commit(); 
} 

private void mapComponents() 
{ 
    View headerView = navigationView.getHeaderView(0); 
    TextView athleteNameSurname = (TextView) headerView.findViewById(R.id.profileNameSurname); 
    TextView emailAddress = (TextView) headerView.findViewById(R.id.profileEmailAddress); 

    String nameSurname = appSharedPreferences.getString("Name", "") + " "+ appSharedPreferences.getString("Surname", ""); 
    athleteNameSurname.setText(nameSurname); 
    emailAddress.setText(appSharedPreferences.getString("EmailAddress", "").toLowerCase()); 

} 
@Override 
protected void onPause() { 
    editor.putString("ToolbarText", toolbarTextView.getText().toString()); 
    editor.commit(); 
    super.onPause(); 
} 
protected void onResume() { 
    super.onResume(); 
    toolbarTextView.setText(activityPreferences.getString("ToolbarText", "")); 
} 
@Override 
public void onBackPressed() { 
    if (mgr.getBackStackEntryCount() > 0) { 
     mgr.popBackStack(); 
    } else { 
     super.onBackPressed(); 
    } 

} 
+0

問題是你如何加載片段;你看,你在另一個片段中有一個片段 - 你需要看看如何從父片段中膨脹一個子片段 – Eenvincible

+0

你能顯示你的活動代碼(或任何組件持有片段)嗎?我懷疑你試圖添加一個片段兩次,一次是在活動的第一次開始,一次是在你回到活動時。如果以編程方式添加任何片段,則需要檢查片段管理器中是否存在片段。 –

+0

您的活動的郵政編碼。看來,android:id =「@ + id/GoogleSearchFragment」被添加了兩次。一旦在xml中,另一次在代碼中。 – Rafal

回答

0

參照這個線程在計算器上:Binary XML file line #26: Duplicate id, tag null, or parent id with another fragment

原來,我的問題是,我在一個片段佈局中有一個標籤。這顯然是不可能的 - 解決方案是將標籤更改爲LinearLayout標籤,並使用FragmentManager將PlaceAutocompleteFragment加載到LinearLayout中。

新XML(與片斷標籤改變):

<LinearLayout 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="Fragments.StartSearchFragment" 
      android:orientation="vertical" 
    > 
<android.support.v7.widget.CardView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_margin="5dp" 
    > 
    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id ="@+id/SearchLinearLayout" 
     android:orientation="vertical"> 
     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:id = "@+id/GoogleSearchFragment" 
      android:orientation="vertical"> 
     </LinearLayout> 
    </LinearLayout> 
</android.support.v7.widget.CardView> 
    <android.support.v7.widget.RecyclerView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id = "@+id/EventSearchResultsRecyclerView" 
     android:layout_margin="5dp"> 
    </android.support.v7.widget.RecyclerView> 
</LinearLayout> 

接下來,使用FragmentManager加載PlacesAutocompleteFragment:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View currentView = inflater.inflate(R.layout.fragment_start_search, container, false); 

    initializeComponents(currentView, savedInstanceState); 
    resolvingError = savedInstanceState != null && savedInstanceState.getBoolean(RESOLVING_ERROR, false); 
    buildGoogleApi(); 
    handlePermissions(); 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 
     getDeviceSuggestedLocations(); 
    } 
    return currentView; 
} 

private void initializeComponents(View currentView, Bundle savedInstanceState) { 
    searchResultsRecyclerView = (RecyclerView) currentView.findViewById(R.id.EventSearchResultsRecyclerView); 
    searchResultsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
    autoCompleteFragment = new PlaceAutocompleteFragment(); 
    autoCompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() { 
      @Override 
      public void onPlaceSelected(Place place) { 
       currentLocation = place.getName().toString(); 
       selectedPlace = place; 
       processSearch(); 
      } 
      @Override 
      public void onError(Status status) { 
       displayMessage("Error Getting Location", status.getStatusMessage()); 
      } 
     }); 
    FragmentManager mgr = getFragmentManager(); 
    FragmentTransaction transaction = mgr.beginTransaction(); 
    transaction.replace(R.id.GoogleSearchFragment, autoCompleteFragment, "AutoSearchFragment"); 
    transaction.commit(); 
} 

然後,重寫onDestroyView方法:

@Override 
public void onDestroyView() { 
    super.onDestroyView(); 
    FragmentManager manager = getActivity().getFragmentManager(); 
    Fragment fragment = manager.findFragmentById(R.id.GoogleSearchFragment); 
    FragmentTransaction trans = manager.beginTransaction(); 
    trans.remove(fragment); 
    trans.commit(); 
}