নির্দিষ্ট সন্তানের ইতিমধ্যে একটি পিতামাতা রয়েছে। আপনাকে অবশ্যই প্রথমে সন্তানের পিতামাতার কাছে অপসারণ ভিউ () কল করতে হবে


164

আমাকে প্রায়শই দুটি বিন্যাসের মধ্যে স্যুইচ করতে হয়। ত্রুটিটি নীচে পোস্ট করা লেআউটে ঘটছে।

যখন আমার লেআউটটিকে প্রথমবার বলা হয় তখন কোনও ত্রুটি ঘটে না এবং সবকিছু ঠিক থাকে। তারপরে আমি যখন কোনও ভিন্ন লেআউট (একটি ফাঁকা একটি) কল করি এবং তারপরে আমার লেআউটটিকে দ্বিতীয়বার কল করি, এটি নিম্নলিখিত ত্রুটিটি ছুঁড়ে ফেলে:

> FATAL EXCEPTION: main
>     java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

আমার লেআউট-কোডটি দেখতে এমন দেখাচ্ছে:

    tv = new TextView(getApplicationContext()); // are initialized somewhere else
    et = new EditText(getApplicationContext()); // in the code


private void ConsoleWindow(){
        runOnUiThread(new Runnable(){

     @Override
     public void run(){

        // MY LAYOUT:
        setContentView(R.layout.activity_console);
        // LINEAR LAYOUT
        LinearLayout layout=new LinearLayout(getApplicationContext());
        layout.setOrientation(LinearLayout.VERTICAL);
        setContentView(layout);

        // TEXTVIEW
        layout.addView(tv); //  <==========  ERROR IN THIS LINE DURING 2ND RUN
        // EDITTEXT
        et.setHint("Enter Command");
        layout.addView(et);
        }
    }
}

আমি জানি এই প্রশ্নটি আগে জিজ্ঞাসা করা হয়েছিল, তবে এটি আমার ক্ষেত্রে সহায়তা করে নি।


1
যিনি একই ত্রুটি পান কেবল তার জন্য: আপনি সঠিক উপাদান যুক্ত করেছেন তা নিশ্চিত করুন। বলে যোগ আছে দেয় LinearLayoutকিন্তু আপনি যোগ TextView। সুতরাং এটি ঠিক করুন।
বিকাশকারী

অ্যান্ড্রয়েড ডেটাবাইন্ডিং ব্যবহার করার সময় আইডি 'রুট' দিয়ে ভিউ ঘোষণা করা উচিত নয়, এটি একই ত্রুটি ঘটায়।
মোহাম্মদ রেজা খাহানী

যারা ব্যবহার করছেন তাদের জন্য TranstitionManager.beginDelayedTransitionদয়া করে আমার উত্তরটি এখানে দেখুন
মোচাদ্বী

উত্তর:


354

ত্রুটি বার্তাটি আপনাকে যা করা উচিত তা বলে।

// TEXTVIEW
if(tv.getParent() != null) {
    ((ViewGroup)tv.getParent()).removeView(tv); // <- fix
}
layout.addView(tv); //  <==========  ERROR IN THIS LINE DURING 2ND RUN
// EDITTEXT

56

কেবল সংযুক্তিযুক্ত যুক্তিটিকে মিথ্যা হিসাবে পাস করুন

View view = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, false);

2
আমার জন্য, এটি একটি বুলসিয়ে ছিল। একটি রিসাইকেলভিউতে আইটেমগুলির জন্য সীমাবদ্ধ বিন্যাস, রানটাইমের ভিত্তিতে গতিশীল প্রতিবন্ধকতা পরিবর্তন করে। কনস্ট্রেইটসেট.অ্যাপ্লি কাজ না করে, এটি না হওয়া পর্যন্ত। সুতরাং, অনক্রেটভিউহোল্ডারটিতে পিতামাতার প্রচার করুন, তবে উত্সাহিত করতে অ্যাডিশনাল পরম হিসাবে মিথ্যা প্রেরণ করুন।
মিরোস্লাভাইন

3
এটাই সঠিক সমাধান! @ স্নিপার যেমন বলেছিলেন, দ্বিতীয় প্যারামের কাছে নাল পাস করার ফলে সন্তানের দৃষ্টিভঙ্গিটি তার পিতামাতার সাথে যেমন নিজেকে সামঞ্জস্য না করে তখন তা হতে পারে। OTOH পিতামাতাকে পাস করা প্রশ্নে ত্রুটির কারণ হতে পারে। সুতরাং, attachToRoot= মিথ্যা, যাওয়ার উপায়।
ভ্যাসিলিস

এটি করার সঠিক উপায়।
রোল্যান্ড মাতেতেজি

50

আমি আমার পুনর্ব্যবহারযোগ্য সাথে ত্রুটিটি অনুসন্ধান করতে এখানে এসেছি তবে সমাধানটি কার্যকর হয়নি (স্পষ্টতই)। পুনর্ব্যবহারযোগ্য ক্ষেত্রে আমি এর কারণ ও সমাধান লিখেছি। আশা করি এটি কাউকে সাহায্য করবে।

onCreateViewHolder()নিম্নলিখিত পদ্ধতিতে অনুসরণ করা হলে ত্রুটি ঘটে:

layoutInflater = LayoutInflater.from(context);
return new VH(layoutInflater.inflate(R.layout.single_row, parent));

পরিবর্তে এটি করা উচিত

return new VH(layoutInflater.inflate(R.layout.single_row, null));

15
কখনও কখনও এলোমেলো উত্তর যা জিজ্ঞাসিত প্রশ্নের উত্তর হ'ল অন্য কাউকে সহায়তা করে। এটি আমার পক্ষে কাজ করেছে। ধন্যবাদ!
আজিত মেমনা

1
ভাল !, এবং সে কারণেই লোকেরা প্রায়শই "নাল" inflaters মধ্যে 2 ডি পরামিতি হিসাবে পাস করা উচিত। ধন্যবাদ।
ব্যবহারকারী 18

4
পিতামাতার জন্য দায়ী প্যারামিটারে নাল পাস করা খারাপ ধারণা নয়, তবে আপনাকে জানতে হবে যে এই ক্ষেত্রে সন্তানের দৃষ্টিভঙ্গি (যেটি আপনি ফুটিয়ে তুলেছেন) এটি কিছু ক্ষেত্রে এটি সঠিকভাবে নিজেই পরিমাপ করতে সক্ষম হবে না কারণ এটি তা করে না পিতা বা মাতা সম্পর্কে কিছু জানেন। কিছু ক্ষেত্রে এটি কাজ করবে তবে কিছু ক্ষেত্রে তা হবে না।
স্টয়েচো আন্দ্রিভ 16

1
নোট করুন যে এর ফলে দর্শকদের থিমটি সঠিকভাবে সমাধান করা যায় না।
স্পেসবিসন

13

মিথ্যের পরিবর্তে মূলের সাথে সংযুক্তিকে ব্যবহার করে কোনও খণ্ডের প্রতিশ্রুতি দেওয়ার সময় আমি এই বার্তাটি পেয়েছি :

return inflater.inflate(R.layout.fragment_profile, container, true)

করার পরে:

return inflater.inflate(R.layout.fragment_profile, container, false)

এটা কাজ করেছে.


5

যদি অন্য সমাধানগুলি কাজ করে না:

View view = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, false);

আপনি খন্ডের অনক্রিটভিউ থেকে কী ফিরে আসছেন তা পরীক্ষা করুন এটি একক দর্শন বা ভিউগ্রুপ? আমার ক্ষেত্রে এক্সএমএল টুকরাটির মূলের উপরে আমার ভিউপিজার ছিল এবং আমি ভিউপ্যাজারটি ফিরছিলাম, যখন আমি বিন্যাসে ভিউগ্রুপ যুক্ত করেছি তখন আপডেট করা হয়নি যে আমাকে এখন ভিউগ্রুপটি ফিরিয়ে দিতে হবে, ভিউপ্যাজার (ভিউ) নয়।


5

frameLayout.addView (bannerAdView); <----- যদি আপনি এই লাইনে ত্রুটি পান তবে নীচের মতো করুন ..

if (bannerAdView.getParent() != null)

  ((ViewGroup) bannerAdView.getParent()).removeView(bannerAdView);

   frameLayout.addView(bannerAdView);     <------ now added view

4

আমার ত্রুটিটি ভিউটিকে এভাবে সংজ্ঞায়িত করা হয়েছিল:

view = inflater.inflate(R.layout.qr_fragment, container);

এটি অনুপস্থিত ছিল:

view = inflater.inflate(R.layout.qr_fragment, container, false);

3

আমার ক্ষেত্রে সমস্যাটি <merge>লেআউটটির সাহায্যে প্যারেন্ট ভিউকে বাড়িয়ে দিচ্ছিল by এই ক্ষেত্রে, addView()ক্র্যাশ ঘটায়।

View to_add = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, true);
// parent_layout.addView(to_add); // THIS CAUSED THE CRASH

অপসারণ addView()সমস্যার সমাধান করতে সহায়তা করেছে।



2

নীচের কোডটি আমার জন্য এটি সমাধান করেছে:

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

দ্রষ্টব্য: ত্রুটিটি আমার খণ্ড খণ্ড শ্রেণীর ছিল এবং এটির মতো অনড্রেস্ট্রয় পদ্ধতি ওভাররাইড করে আমি এটি সমাধান করতে পারি।



2

আমার ক্ষেত্রে এটি ঘটে যখন আমি পিতামাতার দ্বারা অন্য দর্শনে ভিউ যুক্ত করতে চাই

View root = inflater.inflate(R.layout.single, null);
LinearLayout lyt = root.findViewById(R.id.lytRoot);
lytAll.addView(lyt);  // ->  crash

আপনার অবশ্যই এটির মতো পিতামাতার ভিউ যুক্ত করতে হবে

View root = inflater.inflate(R.layout.single, null);
LinearLayout lyt = root.findViewById(R.id.lytRoot);
lytAll.addView(root);

2

আপনার অবশ্যই প্রথমে সন্তানের দৃষ্টিভঙ্গিটিকে তার পিতামাতার থেকে অপসারণ করতে হবে।

যদি আপনার প্রকল্পটি কোটলিনে থাকে তবে আপনার সমাধান জাভা থেকে কিছুটা আলাদা দেখবে। কোটলিন এর সাথে কাস্টিংকে সহজতর করে as?, বাম দিকটি শূন্য হয় বা কাস্ট ব্যর্থ হলে নাল ফিরে।

(childView.parent as? ViewGroup)?.removeView(childView)
newParent.addView(childView)

কোটলিন এক্সটেনশন সলিউশন

আপনার যদি একাধিকবার এটি করার প্রয়োজন হয় তবে আপনার কোডটি আরও পঠনযোগ্য করে তুলতে এই এক্সটেনশনটি যুক্ত করুন।

childView.removeSelf()

fun View?.removeSelf() {
    this ?: return
    val parentView = parent as? ViewGroup ?: return
    parentView.removeView(this)
}

এই ভিউটি শূন্য হলে, পিতামাতার দৃষ্টিভঙ্গি নালুক, বা পিতামাতার ভিউটি ভিউগ্রুপ না হলে এটি নিরাপদে কিছু করবে না


1

আমি অন্য একটি সমাধান পেয়েছি:

if (mView.getParent() == null) {
                    myDialog = new Dialog(MainActivity.this);
                    myDialog.setContentView(mView);
                    createAlgorithmDialog();
                } else {
                    createAlgorithmDialog();
                }

এখানে আমার কাছে কেবলমাত্র একটি আইপি স্টেটমেন্ট চেক আছে যাতে ভিউটির পিতা-মাতা ছিল এবং যদি এটি নতুন ডায়ালগ তৈরি করে না, কনটেন্টভিউ সেট করে এবং আমার "ক্রিয়েট অ্যালগোরিদম ডায়ালগ ()" পদ্ধতিতে ডায়লগটি দেখায়।

এটি অনক্লিকলিস্টনারগুলির সাহায্যে ইতিবাচক এবং নেতিবাচক বোতামগুলি (ঠিক আছে এবং বাতিল বোতামগুলি) সেট করে।


0

কোনও ভিউয়ের বাচ্চা আছে কি না তা পরীক্ষা করতে আপনি এই মেথোডটি ব্যবহার করতে পারেন।

public static boolean hasChildren(ViewGroup viewGroup) {
    return viewGroup.getChildCount() > 0;
 }

0

আমার কেসটি ইতিমধ্যে পিতামাতার ভিউর চেয়ে পৃথক ছিল সন্তানের দৃশ্যের মধ্যে আমি পিতা-মাতার ভিউয়ের মধ্যে সন্তানের দৃশ্যটি বিভিন্ন পিতামাতার সাথে যুক্ত করছি। নীচে উদাহরণ কোড

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/lineGap"
>
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@color/black1"
    android:layout_gravity="center"
    android:gravity="center"
    />

</LinearLayout>

এবং আমি এই দৃষ্টিভঙ্গিটি ফুটিয়ে তুলছিলাম এবং অন্য লিনিয়ারলআউটে যুক্ত করছি, তারপরে আমি উপরের লেআউটটি থেকে লিনারআলআউটটিকে সরিয়ে দিয়ে এর কাজ শুরু করলাম

নীচে কোডটি সমস্যার সমাধান করেছে:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:gravity="center"
   android:textColor="@color/black1" />

0

আমার সমস্যা অন্যান্য উত্তরগুলির সাথে সম্পর্কিত, তবে পরিবর্তনটি করার প্রয়োজনের জন্য কিছুটা আলাদা কারণ ... আমি ক্রিয়াকলাপটিকে একটি খণ্ডে রূপান্তর করার চেষ্টা করছিলাম। সুতরাং আমি স্ফীত কোডটি অনক্রিট থেকে অনক্রিটভিউতে স্থানান্তরিত করেছি, তবে আমি সেটকন্টেন্টভিউ থেকে স্ফীত পদ্ধতিতে রূপান্তর করতে ভুলে গিয়েছি এবং একই অবৈধ স্টেটএক্সেপশন আমাকে এই পৃষ্ঠায় নিয়ে এসেছিল।

আমি এটি পরিবর্তন করেছি:

binding = DataBindingUtil.setContentView(requireActivity(), R.layout.my_fragment)

এটি:

binding = DataBindingUtil.inflate(inflater, R.layout.my_fragment, container, false)

যে সমস্যার সমাধান।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.