2016-07-22 100 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(); 
}