ফোর্স লেআউট (), অনুরোধ লেআউট () ব্যবহার এবং () অবৈধ


185

আমি একটু ভূমিকা সম্পর্কে বিভ্রান্ত forceLayout(), requestLayout()এবং invalidate()পদ্ধতি Viewবর্গ।

তাদের কখন ডাকা হবে?

উত্তর:


357

ভাল দ্বারা উপলব্ধ উত্তর বোঝার জন্য ফ্রাসোয়া BOURLIEUX এবং Dalvik আমি আপনাকে পরামর্শ দিচ্ছি আপনি এই সন্ত্রস্ত দৃশ্য জীবনচক্র ডায়াগ্রাম কটাক্ষপাত করা Arpit মাথুর : এখানে চিত্র বর্ণনা লিখুন


28
আমি প্রায়শই অনুরোধটি দেখি যে অবৈধ বলা হওয়ার পরে সরাসরি কল করা হচ্ছে, আমি এমনকি টেক্সটভিউয়ের মতো জিনিসের জন্য অ্যান্ড্রয়েড সোর্স কোডে ঘটছে তা দেখতে পাচ্ছি, তবে এই চিত্র অনুসারে এটি করা নিরর্থক, তাই না? তাহলে কি সেটার কোনও উদ্দেশ্য আছে?
tcox

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

14
(১/২) : আমি মনে করি না আপনি এই দুটি পদ্ধতি ( invalidate()এবং requestLayout()) সঠিকভাবে বুঝতে পেরেছেন। এই পদ্ধতির উদ্দেশ্যটি হ'ল Viewকী ধরণের অবৈধতা (যেমন আপনি এটি বলেছেন) ঘটেছে tell আপনি যে কোনও Viewএকটি পদ্ধতির কল করার পরে কোন পথ অনুসরণ করবেন তা সিদ্ধান্ত নেওয়ার মতো নয় । View-জীবনচক্র-পথ বেছে নেওয়ার পিছনে যুক্তি হ'ল নিজেকে কল করার জন্য সঠিক পদ্ধতি নির্বাচন করা method আকার পরিবর্তনের সাথে সম্পর্কিত কিছু থাকলে - কল করা requestLayout()উচিত, যদি কোনও আকার পরিবর্তন না করে কেবলমাত্র ভিজ্যুয়াল পরিবর্তন হয় - আপনার কল করা উচিত invalidate()
বারটেক লিপিনস্কি

11
(2/2): আপনি আপনার মাপ পরিবর্তন করেন তাহলে Viewকোনো না কোনোভাবে, যেমন আপনি বর্তমান পেতেLayoutParams একটি এর Viewএবং আপনি তাদের সংশোধন করে, কিন্তু না কল পারেন requestLayoutবা setLayoutParams(যা কল requestLayoutঅভ্যন্তরীণভাবে), তারপর আপনি কল করতে পারেন invalidate()হিসাবে আপনি চান অনেক, এবং Viewপরিমাপ-বিন্যাস প্রক্রিয়ার মধ্য দিয়ে যেতে হবে না, তাই এর আকার পরিবর্তন হবে না। আপনাকে বলতে না থাকলে আপনার Viewযে এর আকার (ক সঙ্গে পরিবর্তিত হয়েছে requestLayoutপদ্ধতি কল), তারপর Viewসেটা করেন নি অনুমান করা হবে, এবং onMeasureএবং onLayoutবলা হবে না।
বারটেক লিপিনস্কি

2
এখানে @tcox -> stackoverflow.com/questions/35279374/...
Sotti

125

invalidate()

কল invalidate()করা হয় যখন আপনি দৃশ্যের একটি পুনরায় চিত্র নির্ধারণ করতে চান। এর পরিণতি onDrawঅবশেষে বলা হবে (শীঘ্রই, তবে অবিলম্বে নয়)। কোনও পাঠ্য বা পটভূমির রঙের বৈশিষ্ট্য পরিবর্তিত হলে কাস্টম ভিউ কখন এটি কল করবে তার একটি উদাহরণ।

দৃশ্যটি পুনরায় চিত্রিত হবে তবে আকার পরিবর্তন হবে না।

requestLayout()

যদি আপনার দৃষ্টিভঙ্গির কিছু পরিবর্তন হয় যা আকারকে প্রভাবিত করে, তবে আপনার কল করা উচিত requestLayout()। এই আরম্ভ হবে onMeasureএবং onLayoutপিতা বা মাতা দেখা লাইন আপ এই দৃশ্যের জন্য কিন্তু সব না শুধুমাত্র।

কলিং requestLayout()হয় একটি ইন ফলাফল নিশ্চিত নয়onDraw (যা গৃহীত উত্তরে ডায়াগ্রাম বোঝা বিপরীত), তাই এটি সাধারণত সঙ্গে মিলিত হয় invalidate()

invalidate();
requestLayout();

এর একটি উদাহরণ হ'ল যখন কোনও কাস্টম লেবেলে তার পাঠ্য সম্পত্তিটি পরিবর্তন করা হয়। লেবেলটি আকার পরিবর্তন করবে এবং তাই এটি পুনরুদ্ধার করা এবং পুনরায় চিত্রিত করা দরকার।

forceLayout()

যখন requestLayout()কোনও অভিভাবক দর্শন গোষ্ঠীতে ডাকা হয়, তখন এটির সন্তানের দৃষ্টিভঙ্গিগুলি স্মরণ করা এবং পুনরায় প্রেরণের প্রয়োজন হয় না। যাইহোক, যদি কোনও শিশুকে স্মরণ এবং রিলেআউটে অন্তর্ভুক্ত করা উচিত তবে আপনি forceLayout()সন্তানের সাথে কল করতে পারেন । forceLayout()কেবলমাত্র কোনও শিশুকে নিয়ে কাজ করে যদি requestLayout()এটির সরাসরি পিতামাতার সাথে মিলিত হয় । ভিউ ট্রি আপ আপ forceLayout()ট্রিগার না করে নিজেই কল করার কোনও প্রভাব থাকবে না requestLayout()

এর আরও বিশদ বিবরণের জন্য এই প্রশ্নোত্তরটি পড়ুন forceLayout()

আরও অধ্যয়ন


1
তবে কি প্রথমে অনুরোধটি লেলআউট () এবং তারপরে () অবৈধ করতে হবে?
স্কোল্ট

2
@ স্কোল্ট, যতদূর আমি জানি অর্ডারটির কোনও গুরুত্ব নেই, তাই আপনি চাইলে আপনি requestLayout()আগে কল invalidate()করতে পারেন। কেউই কোনও লেআউট করে না বা তাত্ক্ষণিকভাবে আঁকবে। পরিবর্তে, তারা পতাকাগুলি সেট করেছে যা পরিণামে রিলেআউট এবং পুনরায় চিত্রের ফলাফল হবে।
সুরগাচ

27

এখানে আপনি কিছু প্রতিক্রিয়া খুঁজে পেতে পারেন: http://developer.android.com/guide/topics/ui/how-android-draws.html

আমার জন্য invalidate()কেবলমাত্র দর্শনকে রিফ্রেশ করার জন্য কল requestLayout()এবং স্ক্রিনে ভিউটির আকার গণনা করার জন্য একটি কল ।


3
তাহলে ফোর্স লেআউট () কীভাবে?
sdabet

@ ফিডলার, এই পদ্ধতিটি কেবল দুটি পতাকা সেট করে: PFLAG_FORCE_LAYOUT এবং PFLAG_INVALIDATED
সুতিশী

7
@ সুটিয়ানশি তখন পতাকা স্থাপনের পরিণতি কী?
সের্গেই

1
@ সেরজেই ফলাফলটি মনে হচ্ছে যে এই পতাকাটি পরিমাপ করা ক্যাশেটিকে ওভাররাইড করে (একই মেজারস্পেকের জন্য ভবিষ্যতে দ্রুত পরিমাপ করতে দৃষ্টিভঙ্গি ক্যাশে ব্যবহার করে); এখানে View.java লাইন 18783 দেখুন: github.com/android/platform_frameworks_base/blob/master/core/...
RhetoricalRuvim

3

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


3

এই উত্তর সম্পর্কে সঠিক নয় forceLayout()

আপনি দেখতে পারেন কোডforceLayout() নিছক চিহ্ন দর্শন হিসাবে "একটি relayout প্রয়োজন" কিন্তু এটা তন্ন তন্ন সময়তালিকা কিংবা ট্রিগার যে relayout আছে। ভবিষ্যতে কোনও সময় ভিউয়ের পিতামাতার অন্য কোনও কারণে নির্ধারিত না হওয়া পর্যন্ত রিলেআউটটি ঘটবে না।

ব্যবহার করার সময় forceLayout()এবং আরও অনেক বড় সমস্যা রয়েছে requestLayout():

ধরা যাক আপনি forceLayout()একটি ভিউ শুরু করেছেন। এখন requestLayout()সেই দৃশ্যের একজন বংশধরকে ডাকার সময় অ্যান্ড্রয়েড পুনরাবৃত্তভাবে requestLayout()সেই বংশধরদের পূর্বপুরুষদের কাছে কল করবে । সমস্যাটি হ'ল এটি যে দৃশ্যে আপনি কল করেছেন তার পুনরাবৃত্তি বন্ধ করবে forceLayout()সুতরাং requestLayout()কলটি কখনই ভিউ রুটে পৌঁছে যাবে না এবং এভাবে কোনও লেআউট পাসের সময় নির্ধারণ করে না। ভিউ হায়ারার্কির একটি সম্পূর্ণ সাবট্রি একটি বিন্যাসের জন্য অপেক্ষা করছে এবং requestLayout()সেই সাবট্রিটির যে কোনও ভিউতে কল করা কোনও বিন্যাসের কারণ হবে না। কেবলমাত্র requestLayout()সেই সাবট্রির বাইরের যে কোনও দৃশ্যে কল করা স্পেলটি ভেঙে দেবে।

আমি বাস্তবায়নের বিষয়টি বিবেচনা করব forceLayout()(এবং এটি কীভাবে requestLayout()ভেঙে পড়তে প্রভাবিত করে এবং আপনার কোডটিতে কখনই এই ফাংশনটি ব্যবহার করা উচিত নয়।


1
ওহে! কীভাবে আপনি এই বানানটি নিয়ে এসেছেন ? এটা কি কোথাও নথিভুক্ত?
আজিজবিকিয়ান

1
দুর্ভাগ্যক্রমে এটি নথিভুক্ত নয় এবং সম্ভবত উদ্দেশ্যও নয়। আমি কোডটি তদন্ত করে Viewএবং নিজেই ইস্যুটি চালিয়ে এবং এটি ডিবাগ করে বুঝতে পেরেছি।
ফ্লুইডসোনিক

তারপর আমি উদ্দেশ্য সম্পর্কে কৌতুহলী forceLayout()এপিআই: এটা আসলে একটি লেআউট পাস জোর করেন না, বরং এটি শুধু একটি পতাকা পরিবর্তন যা পরিলক্ষিত হচ্ছেonMeasure() , কিন্তু onMeasure()যদি না বলা যাবে না requestLayout()বা কোনো স্পষ্ট View#measure()বলা হয়। তার অর্থ, এটি forceLayout()যুক্ত করা উচিত requestLayout()। অন্যদিকে, forceLayout()যদি আমার এখনও পারফর্ম করার দরকার হয় তবে কেন পারফর্ম করব requestLayout()?
আজিজবিকিয়ান

@azizbekian না, আপনার দরকার নেই। requestLayout()যা forceLayout()কিছু করে তা করে।
ফ্লুইডসোনিক

1
@ সুরগাচ এটিকে মিস করেছেন, ধন্যবাদ! খুব আকর্ষণীয় বিশ্লেষণ। এর উদ্দেশ্যমূলক ব্যবহারটি forceLayoutবোধগম্য হয়। সুতরাং শেষ পর্যন্ত এটি খুব খারাপভাবে নামকরণ এবং ডকুমেন্টেড।
ফ্লুইডসোনিক

0

invalidate()---> onDraw()ইউআই থ্রেড থেকে

postInvalidate()---> onDraw()ব্যাকগ্রাউন্ড থ্রেড থেকে

requestLayout()---> onMeasure()এবং onLayout()এবং অগত্যা onDraw()

  • গুরুত্বপূর্ণ : এই পদ্ধতিতে কল করা কথিত শ্রেণীর শিশুকে প্রভাবিত করে না।

forceLayout()---> onMeasure()এবং onLayout() যদি সরাসরি অভিভাবককে ফোন করা হয় requestLayout()

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