java.lang.IllegalStateException: Con được chỉ định đã có cha


99

Tôi đang sử dụng các mảnh vỡ, khi tôi khởi tạo một đoạn ngay lần đầu tiên nó. nhưng lần thứ hai tôi có ngoại lệ này. Tôi không thể tìm thấy dòng mà tôi gặp lỗi?

 04-04 08:51:54.320: E/AndroidRuntime(29713): FATAL EXCEPTION: main
    04-04 08:51:54.320: E/AndroidRuntime(29713): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addViewInner(ViewGroup.java:3013)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addView(ViewGroup.java:2902)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addView(ViewGroup.java:2859)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.view.ViewGroup.addView(ViewGroup.java:2839)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.NoSaveStateFrameLayout.wrap(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.BackStackRecord.run(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.support.v4.app.FragmentManagerImpl$1.run(Unknown Source)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.os.Handler.handleCallback(Handler.java:587)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.os.Handler.dispatchMessage(Handler.java:92)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.os.Looper.loop(Looper.java:132)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at android.app.ActivityThread.main(ActivityThread.java:4126)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at java.lang.reflect.Method.invokeNative(Native Method)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at java.lang.reflect.Method.invoke(Method.java:491)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
    04-04 08:51:54.320: E/AndroidRuntime(29713):    at dalvik.system.NativeStart.main(Native Method)

Đây là những gì tôi làm khi nhấp vào một phần tử trong phân đoạn danh sách của mình.

// If we are not currently showing a fragment for the new
 // position, we need to create and install a new one.
 RouteSearchFragment df = RouteSearchFragment.newInstance(index);

 // Execute a transaction, replacing any existing fragment
 // with this one inside the frame.
 FragmentTransaction ft = fragmentManager.beginTransaction();
 ft.replace(R.id.details_full, df);
 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
 ft.commit();

Lần đầu tiên nó là Ok, tôi nhấp vào element2 từ danh sách, nó cũng ok; nhưng khi tôi quay lại phần tử1, tôi gặp lỗi này.

Cảm ơn mọi người!


cần gọi layoutView.removeAllViews (); trước khi thêm chế độ xem vào bố cục
ρяσѕρєя K

@imrankhan nhầm! Bạn có thể thêm mà không cần xóa tất cả. Phần quan trọng nhất là mất tích và như không có gói tùy chỉnh trong stacktrace, tôi đề nghị bạn loại bỏ một số mã và thử nghiệm nó từng bước ...
WarrenFaith

1
tôi bổ sung thêm chi tiết, vui lòng bạn có thể thấy điều đó?
haythem souissi

Lớp RouteSearchFragment này là gì ?? Không thể tìm thấy bất kỳ tài liệu tham khảo nào trong tài liệu Android. Vui lòng cập nhật định nghĩa lớp quá.
noob

Câu trả lời:


36

Khi bạn ghi đè OnCreateViewtrong RouteSearchFragmentlớp của mình , bạn có

if(view != null) {
    return view; 
}

đoạn mã?

Nếu vậy, việc xóa câu lệnh return sẽ giải quyết được vấn đề của bạn.

Bạn có thể giữ mã và trả lại chế độ xem nếu bạn không muốn tạo lại dữ liệu chế độ xem và phương thức onDestroyView () bạn xóa chế độ xem này khỏi chế độ xem mẹ của nó như sau:

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (view != null) {
            ViewGroup parent = (ViewGroup) view.getParent();
            if (parent != null) {
                parent.removeAllViews();
            }
        }
    }

5
@Override public void onDestroyView () {super.onDestroyView (); ViewGroup parentViewGroup = (ViewGroup) mRoutesSearchViewContainer.getParent (); if (null! = parentViewGroup) {parentViewGroup.removeView (mRoutesSearchViewContainer); }}
haythem souissi

@Medo: Bạn có thể giải thích ngắn gọn về điều này không. Tôi có cùng một lỗi được hiển thị trong logcat. như bạn đã đưa ra gợi ý "loại bỏ câu lệnh trả về sẽ giải quyết được vấn đề của bạn" nhưng chúng ta cần trả về đối tượng View trong phương thức onCreateView (). bạn có thể cung cấp đoạn mã để bạn giải thích. Cảm ơn bạn.
Krishna Prasad,

@Krishna Chỉ cần thổi phồng và trả lại chế độ xem như bình thường. Bạn có thể bỏ qua toàn bộ câu lệnh if.
Medo

65
Đối với tôi, tôi chỉ phải thay thế return inflater.inflate(R.layout.fragment_search, container);bằngreturn inflater.inflate(R.layout.fragment_search, container, false);
Sufian

370

Xin lỗi vì đã đăng một câu hỏi cũ nhưng tôi đã có thể sửa nó bằng một giải pháp hoàn toàn khác. Tôi nhận được ngoại lệ này nhưng tôi đã thay đổi dòng đầu tiên của ghi đè onCreatView của mình từ dòng này:

View result = inflater.inflate(R.layout.customer_layout, container);

... đến đây:

View result = inflater.inflate(R.layout.customer_layout, container, false);

Tôi không biết tại sao nhưng sử dụng ghi đè chấp nhận boolean khi tham số thứ ba đã sửa nó. Tôi nghĩ rằng nó nói với Fragment và / hoặc Activity không sử dụng "vùng chứa" làm cha của Chế độ xem mới được tạo.


53
Đừng tiếc - điều này rất hữu ích với tôi, và rõ ràng là với một số người khác. Cảm ơn!
mã vào

Cảm ơn rất nhiều, tôi tiếp tục lãng quên này và trở lại với câu trả lời này
noloman

@Patrick, Chế độ xem đầu tiên gắn chế độ xem được thổi phồng vào vùng chứa, thêm cờ sai chỉ định bạn không muốn thêm chế độ xem được thổi phồng vào vùng chứa.
Ne0

và tôi tiếp tục quay lại bài đăng này và phát hiện ra rằng đây là CÂU TRẢ LỜI :)
noloman

45

Tôi đã phải đối mặt với vấn đề này nhiều lần. Vui lòng thêm mã sau để giải quyết vấn đề này:

@Override
    public void onDestroyView() {
        super.onDestroyView();
        if (view != null) {
            ViewGroup parentViewGroup = (ViewGroup) view.getParent();
            if (parentViewGroup != null) {
                parentViewGroup.removeAllViews();
            }
        }
    }

Cảm ơn


Cảm ơn bạn về giải pháp này :) Tôi có một trường hợp rất cụ thể mà tôi không thể sử dụng máy thổi phồng để giải quyết vấn đề này. Bạn đã tiết kiệm cho tôi rất nhiều thời gian
Bojan

Tôi xin lỗi, tôi không hiểu lắm vì tôi là người mới sử dụng Android.
Zin Win Htet

Trong view.getParent (); Đối tượng xem liều lượng đến từ đâu?
Zin Win Htet

Cristy YG: Lấy một phiên bản View làm biến toàn cục và thổi phồng xml bố cục của bạn lên trên biến toàn cục. bạn có đang theo dõi tôi hay không?
Hardik

Có, xem khai báo cá thể là toàn cục.
Hardik

35

Nếu bạn có tuyên bố này ..

View view = inflater.inflate(R.layout.fragment1, container);//may be Incorrect 

Sau đó, hãy thử điều này .. Thêm false làm đối số thứ ba .. Có thể nó có thể giúp ..

View view = inflater.inflate(R.layout.fragment1, container, false);//correct one

21

Tôi có mã này trong một phân đoạn và nó đã bị lỗi nếu tôi cố gắng quay lại phân đoạn này

if (mRootView == null) {
    mRootView = inflater.inflate(R.layout.fragment_main, container, false);
} 

sau khi thu thập các câu trả lời trên chủ đề này, tôi nhận ra rằng cha mẹ của mRootView vẫn có mRootView khi còn nhỏ. Vì vậy, đây là bản sửa lỗi của tôi.

if (mRootView == null) {
    mRootView = inflater.inflate(R.layout.fragment_main, container, false);
} else {
    ((ViewGroup) mRootView.getParent()).removeView(mRootView);
}

hi vọng điêu nay co ich


2
+1 đã giúp tôi. Đặc biệt đúng nếu hoạt động của bạn vẫn còn nhưng trình quản lý phân đoạn đang thêm các phân đoạn mới lên trên. khi nó quay trở lại phân đoạn đầu tiên, cần đảm bảo rằng chế độ xem gốc cũ đã bị loại bỏ. Cảm ơn!
Bunde Tweetdee vào

Nó đã giúp tôi rất nhiều. Tôi đã tìm ra giải pháp đó trong 3 ngày. Câu trả lời đơn giản và khá.
Zin Win Htet

Chà! cuối cùng nó đã làm việc cho tôi! dung dịch grat. cảm ơn!
avisper

Tôi không hiểu lý do tại sao "(ViewGroup) mRootView.getParent ()). RemoveView (mRootView);" hoạt động trái ngược với việc gọi trực tiếp "<W AnythingIsParentViewGroupName> .removeView (mRootView)" Nhưng điều này cũng phù hợp với tôi, tôi đang thử nghiệm trên Android 8.0 và 9.0. Cảm ơn nụ ^
Khay

16

Nó cũng xảy ra khi chế độ xem được trả về bởi onCreateView () không phải là chế độ xem bị thổi phồng.

Thí dụ:

View rootView = inflater.inflate(R.layout.my_fragment, container, false);

TextView textView = (TextView) rootView.findViewById(R.id.text_view);
textView.setText("Some text.");

return textView;

Sửa chữa:

return rootView;

Thay vì:

return textView; // or whatever you returned

Cảm ơn! Nó đã giúp đỡ tôi!
Sudheesh Mohan

5

Tôi gặp sự cố này và không thể giải quyết nó bằng mã Java. Vấn đề là với xml của tôi.

Tôi đang cố gắng thêm textView vào vùng chứa, nhưng đã bao bọc textView bên trong LinearLayout.

Đây là tệp xml gốc:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textColor="#fff"
        android:background="?android:attr/activatedBackgroundIndicator"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

</LinearLayout>

Bây giờ với LinearLayout đã bị loại bỏ:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:gravity="center_vertical"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textColor="#fff"
        android:background="?android:attr/activatedBackgroundIndicator"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

Điều này có vẻ không giống với tôi nhưng nó đã thành công và tôi đã không thay đổi mã Java của mình. Tất cả đều có trong xml.


2

Bạn đang thêm a Viewvào a layout, nhưng Chế độ xem đã ở trong một chế độ khác layout. Một Chế độ xem không được ở nhiều nơi.


Tôi đã thêm nhiều chi tiết hơn vào câu hỏi của mình, vui lòng bạn có thể thấy điều đó không?
haythem souissi

1

Giải pháp này có thể giúp:

public class FragmentItem extends Android.Support.V4.App.Fragment
{
    View rootView;
    TextView textView;

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (rootView != null) 
        {
            ViewGroup parent = (ViewGroup)rootView.Parent;
            parent.RemoveView(rootView);
        } else {
            rootView = inflater.Inflate(Resource.Layout.FragmentItem, container, false);
            textView = rootView.FindViewById<TextView>(Resource.Id.textViewDisplay);            
        }
        return rootView;
    }
}

1
Tôi nghĩ rootView sẽ luôn là null vì bạn không khởi tạo nó.
Zin Win Htet

rootView luôn được null
Thinsky

1

Tôi giải quyết nó bằng cách thiết lập attachToRootcủa inflater.inflate()để false.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_overview, container, false);
    return view;
}

0

trong tệp xml của bạn, bạn nên đặt layout_width và layout_height từ wrap_content thành match_parent. nó đã được sửa cho tôi.

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.