【发布时间】:2016-01-21 17:53:22
【问题描述】:
我的活动包含一个带有项目列表的片段。
活动类:
public class CategoryActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subcategory);
setupActionBar();
CategoryFragment fragment = (CategoryFragment) getSupportFragmentManager().findFragmentById(R.id.category_fragment);
fragment.setBrand(mBrand);
}
@Override
public void onDestroy() {
super.onDestroy();
UIUtils.unbindDrawables(findViewById(R.id.RootView));
CategoryFragment fragment = (CategoryFragment) getSupportFragmentManager().findFragmentById(R.id.category_fragment);
if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
System.gc();
}
public static class CategoryFragment extends Fragment {
private ListView mListView;
private CategoryAdapter mAdapter;
private Category mRoot;
private List<Category> mCategories;
private Brand brand;
public CategoryFragment(){}
public void setBrand(Brand brand) {
this.brand = brand;
}
private boolean mIsAnimating;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_category, container, false);
mListView = (ListView) view.findViewById(R.id.list_view);
try {
if (mCategories == null) {
loadCategories(AppController.getInstance().getCategory());
}
if (mCategories != null) {
mAdapter = new CategoryAdapter(getActivity(), mRoot);
mAdapter.setListener(new CategoryAdapter.Listener() {
@Override
public void onCategoryClick(String category) {
if (brand == null) return;
Utils.openQueryView(getActivity(), category, brand);
}
@Override
public void openSubcategory(Category category) {
openSubcategoriesView(category);
}
@Override
public void onBrowseAllClick(Category category) {
if (brand == null) return;
if (category.name.equals(Category.ROOT)) {
Utils.openQueryView(getActivity(), category.name, brand);
} else {
Utils.openStoreActivity(getActivity(), category, brand);
}
}
});
mListView.setAdapter(mAdapter);
}
}catch (Exception e){
LOGD(TAG, e.getMessage());
return view;
}
return view;
}
private void loadCategories(Category root) {
// stuff here... it work well
}
private void openSubcategoriesView(Category category) {
AnalyticsManager.sendScreenView(SCREEN_NAME);
final CategoryFragment fragment = new CategoryFragment();
fragment.setCategories(category);
fragment.setBrand(brand);
if (mIsAnimating) {
return;
}
mIsAnimating = true;
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_in_right, 0, 0,
R.anim.slide_out_right);
transaction.add(R.id.category_fragment, fragment);
transaction.addToBackStack(null);
transaction.commit();
mIsAnimating = false;
List<Fragment> fs = getFragmentManager().getFragments();
for(int i = 0; i< fs.size(); i++){
LOGD(TAG, "fragment[" + i + "]: " + fs.get(i).getActivity());
}
}
public void setCategories(Category category) {
loadCategories(category);
}
}
}
活动布局xml:
<fragment android:id="@+id/the_main_fragment" android:tag="firstFragment" android:name="com.greelane.gapp.ui.CategoryActivity$CategoryFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:background="@drawable/header_shadow" android:layout_width="match_parent" android:layout_height="12dp"></LinearLayout> </RelativeLayout>
每次我点击一个项目时,一个新的 CategoryFragment 将被添加到这个活动的 FragmentManager 中,并且在 xml 布局中具有相同的 Fragment 类(category_fragment id)作为一个孩子如果一个孩子有他的孩子,这个概念会重复。
我尝试登录查看我有多少片段,每次我点击一个项目:
函数openSubcategoriesView
List<Fragment> fs = getFragmentManager().getFragments();
// fs size > 1, but just one instance of CategoryFragment
for(int i = 0; i< fs.size(); i++){
LOGD(TAG, "fragment[" + i + "]: " + fs.get(i).getActivity());
}
导航到活动后我第一次点击一个项目,它只创建一个片段,所以 fs 大小为 1;
然后我点击返回 > 点击另一个项目,我看到 fs 大小是 2,但是我找到了一个 CategoryFragment 的实例。
我不知道它如何处理活动中的片段,但有时我的应用程序在 onCreateActivity setContentView(R.layout.activity_subcategory); 的这一行崩溃;
错误日志:
原因:android.view.InflateException: Binary XML file line #14: Error inflating class fragment
我的 xml 布局中的第 14 行从这里开始
片段 android:id="@+id/category_fragment" ...
所以问题是:
为什么我在多次添加后只有一个 CategoryFragment 实例以及如何解决此问题?
为什么有时我会收到上述充气异常广告以及如何解决此问题?
#Updated1
第二个问题的错误日志,找不到任何异常堆栈跟踪:
01-21 11:16:54.276 16783-16783/? W/System.err: java.lang.RuntimeException: Unable to start activity ComponentInfo{vn.app.alezaa/com.greelane.gapp.ui.CategoryActivity}: android.view.InflateException: Binary XML file line #14: Error inflating class fragment
01-21 11:16:54.279 16783-16783/? W/System.err: Caused by: android.view.InflateException: Binary XML file line #14: Error inflating class fragment
01-21 11:16:54.282 16783-16783/? W/System.err: Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.greelane.gapp.ui.CategoryActivity$CategoryFragment: make sure class name exists, is public, and has an empty constructor that is public
01-21 11:16:54.286 16783-16783/? W/System.err: Caused by: java.lang.InstantiationException: can't instantiate class com.greelane.gapp.ui.CategoryActivity$CategoryFragment; no empty constructor
#Updated2
- 我不能使用
android:name=...CategoryActivity.CategoryFragment代替android:name=...CategoryActivity$CategoryFragment但仍然有同样的错误 - 我第一次发布这个问题时,空的构造函数已经有了。
我已编辑我的代码以添加新的 CategoryFragment,例如:
final CategoryFragment fragment = new CategoryFragment();
fragment.setCategories(category);
fragment.setBrand(brand);
if (mIsAnimating) {
return;
}
mIsAnimating = true;
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction
.setCustomAnimations(R.anim.slide_in_right, 0, 0, R.anim.slide_out_right)
.replace(R.id.container, fragment, category.title)// set tag is title of ctg
.addToBackStack(category.title)
.commit();
mIsAnimating = false;
List<Fragment> fs = getFragmentManager().getFragments();
// `error raised here after two times add CategoryFragment, the **fs** size > 1, but just one instance of it.`
for(int i = 0; i< fs.size(); i++){
LOGD(TAG, "fragment[" + i + "]: " + fs.get(i).getActivity());
}
xml 布局已编辑:
<fragment android:id="@+id/the_main_fragment" android:tag="firstFragment" android:name="com.greelane.gapp.ui.CategoryActivity$CategoryFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:background="@drawable/header_shadow" android:layout_width="match_parent" android:layout_height="12dp"></LinearLayout> </RelativeLayout>
或者我是否需要将 CategoryFragment 分离到其他类并转向非静态,因为现在我无法删除静态。有什么想法吗?
【问题讨论】:
-
2.您应该附加完整的异常堆栈跟踪。那里会提供更多信息。