রিসাইক্লারভিউ.ভিউহোল্ডার - getAlapout অবস্থান বনাম getAdapterPosition


90

নতুন সমর্থন লাইব্রেরি সংস্করণ (22.x) যেহেতু বিষয়টিতে উল্লিখিত পদ্ধতিগুলির পরিবর্তে ক্লাসের getPosition()পদ্ধতি অবনমিত RecyclerView.ViewHolderকরা হয়েছে। আমি ডক্সটি পড়ে সত্যিই পার্থক্য পাই না। কেউ কি সাধারণ ব্যক্তির শর্তাবলী পার্থক্য ব্যাখ্যা করতে পারে?

আমার নীচের ব্যবহারের কেস রয়েছে - আমি আমার অ্যাডাপ্টারকে একটি দিই List, এবং প্রতিটি তালিকার আইটেমের জন্য অতিরিক্ত তথ্য সংযুক্ত করতে সক্ষম হতে চাই। আমার কাছে অবস্থান-থেকে-অতিরিক্ত ম্যাপিং রয়েছে, এবং ম্যাপিং হোল্ডারদের জন্য উপলব্ধ যাতে তারা তাদের অবস্থানের জন্য অতিরিক্ত আনতে এবং এটি দিয়ে স্টাফ করতে পারে। ধারকটিতে, আমার কোন পদ্ধতিটি ব্যবহার করা উচিত?

সূচক 0 এবং 1 এ তালিকার আইটেমগুলি স্থান পরিবর্তন করা হলে ধারক পজিশনের সাথে কী ঘটে? পদ্ধতিগুলি কি ফিরে আসে?

উত্তর:


116

এটি একটি জটিল পরিস্থিতি, দুঃখিত যে ডক্স যথেষ্ট নয়।

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

আপনার ব্যবহারের ক্ষেত্রে, যেহেতু আপনার ডেটা আপনার অ্যাডাপ্টারের সামগ্রীর সাথে সম্পর্কিত (এবং আমি ধরে নিই যে অ্যাডাপ্টারের পরিবর্তনের সাথে ডেটা একই সময়ে পরিবর্তিত হয়েছিল), আপনার ব্যবহার করা উচিত adapterPosition

সতর্ক থাকুন, যদি আপনি কল করছেন notifyDataSetChanged(), কারণ এটি সবকিছুকে অকার্যকর করে দেয়, রিসাইক্লার ভিউ জানেন না যে পরবর্তী লেআউটটি গণনা করা না হওয়া পর্যন্ত ভিউহোল্ডারের অ্যাডাপ্টারের অবস্থানটি জানেন না। সেক্ষেত্রে, getAdapterPosition()ফিরে আসবে RecyclerView#NO_POSITION( -1)।

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

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

যখন লেআউট অবস্থান ভাল হয় জন্য সম্পাদনা করুন

আপনাকে LinearLayoutManagerএখন ক্লিক করা আইটেমের উপরে ভিউহোল্ডারটি ব্যবহার করতে এবং অ্যাক্সেস করতে চাই তা বলতে দিন । সেক্ষেত্রে উপরের আইটেমটি পেতে আপনার বিন্যাসের অবস্থানটি ব্যবহার করা উচিত।

mRecyclerView.findViewHolderForLayoutPosition(myViewHolder.getLayoutPosition() - 1)

আপনাকে লেআউট অবস্থানটি ব্যবহার করতে হবে কারণ এটি বর্তমানে স্ক্রিনে ব্যবহারকারী যা দেখছেন তার সাথে এটি মেলে।


4
আমি কিছুটা খেলা করেছি এবং এটি getAdapterPosition () পদ্ধতিটি সর্বদা আমার উপর ফেরত দেয়। আমি এটি ডিবাগ করেছি এবং কারণটি হ'ল পদ্ধতিটির কোড (চূড়ান্ত ভিউ-প্যারেন্ট প্যারেন্ট = আইটেম ভিউ.সেটপ্যারেন্ট (); যদি (! (পিতামহ উদাহরণস্বরূপ রিসাইক্লারভিউ)) {রিটার্ন -1;} সর্বদা আইএফ ব্লকের মধ্যে চলে আসে, অর্থাত্ পুনর্ব্যবহারকারী ভিউ আমার ঘর দেখার পিতামাতা নয় not এটি কীভাবে হতে পারে? ধারক তৈরি করার জন্য আমার কোডটি হ'ল: MyViewHolder (LayoutInflater.from (viewGroup.getContext ()) ফিরিয়ে দিন inf (অন্য মন্তব্যে অব্যাহত))
wujek

আমি যখন ফোনটি ফোলা কল করতে কোড পরিবর্তন করি (R.layout.test_list_item, ভিউগ্রুপ, সত্য); ('রুটে সংযুক্ত হওয়ার জন্য সত্যটি নোট করুন), অ্যান্ড্রয়েড নিক্ষেপ করেছে: java.lang.IllegalStateException: নির্দিষ্ট সন্তানের ইতিমধ্যে একটি পিতামাতা রয়েছে। আপনাকে অবশ্যই প্রথমে সন্তানের পিতামাতার কাছে রিমুভ ভিউ () কল করতে হবে। তাহলে পুনরায় ব্যবহারকারীর দৃশ্যের সাথে সঠিকভাবে সংযুক্ত এমন একটি ভিউ সহ কোনও দৃশ্য ধারক তৈরির সঠিক উপায় কী? আশ্চর্যজনকভাবে যথেষ্ট, এমনকি যদি getAdapterPosition () -1 ফেরত দেয় কারণ পিতা-মাতা নাল, অন্য সব কিছু ঠিকঠাক কাজ করে।
ওয়াজেক

4
লেআউট ইনফ্ল্লেটারের বুলিয়ান প্যারামিটারটি হ'ল "অ্যাডটোপারেন্ট"। এটি অবশ্যই মিথ্যা হবে কারণ এটি যুক্ত করা লেআউটম্যানেজারের দায়িত্ব। আমি মনে করি আপনি অনবিন্দে getAdapterPosition কল করছেন যেখানে আপনি ইতিমধ্যে অবস্থানটি পাস করেছেন। প্রযুক্তিগতভাবে, ভিউ হোল্ডার অনবিন্দ রিটার্নের পরে সেই অবস্থানটি উপস্থাপন করে। বিটিডব্লিউ, আমরা একটি বৈধ অবস্থান (যদি সম্ভব হয়) ফিরিয়ে দেওয়ার জন্য getAdapter অবস্থান আপডেট করেছি, এমনকি যদি এটি আলাদা করা হয় তবে তা শীঘ্রই প্রকাশ করা হবে।
ইয়াজিট

আপনি ঠিক বলেছেন, আমি অনবিন্দে getAdapterPosition কল করছি। পরিবর্তে এই ক্ষেত্রে আমার কী করা উচিত, কিছু তথ্য পাওয়ার জন্য আমার অবস্থানের দরকার যা কিছু মতামতের রাজ্যগুলিকে প্রভাবিত করে। এই ক্ষেত্রে getLayoutPosition কল করা ঠিক আছে?
ওয়াজেক

4
আপনার অবস্থানের পরামিতি ব্যবহার করা উচিত যা অনবাইন্ড পদ্ধতিতে পাস করা হয়।
ইয়িগিত

2


আদেশের পার্থক্য (গুলি) তর্ক করার জন্য getAdapterPosition(), getLayoutPosition()এবংposition ; আমরা নীচের মামলাগুলি লক্ষ্য করব:

ঘ।positiononBindViewHolder() পদ্ধতিতে যুক্তি :

আমরা positionদেখার জন্য ডেটা বেঁধে রাখতে ব্যবহার positionকরতে পারি এবং এটি করার জন্য আর্গুমেন্টটি ব্যবহার করা ঠিক আছে তবে positionব্যবহারকারীর ক্লিকগুলি পরিচালনা করতে আর্গুমেন্ট ব্যবহার করা ঠিক নয় এবং আপনি যদি এটি ব্যবহার করেন তবে আপনি একটি সতর্কতা আপনাকে দেখবেন "চিকিত্সা না করতে" বলেছেposition যেমন স্থির এবং holder.getAdapterPosition()পরিবর্তে ব্যবহার করুন "।

ঘ।getAdapterPosition() :

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

ঘ।getLayoutPosition() .:

কখনও কখনও, positionআপডেট লেআউটের (ব্যবহারকারীরা এখন দেখছে এমন শেষের লেআউট) শর্তাবলী সন্ধান করা প্রয়োজন, উদাহরণস্বরূপ: যদি ব্যবহারকারী তৃতীয়টির জন্য জিজ্ঞাসা করেন positionতিনি দেখতে পারেন এবং আপনি আইটেমগুলির জন্য swipe/ ব্যবহার করতে পারেন dismissবা কোনও অ্যানিমেশন প্রয়োগ করতে পারেন বা আইটেমগুলির জন্য সজ্জা getLayoutPosition()পরিবর্তে এটি ব্যবহার করা ভাল getAdapterPosition()cause


এ সম্পর্কে আরও তথ্যের জন্য; দেখতে এখানে । । ।

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