বিড়ম্বনা: উইজেট বিল্ডে রান পদ্ধতিটি সম্পূর্ণ


122

উইজেটের বিল্ডিং / লোডিং শেষ হয়ে গেলে আমি ফাংশনগুলি চালাতে সক্ষম হতে চাই তবে কীভাবে তা সম্পর্কে আমি নিশ্চিত নই। আমার বর্তমান ব্যবহারের ক্ষেত্রে কোনও ব্যবহারকারী প্রমাণিত হয়েছে কিনা তা যাচাই করা এবং যদি তা না হয় তবে লগইন দৃশ্যে পুনর্নির্দেশ করুন। আমি আগে যাচাই বাছাই করতে চাই না এবং লগইন ভিউ বা মূল দৃশ্যের দিকে চাপ দিতে চাই না, মূল ভিউ লোড হওয়ার পরে এটি হওয়া দরকার। আমি এটি করতে কিছু ব্যবহার করতে পারি?


আপনি লগইন প্রক্রিয়াটি শুরু করতে চান এটি অসম্ভব build। বিল্ডকে যে কোনও সময় একাধিকবার কল করা যেতে পারে।
গন্টার জ্যাচবাউয়ার 15 '45

উত্তর:


181

আপনি ব্যবহার করতে পারেন

https://github.com/slightfoot/flutter_ after_layout

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

মূলত যা

  void initState() {
    super.initState();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => yourFunction(context));
  }

ধন্যবাদ থমাস আপনার উত্তরগুলি আমার জন্য খুব সহায়ক। আমি এটি নিয়ে দু'দিন আগে কাজ করেছি এবং এখন তারা এবং আপনার উত্তরগুলি পড়ার পরে। আবার আপনাকে ধন্যবাদ খুব ভাল কাজ
রবীন্দ্র ভান্ডারী

6
@ Anmol.majhail উত্তর দেখুন: WidgetsBinding.instance.addPostFrameCallback((_) => yourFunciton(context));আর কাজ করছে না
পাবলো ইনসুয়া

হাই @ থমাস, এটি আমার পক্ষে কাজ করছে না। এখনও নাল ব্যতিক্রম পেতে। কোন ধারণা ?
zukijuki

4
@ অ্যানিক্স্যাসকার্ডার: এটি আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে। অনেক সময় আপনার এটিকে অন্য initStateযেমন কল করা উচিত , যেমন। মধ্যে build
গিরালদী

4
এটি কার্যকর করার জন্য আপনার পদ্ধতির setStateমধ্যে কল করা উচিতyourFunction
পার্স করুন

89

আপডেট: বিড়ম্বনা v1.8.4

উল্লিখিত উভয় কোডই এখন কাজ করছে:

কাজ:

WidgetsBinding.instance
        .addPostFrameCallback((_) => yourFunction(context));

কাজ করা

import 'package:flutter/scheduler.dart';

SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));

4
দ্বিতীয়টি আর কাজ করে না। NoSuchMethodError (NoSuchMethodError: The method 'addPostFrameCallback' was called on null. Receiver: null
অলিভার ডিকসন

4
@ এলিয়াউইস - এটি আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে - বিল্ডের পরে উইজেটগুলিতে কোনও ফাংশন কল করার এটি কেবল একটি উপায়। সাধারণ ব্যবহারটি init ()
anmol.majhail

20

সম্ভাব্য তিনটি উপায় রয়েছে:

1) WidgetsBinding.instance.addPostFrameCallback((_) => yourFunc(context));

2) Future.delayed(Duration.zero, () => yourFunc(context));

3) Timer.run(() => yourFunc(context));

হিসাবে হিসাবে context, আমার Scaffold.of(context)সমস্ত উইজেটগুলি রেন্ডার হওয়ার পরে এটির জন্য আমার প্রয়োজন ছিল needed

তবে আমার নম্র মতে এটি করার সর্বোত্তম উপায় হ'ল:

void main() async {
  WidgetsFlutterBinding.ensureInitialized(); //all widgets are rendered here
  await yourFunc();
  runApp( MyApp() );
}

13

পিচুনি 1.2 - ডার্ট 2.2

সরকারী নির্দেশিকা এবং সূত্র অনুসারে আপনি যদি নিশ্চিত হতে চান যে আপনার লেআউটের শেষ ফ্রেমটিও আঁকানো হয়েছিল তবে উদাহরণস্বরূপ লিখতে পারেন:

import 'package:flutter/scheduler.dart';

void initState() {
   super.initState();
   if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) {
        SchedulerBinding.instance.addPostFrameCallback((_) => yourFunction(context));
   }
}

আমার জন্য এই কাজ করে নি, কারণ initState () সময়ে আমি schedulerPhase পেতে SchedulerPhase.idle মান ... কি এটা আসলে কাজ বিল্ড মধ্যে যে চেক () যোগ করার জন্য ছিল
Alessio

11

আপনি যদি রিঅ্যাক্টনেটিভের componentDidMountসমতুল্য সন্ধান করছেন, তোড়জোড় এটি আছে। এটি এত সহজ নয় তবে এটি একই পদ্ধতিতে কাজ করছে। ঝাঁকুনিতে এসগুলি Widgetতাদের ইভেন্টগুলি সরাসরি পরিচালনা করে না। পরিবর্তে তারা তাদের Stateবস্তুটি এটি করতে ব্যবহার করে ।

class MyWidget extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => MyState(this);

  Widget build(BuildContext context){...} //build layout here

  void onLoad(BuildContext context){...} //callback when layout build done
}

class MyState extends State<MyWidget>{

  MyWidget widget;

  MyState(this.widget);

  @override
  Widget build(BuildContext context) => widget.build(context);

  @override
  void initState() => widget.onLoad(context);
}

State.initStateঅবিলম্বে একবারে স্ক্রিনটি ডাকা হবে যখন লেআউটটির রেন্ডারিং শেষ হয়েছে। আপনি ডিবাগ মোডে থাকাকালীন আর পুনরায় গরম পুনরায় লোড করা হবে না, যতক্ষণ না স্পষ্টভাবে এটি করার সময় না পৌঁছায়।


আমার উদাহরণ থেকে, আপনি StatefulWidgetক্লাসটি এটির Stateমতো একটি বিষয়টিকে পরিচালনা করতে ক্লাস ব্যবহার করতে পারেন StatelessWidgetতবে আমি এটির সুপারিশ করছি না। আমি এখনও কোনও সমস্যা পাইনি তবে অনুগ্রহ করে Stateপ্রথমে বস্তুর ভিতরে সমস্ত কিছু প্রয়োগ করার চেষ্টা করুন
jerinho.com

4
flutter.dev/docs/cookbook/networking/fetch-data গুগল initState () এ ডেটা আনার জন্য কল করার পরামর্শ দেয়। অতএব এই সমাধানটি নিয়ে কোনও সমস্যা নেই, আসলে এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
বিকাশকারী

প্রতিক্রিয়াতে নেটিভ componentWillMountউপস্থাপনের ঠিক আগে নেটিভ ডেটা আনার কাজ করা যেতে পারে । ঝাঁকুনি সহজ সমাধান সরবরাহ করে। initStateডেটা আনার জন্য এবং লেআউটে রেন্ডার উভয়ের জন্যই যথেষ্ট, যদি আমরা এটি সঠিকভাবে কীভাবে করতে হয় তা জানতে পারি
jerinho.com

4
উপাদান শীঘ্রই শীঘ্রই হ্রাস করা হবে component সুতরাং উপাদানটি মাউন্ট এবং নির্মাণের পরে আনার কাজ করা হবে।
বিকাশকারী

8

বিড়বিড় সংস্করণে 1.14.6, ডার্ট সংস্করণ 28।

নীচে আমার জন্য যা কাজ করেছে তা হল, বিল্ড পদ্ধতির পরে আপনি যা করতে চান তা কেবল একটি পৃথক পদ্ধতি বা ফাংশনে রূপান্তর করতে আপনার কেবল প্রয়োজন।

@override
void initState() {
super.initState();
print('hello girl');

WidgetsBinding.instance
    .addPostFrameCallback((_) => afterLayoutWidgetBuild());

}

3

সময়সূচীর বাইন্ডিং চেষ্টা করুন,

 SchedulerBinding.instance
                .addPostFrameCallback((_) => setState(() {
              isDataFetched = true;
            }));

1

এটি করার সর্বোত্তম উপায়,

1. উইজেটস বাইন্ডিং

WidgetsBinding.instance.addPostFrameCallback((_) {
      print("WidgetsBinding");
    });

2. উইজেটস বাইন্ডিং

SchedulerBinding.instance.addPostFrameCallback((_) {
  print("SchedulerBinding");
});

এটি ভিতরে কল করা যেতে পারে initState, দু'জনেই কেবল একবার রেন্ডারিংয়ের মাধ্যমে বিল্ড উইজেট পরে ডাকা হবে।

@override
  void initState() {
    // TODO: implement initState
    super.initState();
    print("initState");
    WidgetsBinding.instance.addPostFrameCallback((_) {
      print("WidgetsBinding");
    });
    SchedulerBinding.instance.addPostFrameCallback((_) {
      print("SchedulerBinding");
    });
  }

উপরের উভয় কোড একইরকম কাজ করবে যেহেতু উভয় একই ধরণের বাঁধাই কাঠামো ব্যবহার করে। পার্থক্যের জন্য নীচের লিঙ্কটি সন্ধান করুন।

https://medium.com/flutterworld/flutter-schedulerbinding-vs-widgetsbinding-149c71cb607f


0

আপনি যদি এটি একবারই করতে চান, তবে এটি করুন কারণ ফ্রেমওয়ার্কটি initState()প্রতিটি স্টেট অবজেক্ট তৈরির জন্য পদ্ধতিটিকে একবার কল করবে ।

 @override
  void initState() {
    super.initState();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => executeAfterBuildComplete(context));
  }

আপনি যদি বার বার এটি করতে চান বা পিছনে পছন্দ করতে চান বা পরবর্তী স্ক্রিনে নেভিগেট করতে চান ইত্যাদি ইত্যাদি, তবে এটি করুন কারণ didChangeDependencies()যখন এই রাজ্যের অবজেক্টের নির্ভরতা বদলে যায় তখনই ডাকা হয়।

উদাহরণস্বরূপ, যদি পূর্ববর্তী কলটি পরে পরিবর্তিত buildকোনও রেফারেন্স করতে থাকে InheritedWidgetতবে ফ্রেমওয়ার্কটি এই অবজেক্টটি পরিবর্তনের বিষয়ে অবহিত করার জন্য এই পদ্ধতিটিকে কল করবে।

এই পদ্ধতিটি সঙ্গে সঙ্গে বলা হয় initStateBuildContext.dependOnInheritedWidgetOfExactTypeএই পদ্ধতি থেকে কল করা নিরাপদ ।

 @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => executeAfterBuildComplete(context));
  }

এটি আপনার কলব্যাক ফাংশন

executeAfterBuildComplete([BuildContext context]){
    print("Build Process Complete");
  }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.