একটি নতুন অ্যান্ড্রয়েড টুকরা ইনস্ট্যান্ট করার জন্য সেরা অনুশীলন


705

আমি একটি অ্যাপ্লিকেশনটিতে একটি নতুন টুকরা ইনস্ট্যান্ট করতে দুটি সাধারণ অনুশীলন দেখেছি:

Fragment newFragment = new MyFragment();

এবং

Fragment newFragment = MyFragment.newInstance();

দ্বিতীয় বিকল্পটি একটি স্থিতিশীল পদ্ধতি ব্যবহার করে newInstance()এবং সাধারণত নিম্নলিখিত পদ্ধতিটি ধারণ করে।

public static Fragment newInstance() 
{
    MyFragment myFragment = new MyFragment();
    return myFragment;
}

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

আমি কি কিছু রেখে গেলাম?

অন্য এক পদ্ধতির সুবিধা কি? নাকি এটা কি শুধুই ভাল অভ্যাস?


যখন প্যারামিটারগুলি থাকে, তখন কোনও পছন্দ হয় না এবং এটির এখানে বিস্তৃত উত্তর দেওয়া হয়। তবুও, প্রশ্নটি খণ্ডটি অ-যুক্তিযুক্ত নির্মাণের জন্য রয়ে গেছে।
rd

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

উত্তর:


1136

যদি অ্যান্ড্রয়েড পরে আপনার ফ্রেগমেন্টটি পুনরায় তৈরি করার সিদ্ধান্ত নেয়, এটি আপনার খণ্ডটির নো-আর্গুমেন্ট কনস্ট্রাক্টরকে কল করতে চলেছে। সুতরাং নির্মাণকারীকে ওভারলোড করা কোনও সমাধান নয়।

এই কথাটি বলা হচ্ছে যে, আপনার ফ্র্যাগমেন্টে স্টাফগুলি পাস করার উপায়টি যাতে অ্যান্ড্রয়েড দ্বারা ফ্রেগমেন্টটি পুনরায় তৈরি করার পরে সেগুলি উপলব্ধ থাকে সে setArgumentsপদ্ধতিতে একটি বান্ডিল পাস করা ।

সুতরাং, উদাহরণস্বরূপ, আমরা যদি খণ্ডটিতে একটি পূর্ণসংখ্যারটি পাস করতে চাই তবে আমরা এরকম কিছু ব্যবহার করব:

public static MyFragment newInstance(int someInt) {
    MyFragment myFragment = new MyFragment();

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    myFragment.setArguments(args);

    return myFragment;
}

এবং পরে খণ্ডে onCreate()আপনি ব্যবহার করে সেই পূর্ণসংখ্যার অ্যাক্সেস করতে পারেন:

getArguments().getInt("someInt", 0);

এই বান্ডিলটি উপলব্ধ হবে এমনকি যদি ফ্রেগমেন্টটি কোনওভাবে অ্যান্ড্রয়েড দ্বারা তৈরি করা হয়।

এছাড়াও দ্রষ্টব্য: setArgumentsক্রিয়াকলাপের সাথে খণ্ডটি সংযুক্ত হওয়ার আগে কেবল কল করা যেতে পারে।

এই পদ্ধতির অ্যান্ড্রয়েড বিকাশকারী রেফারেন্সেও নথিভুক্ত করা হয়েছে: https://developer.android.com/references/android/app/Fragment.html


7
@ ভ্লাস্টো দুর্ভাগ্যক্রমে স্থির পদ্ধতিগুলি ওভাররাইড করা যায় না।
এজেডি

8
@ হাইডল আমি মনে করি যে আমি এখানে কিছু মিস করছি, আপনি এখানে কোনও কনস্ট্রাক্টর ব্যবহার করতে পারবেন না, যেটি বান্ডিল তৈরি করে এবং সেটআর্গমেন্টস () কল করে এখনও এটি কেবল আপনার কোড দ্বারা কল করা হবে (এবং যখন অ্যান্ড্রয়েড আপনার পুনরায় তৈরি করে না তখন টুকরা)?
মাইক টোনিক্লিফ

9
@ এমজিবসন যদি খণ্ডটি পরে পুনরায় তৈরি করা হয় তবে আপনি ডেটা উপলভ্য করতে চাইলে আপনাকে অবশ্যই একটি বান্ডিল ব্যবহার করতে হবে।
ইয়াইল

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

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

95

newInstance()আমি যে দেখি তা ব্যবহারের একমাত্র উপকারটি হ'ল:

  1. আপনার একটি একক জায়গা থাকবে যেখানে খণ্ড দ্বারা ব্যবহৃত সমস্ত যুক্তিগুলি বান্ডিল করা যেতে পারে এবং প্রতিবার কোনও খণ্ডকে ইনস্ট্যান্ট করার সময় আপনাকে নীচের কোডটি লিখতে হবে না।

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    args.putString("someString", someString);
    // Put any other arguments
    myFragment.setArguments(args);
  2. এটি অন্যান্য ক্লাসগুলিকে কী যুক্তি দিয়ে বিশ্বস্ততার সাথে কাজ করার আশা করে তা জানানোর এটি একটি ভাল উপায় (যদিও খণ্ডের ক্ষেত্রে কোনও যুক্তি বান্ডিল না করা থাকলে আপনার কেসগুলি পরিচালনা করতে সক্ষম হওয়া উচিত)।

সুতরাং, আমার গ্রহণযোগ্যতাটি newInstance()হ'ল কোনও খণ্ডকে ইনস্ট্যান্ট করতে স্ট্যাটিক ব্যবহার করা ভাল অভ্যাস।


4
1) এটি কোনও কনস্ট্রাক্টারে লজিক রাখার চেয়ে আলাদা কীভাবে? উভয়ই একক স্থান যেখানে আপনি এই যুক্তি যুক্ত করেছেন। 2) স্ট্যাটিক কারখানার প্যারামিটারগুলি কনস্ট্রাক্টরের পরামিতিগুলির চেয়ে আলাদা কীভাবে? উভয়ই বলুন কী যুক্তি প্রত্যাশিত। আমার বক্তব্য হ'ল এটি একটি আলাদা দৃষ্টান্ত, অবশ্যই, তবে কনস্ট্রাক্টর ব্যবহার করে এটির কোনও সুস্পষ্ট সুবিধা নেই।
আরজে কুথবার্টসন

2
আপনি খণ্ডের জন্য কাস্টম কনস্ট্রাক্টর ব্যবহার করতে পারবেন না। টুকরোগুলি পুনরুদ্ধারের জন্য ফ্রেমওয়ার্ক কোনও যুক্তি নির্মাতা ব্যবহার করে।
500865

5
হ্যাঁ, আমি সেখানে আপনার সাথে একমত আমি ধারণা করছি বলছি ওভারলোডেড কনস্ট্রাক্টর ব্যবহার না করে স্থির কারখানার প্যাটার্নটি ব্যবহার করার কোনও সুবিধা নেই এবং তদ্বিপরীত। আপনার উভয় পয়েন্ট উভয়ই নিদর্শন বৈধ; একে অপরকে ব্যবহার করে লাভ নেই। অ্যান্ড্রয়েড আপনাকে স্থির কারখানার প্যাটার্ন ব্যবহার করতে বাধ্য করে - তবে একটি বা অন্যটি ব্যবহার করে কোনও লাভ হয় না।
আরজে কুথবার্টসন

পেস্টবিন.com
আরজে কুথবার্টসন

@ আরজেকুবার্টসন একটি সম্ভাব্য সুবিধা হ'ল স্থিতিশীল কারখানার পদ্ধতির শ্রেণীর সাবক্লাস তৈরি এবং ফিরিয়ে আনার ক্ষমতা অর্থাৎ পরিস্থিতির জন্য উপযুক্ত উপক্লাস ফিরিয়ে দেওয়া।
তাত্ক্ষণিক

62

আরও একটি উপায় আছে:

Fragment.instantiate(context, MyFragment.class.getName(), myBundle)

যদি আমার ভুল না হয় তবে এটি কেবল তখনই সম্ভব যখন আপনি অ্যান্ড্রয়েড সমর্থন লাইব্রেরি ব্যবহার করেন।
টিমো

2
সমর্থন লাইব্রেরি দিয়ে এটি চেষ্টা করে দেখুন, তবে অনক্রিটভিউতে (আমার খণ্ডে), বান্ডিলটি পাস হয়ে গেছে, তাই আমি সেটআর্গমেন্টস / গেটআরগমেন্টস বিকল্পটি দিয়ে চলেছি এবং এটি (যে কেউ এটি পড়ার জন্য) কাজ করে।
Jrop

1
মজার বিষয়, আমি এই পদ্ধতির আগে দেখিনি। খণ্ডটি ইনস্ট্যান্ট করার জন্য অন্যান্য পদ্ধতির তুলনায় এর কোনও সুবিধা আছে কি?
ইগোরগানাপলস্কি

22
থেকে বিকাশকারী ডক্স ,instantiate() Creates a new instance of a Fragment with the given class name. This is the same as calling its empty constructor.
ব্রায়ান তীরন্দাজ

2
যদিও তারা খালি কনস্ট্রাক্টরকে কল করার অনুরূপ উল্লেখ করেছে। "args.setClassLoader (f.getClass () getClassLoader ()।);" বান্ডিল আর্গুমেন্ট জন্য নীচে বলা হয়
Gakhan Barış Aker

49

যদিও @yydl newInstanceপদ্ধতিটি আরও ভাল কেন তার জন্য একটি বাধ্যতামূলক কারণ দেয় :

যদি অ্যান্ড্রয়েড পরে আপনার ফ্রেগমেন্টটি পুনরায় তৈরি করার সিদ্ধান্ত নেয়, এটি আপনার খণ্ডটির নো-আর্গুমেন্ট কনস্ট্রাক্টরকে কল করতে চলেছে। সুতরাং নির্মাণকারীকে ওভারলোড করা কোনও সমাধান নয়।

এটি এখনও কনস্ট্রাক্টর ব্যবহার করা বেশ সম্ভব । এটি কেন তা দেখার জন্য প্রথমে আমাদের দেখতে হবে যে উপরের ওয়ার্কআউন্ডটি অ্যান্ড্রয়েড কেন ব্যবহার করে।

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

ক্রিয়াকলাপের জীবদ্দশায় খণ্ডটি উপরে হিসাবে তৈরি হয় এবং অ্যান্ড্রয়েড দ্বারা একাধিকবার ধ্বংস হয়। এর অর্থ হ'ল আপনি যদি খণ্ড খণ্ডটিতে নিজেই ডেটা রাখেন, খণ্ডটি নষ্ট হয়ে গেলে এটি হারিয়ে যাবে।

অবিচ্ছিন্নভাবে, অ্যান্ড্রয়েড আপনাকে একটি Bundle(কলিং setArguments()) ব্যবহার করে ডেটা সঞ্চয় করার জন্য জিজ্ঞাসা করে , যা এর পরে অ্যাক্সেস করা যায় YourFragment। যুক্তি bundleগুলি অ্যান্ড্রয়েড দ্বারা সুরক্ষিত এবং তাই অবিচ্ছিন্ন থাকার গ্যারান্টিযুক্ত ।

একটি স্ট্যাটিক newInstanceপদ্ধতি ব্যবহার করে এই বান্ডিলটি সেট করার একটি উপায় :

public static YourFragment newInstance (int data) {
    YourFragment yf = new YourFragment()
    /* See this code gets executed immediately on your object construction */
    Bundle args = new Bundle();
    args.putInt("data", data);
    yf.setArguments(args);
    return yf;
}

তবে, একজন নির্মাতা:

public YourFragment(int data) {
    Bundle args = new Bundle();
    args.putInt("data", data);
    setArguments(args);
}

newInstanceপদ্ধতি হিসাবে ঠিক একই জিনিস করতে পারেন ।

স্বাভাবিকভাবেই, এটি ব্যর্থ হবে এবং অ্যান্ড্রয়েড আপনি যে newInstanceপদ্ধতিটি ব্যবহার করতে চান তার অন্যতম কারণ :

public YourFragment(int data) {
    this.data = data; // Don't do this
}

আরও ব্যাখ্যা হিসাবে, এখানে অ্যান্ড্রয়েডের টুকরা ক্লাস:

/**
 * Supply the construction arguments for this fragment.  This can only
 * be called before the fragment has been attached to its activity; that
 * is, you should call it immediately after constructing the fragment.  The
 * arguments supplied here will be retained across fragment destroy and
 * creation.
 */
public void setArguments(Bundle args) {
    if (mIndex >= 0) {
        throw new IllegalStateException("Fragment already active");
    }
    mArguments = args;
}

নোট করুন যে অ্যান্ড্রয়েড জিজ্ঞাসা করেছে যে আর্গুমেন্টগুলি কেবল নির্মাণের সময় সেট করা হবে এবং গ্যারান্টি দেয় যে এগুলি বজায় রাখা হবে।

সম্পাদনা : হিসাবে, @JHH দ্বারা মন্তব্য নির্দিষ্ট যদি আপনি যে কিছু আর্গুমেন্ট প্রয়োজন একটি কাস্টম কন্সট্রাকটর প্রদান, তারপর জাভা একটির সাথে আপনার টুকরা প্রদান করবে না কোন ARG ডিফল্ট কন্সট্রাকটর। সুতরাং এটির জন্য আপনাকে কোনও আরগ কনস্ট্রাক্টর সংজ্ঞায়িত করতে হবে , যা কোড যা আপনি newInstanceকারখানার পদ্ধতিতে এড়াতে পারেন ।

সম্পাদনা : অ্যান্ড্রয়েড আর টুকরো টুকরো করার জন্য একটি ওভারলোডেড কনস্ট্রাক্টর ব্যবহারের অনুমতি দেয় না। আপনার অবশ্যই newInstanceপদ্ধতিটি ব্যবহার করা উচিত ।


কখন অ্যান্ড্রয়েড ব্যবহারের ন্যায্যতা পাওয়া যাবে: কনফিগারেশন = "ওরিয়েন্টেশন? কীবোর্ডহিডেন | স্ক্রিনসাইজ"?
লুক অ্যালিসন

1
অ্যান্ড্রয়েড স্টুডিও এখন সমস্ত অ-ডিফল্ট নির্মাতাদের খণ্ডগুলিতে ত্রুটি ছুঁড়েছে, সুতরাং এটি আর কাজ করে না।
শেহেরিয়ার

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

3
ঠিক আছে, একটি সূক্ষ্ম কারণ আছে। আপনি আর্গুমেন্ট দিয়ে আপনার নিজের নির্মাতা তৈরি করতে নির্দ্বিধায় রয়েছেন, তবে এখনও একটি নো-আরগ কনস্ট্রাক্টর হওয়া দরকার । যেহেতু ক্লাসগুলির সর্বদা একটি নিখরচায় নো-আরগ কনস্ট্রাক্টর থাকে যতক্ষণ না আরগস সহ কোনও কনস্ট্রাক্টর স্পষ্টভাবে সংজ্ঞায়িত করা হয় , এর অর্থ হ'ল আপনাকে আপনার আর্গ-কনস্ট্রাক্টর এবং একটি নো-আরগ কনস্ট্রাক্টর উভয়কেই স্পষ্টভাবে সংজ্ঞায়িত করতে হবে , বা সিস্টেম কোনও আবেদন করতে সক্ষম হবে না নো-আরগ নির্মাণকারী। আমি বিশ্বাস করি এ কারণেই স্থির কারখানার পদ্ধতিটি ব্যবহার করার পরামর্শ দেওয়া হচ্ছে - এটি কেবল কোনও নো-আরগ কনস্ট্রাক্টর সংজ্ঞা দিতে ভুলে যাওয়ার ঝুঁকি হ্রাস করে।
JHH

@ জেএইচএইচ যে সংকলন সময়ে নিজেই ব্যর্থ হবে, তাই ঝুঁকি এত বড় নয়। তবে, এখানে সমস্যাটি হল যে কনস্ট্রাক্টর ওভারলোডিং, একটি মূল প্রোগ্রামিং দৃষ্টান্ত, যা অ্যান্ড্রয়েড দ্বারা অস্বীকার করা হচ্ছে।
PS95

20

আমি yydi উত্তর সাথে একমত দিয়ে :

যদি অ্যান্ড্রয়েড পরে আপনার ফ্রেগমেন্টটি পুনরায় তৈরি করার সিদ্ধান্ত নেয়, এটি আপনার খণ্ডটির নো-আর্গুমেন্ট কনস্ট্রাক্টরকে কল করতে চলেছে। সুতরাং নির্মাণকারীকে ওভারলোড করা কোনও সমাধান নয়।

আমি মনে করি এটি একটি সমাধান এবং একটি ভাল, এটি জাভা মূল ভাষা দ্বারা এটি বিকাশ করা ঠিক ঠিক কারণ।

এটি সত্য যে অ্যান্ড্রয়েড সিস্টেম আপনার ধ্বংস এবং পুনরায় তৈরি করতে পারে Fragment। সুতরাং আপনি এটি করতে পারেন:

public MyFragment() {
//  An empty constructor for Android System to use, otherwise exception may occur.
}

public MyFragment(int someInt) {
    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    setArguments(args);
}

এটি আপনাকে পরবর্তী someIntথেকে টানতে দেয় getArguments(), এমনকি যদি Fragmentসিস্টেম দ্বারা পুনরায় তৈরি করা হয়। এটি এর চেয়ে আরও মার্জিত সমাধানstatic কনস্ট্রাক্টরের ।

আমার মতামতের জন্য staticকনস্ট্রাক্টরগুলি বেহুদা এবং ব্যবহার করা উচিত নয়। ভবিষ্যতে আপনি এটি প্রসারিত Fragmentকরতে এবং নির্মাণকারীর আরও কার্যকারিতা যুক্ত করতে চাইলে তারা আপনাকে সীমাবদ্ধ করে দেবে । সঙ্গে staticকন্সট্রাকটর আপনি এই কাজ করতে পারবে না।

হালনাগাদ:

অ্যান্ড্রয়েড পরিদর্শন যোগ করেছে যা ত্রুটিযুক্ত সমস্ত অ-ডিফল্ট নির্মাণকারীকে পতাকাঙ্কিত করে।
আমি উপরে বর্ণিত কারণে, এটি নিষ্ক্রিয় করার পরামর্শ দিচ্ছি।


4
একটি স্থিতিশীল পদ্ধতি থাকার আরেকটি সুবিধা যা আমি উপরে উল্লেখ করি নি তা হল আপনি দুর্ঘটনাক্রমে এ থেকে সম্পত্তি সেট করতে পারবেন না।
yydl

4
অতিরিক্ত হিসাবে, "এই খণ্ডটি প্রসারিত করুন" সম্পর্কে আপনার পয়েন্টটি সম্পর্কিত, আপনি যদি কখনও ক্লাসটি প্রসারিত করেন তবে এই পদ্ধতিটি আসলেই খারাপ হবে। সুপারকে কল করা সেটঅর্গমেন্টস () কলটি কেবলমাত্র শিশু বা পিতামাতার উভয়ের জন্য কার্যকর হবে, তবে উভয়েরই নয়!
yydl

2
@ হাইডলে আপনি শিশু বান্ডেল শুরু করার জন্য আর্গুমেন্ট কল করে এই পরিস্থিতি এড়াতে পারবেন। জাভা উপায় সবসময় ভাল।
ইলিয়া গাজমান

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

3
আমি @ হাইডেলের সাথে একমত যে স্থির সৃষ্টি আরও ভাল। আর একটি সুবিধা হ'ল ভবিষ্যতের নতুন নির্ভরতাগুলির নির্ভরতা ইনজেকশন - এর জন্য কনস্ট্রাক্টর অসুস্থ এবং এটি আরও কোড পরিবর্তন (বা আরও কনস্ট্রাক্টর যুক্ত হতে পারে) এর কারণ হতে পারে।
বুন 18

19

কিছু কোটলিন কোড:

companion object {
    fun newInstance(first: String, second: String) : SampleFragment {
        return SampleFragment().apply {
            arguments = Bundle().apply {
                putString("firstString", first)
                putString("secondString", second)
            }
        }
    }
}

এবং আপনি এটি দিয়ে যুক্তি পেতে পারেন:

val first: String by lazy { arguments?.getString("firstString") ?: "default"}
val second: String by lazy { arguments?.getString("secondString") ?: "default"}

3

অ্যান্ড্রয়েডে যুক্তিযুক্ত টুকরো টুকরো টুকরো করার সর্বোত্তম অনুশীলন হ'ল আপনার খণ্ডে স্থিতিশীল কারখানা পদ্ধতি।

public static MyFragment newInstance(String name, int age) {
    Bundle bundle = new Bundle();
    bundle.putString("name", name);
    bundle.putInt("age", age);

    MyFragment fragment = new MyFragment();
    fragment.setArguments(bundle);

    return fragment;
}

কোনও খণ্ডের উদাহরণ সহ আপনার ক্ষেত্রগুলি সেট করা আপনার এড়ানো উচিত। কারণ যখনই অ্যান্ড্রয়েড সিস্টেমটি আপনার খণ্ডটিকে পুনরায় তৈরি করে, যদি মনে হয় যে সিস্টেমে আরও মেমরির প্রয়োজন রয়েছে, তার চেয়ে কোনও যুক্তি ছাড়াই কনস্ট্রাক্টর ব্যবহার করে এটি আপনার খণ্ডটিকে পুনরায় তৈরি করবে।

আপনি এখানে আর্গুমেন্টের সাহায্যে টুকরো টুকরো টানতে সর্বোত্তম অনুশীলন সম্পর্কে আরও তথ্য পেতে পারেন ।


2

যেহেতু সেরা অনুশীলন সম্পর্কে প্রশ্নগুলি রয়েছে, আমি যুক্ত করব, প্রায়শই কিছু রেস্ট ওয়েবসাইটের সাথে কাজ করার সময় খণ্ড তৈরির জন্য হাইব্রিড পদ্ধতির ব্যবহার করা খুব ভাল ধারণা

আমরা ব্যবহারকারীর অংশটি প্রদর্শন করার ক্ষেত্রে কিছু জটিল মডেল উদাহরণস্বরূপ কিছু ব্যবহারকারীর মডেলটি পাস করতে পারি না

তবে আমরা যা করতে পারি তা হ'ল onCreateসেই ব্যবহারকারীর চেক করা ! = বাতিল এবং যদি না হয় - তবে তাকে ডেটা স্তর থেকে আনুন, অন্যথায় - বিদ্যমান ব্যবহার করুন।

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

কিছু এটি পছন্দ করে:

public class UserFragment extends Fragment {
    public final static String USER_ID="user_id";
    private User user;
    private long userId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        userId = getArguments().getLong(USER_ID);
        if(user==null){
            //
            // Recreating here user from user id(i.e requesting from your data model,
            // which could be services, direct request to rest, or data layer sitting
            // on application model
            //
             user = bringUser();
        }
    }

    public static UserFragment newInstance(User user, long user_id){
        UserFragment userFragment = new UserFragment();
        Bundle args = new Bundle();
        args.putLong(USER_ID,user_id);
        if(user!=null){
            userFragment.user=user;
        }
        userFragment.setArguments(args);
        return userFragment;

    }

    public static UserFragment newInstance(long user_id){
        return newInstance(null,user_id);
    }

    public static UserFragment newInstance(User user){
        return newInstance(user,user.id);
    }
}

3
আপনি বলেছিলেন: "আমরা জটিল বস্তুগুলি পাস করতে পারি না, উদাহরণস্বরূপ কিছু ব্যবহারকারীর মডেল" - এটি সত্য নয়, আমরা পারি। এটির মতো: User user = /*...*/ ব্যবহারকারীকে বান্ডলে রাখুন: Bundle bundle = new Bundle(); bundle.putParcelable("some_user", user); এবং যুক্তি থেকে ব্যবহারকারীকে পান: User user = getArguments().getParcelable("some_user");অবজেক্টটি অবশ্যই পার্সেবল ইন্টারফেস প্রয়োগ করতে হবে। লিঙ্ক
আদম ভারহেগি

3
আচ্ছা, হ্যাঁ, তবে যখন শ্রেণি জটিল হয় এবং অন্য কোনও অবজেক্টের রেফার থাকে ... আমি ব্যক্তিগতভাবে এটিকে সহজ রাখতে পছন্দ করি, হয় আমার আপত্তি আছে, অথবা আমার নেই এবং তারপরে এটি পাওয়া দরকার
টিগ্রা

1

এই সমস্যাটি ব্যবহার করুন 100% আপনার সমস্যার সমাধান করুন

ফার্স্ট ফ্রেমে এই কোডটি প্রবেশ করান

public static yourNameParentFragment newInstance() {

    Bundle args = new Bundle();
    args.putBoolean("yourKey",yourValue);
    YourFragment fragment = new YourFragment();
    fragment.setArguments(args);
    return fragment;
}

এই নমুনা বুলিয়ান ডেটা প্রেরণ

এবং সিকেন্ডফ্র্যাগমেন্টে

yourNameParentFragment name =yourNameParentFragment.newInstance();
   Bundle bundle;
   bundle=sellDiamondFragments2.getArguments();
  boolean a= bundle.getBoolean("yourKey");

প্রথম খণ্ডে মান অবশ্যই স্থিতিশীল

হ্যাপি কোড


0

খণ্ডটি ইনস্ট্যান্ট করার সর্বোত্তম উপায় হ'ল ডিফল্ট ফ্রেগমেন্ট ইনস্ট্যানিয়েট পদ্ধতি ব্যবহার করুন বা টুকরোটি ইনস্ট্যান্ট করতে ফ্যাক্টরি পদ্ধতি তৈরি করুন
সতর্কতা: খণ্ডের স্মৃতি পুনরুদ্ধার করার সময় সর্বদা একটি খালি নির্মাণকারীর তৈরি করুন রান-টাইম ব্যতিক্রম ছুঁড়ে ফেলা হবে।


0

আমি ইদানীং এখানে আছি। তবে আমি কিছুটা সবেমাত্র জানি যা আপনাকে কিছুটা সাহায্য করতে পারে।

আপনি যদি জাভা ব্যবহার করছেন তবে পরিবর্তন করার মতো অনেক কিছুই নেই। তবে কোটলিন বিকাশকারীদের জন্য, এখানে কয়েকটি নীচের স্নিপেট আমি মনে করি যা আপনাকে চালানোর জন্য বেসমেন্টে পরিণত করতে পারে:

  • অভিভাবক খণ্ড:
inline fun <reified T : SampleFragment> newInstance(text: String): T {
    return T::class.java.newInstance().apply {
        arguments = Bundle().also { it.putString("key_text_arg", text) }
    }
}
  • সাধারণ কল
val f: SampleFragment = SampleFragment.newInstance("ABC")
// or val f = SampleFragment.newInstance<SampleFragment>("ABC")
  • আপনি শিশু খণ্ড শ্রেণিতে পিতামাতার আরম্ভ অপারেশনটি এর দ্বারা প্রসারিত করতে পারেন:
fun newInstance(): ChildSampleFragment {
    val child = UserProfileFragment.newInstance<ChildSampleFragment>("XYZ")
    // Do anything with the current initialized args bundle here
    // with child.arguments = ....
    return child
}

শুভ কোডিং।


-2

setArguments()অকেজো এটি কেবল একটি জগাখিচুড়ি এনে দেয়।

public class MyFragment extends Fragment {

    public String mTitle;
    public String mInitialTitle;

    public static MyFragment newInstance(String param1) {
        MyFragment f = new MyFragment();
        f.mInitialTitle = param1;
        f.mTitle = param1;
        return f;
    }

    @Override
    public void onSaveInstanceState(Bundle state) {
        state.putString("mInitialTitle", mInitialTitle);
        state.putString("mTitle", mTitle);
        super.onSaveInstanceState(state);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
        if (state != null) {
            mInitialTitle = state.getString("mInitialTitle");
            mTitle = state.getString("mTitle");
        } 
        ...
    }
}

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

@ আসাগেন, আমি প্রাথমিক এবং ব্যবহারকারীর মানগুলির তুলনা সম্পর্কে আপনার মন্তব্য পছন্দ করি। আমি কোড সম্পাদনা করেছি এবং বিবেচনা করি যে এটি এখনও অভিন্ন এবং স্পষ্ট বিস্মৃত getArgumentsস্টাফ। onViewCreatedসুযোগ সম্পর্কে কী ... আমরা সেখানে রাষ্ট্রীয় বান্ডিলটি পুনরুদ্ধার করতে পারি। তবে আমি কেবল onCreateViewহালকা এবং দ্রুত তৈরি করা পছন্দ করি এবং এর মধ্যে সমস্ত ভারী সূচনা করি onActivityCreatedকারণ Fragment.getActivity()কখনও কখনও ফিরে আসতে পছন্দ করে nullএবং onAttach()এপিআই 23 এর নতুন সংস্করণে পরিবর্তনের কারণে
ভাদিম স্টার

আপনি এখানে যা করেছেন তা সব সরানো set এবং get Argumentsপ্রবেশ করানো হয়েছিল saveInstanceState। আপনি মূলত একই জিনিস করছেন যা "হুডের নিচে"
ওয়ান ক্রিকেটার

1
@ ক্রিকেট_007, বা ঠিক বিপরীত । ব্যবহার করা saveInstanceStateহচ্ছে "হুডের নিচে"। এবং এর ব্যবহার Argumentsহ'ল কার্যকারিতার সদৃশতা যা আপনাকে দ্বিগুণ চেক করে তোলে: প্রথম Argumentsমান এবং তারপরে saveInstanceStateমানগুলি। কারণ আপনাকে যে saveInstanceStateকোনও উপায়ে ব্যবহার করতে হবে । কি সম্পর্কে Arguments... তারা প্রয়োজন হয় না।
ভাদিম স্টার

যুক্তিগুলি খণ্ডগুলির জন্য ইনটেন্ট অতিরিক্তগুলির সমতুল্য । এগুলি অকেজো নয়, এগুলিতে প্রাথমিক পরামিতি রয়েছে যা বর্তমান অবস্থা থেকে পৃথক।
ব্লেডকডার

-12

আমি বিশ্বাস করি এটির জন্য আমার আরও সহজ সমাধান রয়েছে।

public class MyFragment extends Fragment{

   private String mTitle;
   private List<MyObject> mObjects;

   public static MyFragment newInstance(String title, List<MyObject> objects)
   MyFragment myFrag = new MyFragment();
   myFrag.mTitle = title;
   myFrag.mObjects = objects;
   return myFrag;
   }

12
মাইফ্র্যাগমেন্টটি পুনরায় তৈরি হয়ে গেলে এমওবজগুলি সাফ হয়ে যাবে (ব্যবহারকারী ডিভাইসের হোম স্ক্রিনে যান এবং পরে মাইফ্রেগমেন্টে ছেড়ে যাওয়া অ্যাপটি খুলুন)। আপনি মাইফ্রেগমেন্টটিকে আর্গুমেন্ট হিসাবে একটি বান্ডিল প্রেরণ করে এমওবজেক্টগুলি ধরে রাখতে পারবেন।
ynnadkrap

1
এছাড়াও, স্থিতিশীল পদ্ধতিটি কীভাবে অ স্থিতিশীল সদস্য ভেরিয়েবলগুলি অ্যাক্সেস করতে পারে?
OrhanC1

2
@ynnadkrap আপনি সঠিক, একটি বান্ডিল ব্যবহার এখানে যাওয়ার উপায়।
স্টিফান বোগার্ড

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

@ গুহন আপনি ঠিক বলেছেন! এটা না। বিভ্রান্তির জন্য দুঃখিত :)
OrhanC1
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.