我有一个包含RecyclerView的Fragment(SearchResultsFragment)。搜索结果被加载到RecyclerView(这是一系列CardViews)。
当用户选择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 :(得分:0)
在StackOverflow上引用此线程: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();
}