#android #android-fragments #android-3.0-honeycomb
#Android #android-фрагменты #android-3.0-honeycomb
Вопрос:
Я впервые работаю над 3.0. Я хочу добавлять фрагменты динамически, но отображается ошибка:-
10-18 18:29:11.215: ERROR/AndroidRuntime(3550): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
XML-код
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@ id/frags">
<ListView
android:id="@ id/number_list"
android:layout_width="250dip"
android:layout_height="match_parent" />
<FrameLayout
android:id="@ id/the_frag"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Активность
public class FragmentExampleActivity extends Activity implements
OnItemClickListener {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView l = (ListView) findViewById(R.id.number_list);
ArrayAdapter<String> numbers = new ArrayAdapter<String>(
getApplicationContext(), android.R.layout.simple_list_item_1,
new String[] { "one", "two", "three", "four", "five", "six" });
l.setAdapter(numbers);
l.setOnItemClickListener(this);
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Fragment f = new FragmentExample();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.the_frag, f);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
}
}
public class FragmentExample extends Fragment {
private int nAndroids=1;
public FragmentExample() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saved) {
int n;
View l = inflater.inflate(R.layout.textlay,container);
TextView tv = (TextView) l.findViewById(R.id.textView1);
tv.setText("value " nAndroids);
return l;
}
}
Пожалуйста, проясните, где я ошибаюсь:(
Ответ №1:
Вместо использования
View l = inflater.inflate(R.layout.textlay,container);
вы должны использовать
View l = inflater.inflate(R.layout.textlay, container, false);
или альтернативно
View l = inflater.inflate(R.layout.textlay, null );
Я настоятельно рекомендую вам использовать версию inflate
, которая принимает три параметра. Android использует контейнер только для целей параметров макета. Передача false
в качестве третьего параметра предотвращает добавление textlay
, к container
и устраняет вашу проблему
Комментарии:
1. Контейнер следует использовать только для параметров макета. Не во время инфляции.
2. Из всех вопросов с одинаковыми ошибками это решение помогло. Сообщение об ошибке бесполезно, imo. Большое спасибо!
Ответ №2:
если в onCreateView () вы хотите повторно использовать view , то вы можете справиться с onDestroyView()
@Override
public void onDestroyView() {
super.onDestroyView();
if (view != null) {
ViewGroup parentViewGroup = (ViewGroup) view.getParent();
if (parentViewGroup != null) {
parentViewGroup.removeAllViews();
}
}
}
Ответ №3:
или вы можете использовать третий аргумент и передать его как false.
inflater.inflate(R.layout.sample_fragment, container,false);
это означает, что не привязывайте текущее представление к root.
Ответ №4:
Следующее решает множество проблем:
public static View contentView;
public static class MenuCardFrontFragment extends Fragment {
public MenuCardFrontFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
try
{
LinearLayout frontLayout = (LinearLayout)inflater.inflate(R.layout.content_card, container, false);
// modify layout if necessary
return contentView = frontLayout;
} catch (InflateException e) {
return contentView;
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (contentView != null) {
ViewGroup parentViewGroup = (ViewGroup) contentView.getParent();
if (parentViewGroup != null) {
parentViewGroup.removeAllViews();
}
}
}
}
-
Если фрагменты отображаются с анимацией, и пользователь вынужден повторить анимацию до ее завершения. пример: дважды нажмите кнопку меню, прежде чем фрагмент меню завершит анимацию и появится. (это было решено с помощью onDestryView от пользователя 2764384)
-
Если метод inflate вызывается с указанием контейнера, чтобы получить компоновку контейнера. похоже, что это проблема, потому что во 2-й раз, когда это произошло, у старого контейнера уже есть представление. поэтому, если это исключение произойдет, оно будет перехвачено и вернет старое представление contentView.