আমি কেন খণ্ডে অ-ডিফল্ট নির্মাণকারীদের এড়াতে চাই?


173

আমি Fragmentsতাদের সাথে একটি অ্যাপ তৈরি করছি এবং এর মধ্যে একটি আমি একটি ডিফল্ট নির্মাতা তৈরি করেছি এবং এই সতর্কতা পেয়েছি:

Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead

কেউ আমাকে বলতে পারেন কেন এটি ভাল ধারণা নয়?

আমি কীভাবে এটি সম্পাদন করব তাও আপনি পরামর্শ দিতে পারেন:

public static class MenuFragment extends ListFragment {
    public ListView listView1;
    Categories category;

    //this is my "non-default" constructor
    public MenuFragment(Categories category){
        this.category = category;
    }....

ডিফল্ট কনস্ট্রাক্টর ব্যবহার না করে?



3
না, তারা সাহায্য করে না। তারা আমার প্রশ্নের উত্তর দেয় নি। তবে আপনাকে কম ধন্যবাদ :)
ব্ল্যাকহ্যাটসামুরাই

31
@BlaineOmega বাস্তবিক বিশেষ এই এক: stackoverflow.com/a/11602478/321697 স্পষ্টভাবে আপনার প্রশ্নের উত্তর। ওরিয়েন্টেশন পরিবর্তন বা অন্য ইভেন্টের ফলে খণ্ডটিকে পুনরায় তৈরি করা যায়, অ্যান্ড্রয়েড ডিফল্ট কনস্ট্রাক্টর পাশাপাশি বান্ডেলকে আর্গুমেন্ট হিসাবে পাস করে। যদি আপনি কোনও কাস্টম কনস্ট্রাক্টর ব্যবহার করছেন, তবে এই ইভেন্টগুলির একটির কারণে খণ্ডটি পুনরায় তৈরি করা মাত্রই আপনি কাস্টম কনস্ট্রাক্টরে যা কিছু করেছেন তা নষ্ট হয়ে যায়।
কেভিন কপক

1
ধন্যবাদ, তবে এটি উত্তর দেয় তবে কীভাবে নয় not
ব্ল্যাকহ্যাটসামুরাই

এটি আমার মূল মন্তব্যে প্রথম এবং দ্বিতীয় লিঙ্কগুলি দ্বারা আচ্ছাদিত।
কমন্সওয়্যার

উত্তর:


110

একটি বান্ডিল বস্তু তৈরি করুন এবং আপনার ডেটা sertোকান (এই উদাহরণে আপনার Categoryঅবজেক্ট)। সাবধানতা অবলম্বন করুন, আপনি এই বস্তুটি সরাসরি বান্ডলে প্রবেশ করতে পারবেন না, যদি না এটি সিরিয়ালযোগ্য হয়। আমি মনে করি খণ্ডগুলিতে আপনার অবজেক্টটি তৈরি করা ভাল, এবং কেবল একটি আইডি বা অন্য কিছু বান্ডেলে রেখে দেওয়া। এটি একটি বান্ডিল তৈরি এবং সংযুক্ত করার কোড:

Bundle args = new Bundle();
args.putLong("key", value);
yourFragment.setArguments(args);

এর পরে, আপনার খণ্ড অ্যাক্সেস ডেটাতে:

Type value = getArguments().getType("key");

এখানেই শেষ.


3
কীভাবে কোন জিনিস পাস? আমি একটি প্রসঙ্গ অবজেক্ট বা অন্য কোনও অবজেক্ট পাস করতে চাই।
আদিল মালিক

12
বান্ডিলগুলি সিরিয়ালযুক্ত জাভা অবজেক্টের পাশাপাশি অবজেক্টও বহন করতে পারে Parcelable। এছাড়াও, আপনার কোনও পাস করা উচিত নয় Context, কারণ সেই তথ্যটি খণ্ডটির getActivity()পদ্ধতির মাধ্যমে অ্যাক্সেস করা যায় ।
ক্রাকাতোয়া

খণ্ডে কোথায় এটি করতে হবে Type value = getArguments().getType("key");?
মুহাম্মদ বাবর

4
@ মুহম্মদ বাবর: আমি যদি আপনি থাকতাম তবে আমি এটিকে newInstance()পদ্ধতিতে যুক্ত করতাম । উদাহরণস্বরূপ: public static FragmentName newInstance(your variables){}। অ্যান্ড্রয়েড ডকুমেন্টেশনের পরামর্শ অনুসারে, প্যারামিটারগুলি দিয়ে কোনও কনস্ট্রাক্টর তৈরি করবেন না, কারণ আপনার খণ্ডটি পুনরায় চালু করার পরে ডিফল্ট একটিকে (পরামিতি ছাড়াই) স্বয়ংক্রিয়ভাবে ডাকা হবে।
nistv4n

@ মুহম্মদবাবার অন ক্রিয়েটভিউ ঠিক আছে
চানজিয়ানী

272

দেখে মনে হচ্ছে যে উত্তরগুলির কোনওটিরই উত্তর নেই যে "কেন ডিফল্ট কনস্ট্রাক্টরের চেয়ে পরামিতিগুলি পাস করার জন্য বান্ডিল ব্যবহার করুন"

আপনার বান্ডিলের মাধ্যমে পরামিতিগুলি কেন অতিক্রম করা উচিত তার কারণ হ'ল যখন সিস্টেমটি একটি fragment(যেমন কনফিগারেশনের পরিবর্তে) পুনরুদ্ধার করে, এটি স্বয়ংক্রিয়ভাবে আপনার পুনরুদ্ধার করে bundle

কলব্যাকগুলি প্যারামিটারগুলি পছন্দ করে onCreateবা onCreateViewপড়তে পারে bundle- এইভাবে আপনি fragmentসঠিকভাবে একই অবস্থায় যে অবস্থাটি শুরু করেছিলেন ঠিক সেই অবস্থাতে পুনরুদ্ধার করার গ্যারান্টিযুক্ত fragment(নোট এই রাজ্যটি onSaveInstanceState bundleযেটি পাস হয়েছে তার থেকে আলাদা হতে পারে onCreate/onCreateView)

স্থির newInstance()পদ্ধতিটি ব্যবহারের সুপারিশটি কেবল একটি সুপারিশ। আপনি একটি অ ডিফল্ট কনস্ট্রাক্টর ব্যবহার করতে পারেন তবে নিশ্চিত করুন যে আপনি bundleসেই কনস্ট্রাক্টরের দেহের অভ্যন্তরে সূচনা পরামিতিগুলি স্থাপন করছেন । এবং সেই পরামিতিগুলি onCreate()বা onCreateView()পদ্ধতিতে পড়ুন।


2
ভাল করে বুঝিয়েছি। ধন্যবাদ। যদি আমিই যদি প্রশ্নটি জিজ্ঞাসা করি তবে আমি আপনাকে একটি টিক দিয়ে
দিতাম

5
আর আপনি অ-ডিফল্ট কনস্ট্রাক্টর ব্যবহার করতে পারবেন না (যে কারণেই হোক না কেন) .... এটি একটি সংকলক ত্রুটি দেয় (সতর্কতা হিসাবে ব্যবহৃত হয়েছিল)।
এমপিভ্লাক

51

তোমার Fragmentকারণ কিভাবে কনস্ট্রাকটর থাকা উচিত নয় FragmentManagerএটা instantiates। newInstance()আপনার প্রয়োজনীয় পরামিতিগুলির সাথে সংজ্ঞায়িত একটি স্ট্যাটিক পদ্ধতি থাকা উচিত , তারপরে সেগুলি বান্ডিল করুন এবং খণ্ডের আর্গুমেন্ট হিসাবে সেট করুন, যা আপনি পরে Bundleপ্যারামিটার দিয়ে অ্যাক্সেস করতে পারবেন ।

উদাহরণ স্বরূপ:

public static MyFragment newInstance(int title, String message) {
    MyFragment fragment = new MyFragment();
    Bundle bundle = new Bundle(2);
    bundle.putInt(EXTRA_TITLE, title);
    bundle.putString(EXTRA_MESSAGE, message);
    fragment.setArguments(bundle);
    return fragment ;
}

এবং এই যুক্তিগুলি এখানে পড়ুন onCreate:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    title = getArguments().getInt(EXTRA_TITLE);
    message = getArguments().getString(EXTRA_MESSAGE);

    //...
}

এইভাবে, যদি বিযুক্ত এবং পুনরায় সংযুক্ত থাকে, তবে বস্তুর অবস্থা আর্গুমেন্টের মাধ্যমে অনেকগুলি bundlesসংযুক্তের মতো সংরক্ষণ করা যেতে পারে Intent


9

আপনি যদি কিছু ক্লাসের জন্য প্যারামিটার ব্যবহার করেন। এটা চেষ্টা কর

SomeClass mSomeInstance;
public static final MyFragment newInstance(SomeClass someInstance){
    MyFragment f = new MyFragment();
    f.mSomeInstance = someInstance;
    return f;
}

5
এটি আসলে একটি খারাপ পরামর্শ। একবার খণ্ড খ এর মাধ্যমে আবার তৈরি করা FragmentManagerহবে, আপনি এমসোমাইন্সট্যান্স হারাবেন।
ইয়ারোস্লাভ মাইটকলিক

সম্মত হয়েছে, সামারক্লাসটি পার্সেবল এবং সেটআরগমেন্টস () ব্যবহার করে একটি বান্ডেলে সংরক্ষণ করা উচিত
জ্যাক_

1

আমি মনে করি, স্ট্যাটিক কন্সট্রাক্টর এবং দুটি কনস্ট্রাক্টরের মধ্যে কোনও পার্থক্য নেই (খালি এবং প্যারাম্যাট্রাইজড একটি যা ফ্রেগমেন্টের আর্গুমেন্ট বান্ডেলের মধ্যে যুক্তিগুলি সংরক্ষণ করে), সম্ভবত, জাভাতে নো-আরগ কনস্ট্রাক্টর প্রয়োগ করতে ভুলে যাওয়ার সম্ভাবনা হ্রাস করার জন্য থাম্বের এই নিয়মটি তৈরি করা হয়েছে probably , ওভারলোড উপস্থিত থাকাকালীন যা স্পষ্টভাবে উত্পন্ন হয় না।

আমার প্রকল্পগুলিতে আমি কোটলিন ব্যবহার করি এবং আর্গুমেন্টগুলির জন্য প্রাথমিক নো-আরগ নির্মাতা এবং গৌণ কনস্ট্রাক্টরের সাথে টুকরোগুলি প্রয়োগ করি যা এগুলি কেবল একটি বান্ডেলে সংরক্ষণ করে এবং এটি খণ্ড যুক্তি হিসাবে সেট করে, সবকিছু ঠিকঠাক কাজ করে।


0

যদি টুকরাটি কনফিগারেশন পরিবর্তনের পরে অ-ডিফল্ট নির্মাণকারী ব্যবহার করে তবে খণ্ডটি সমস্ত ডেটা হারাবে।

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