تابستون داره تموم میشه ها، فرصت‌ها محدودن کلی آفر جذاب در کمپین تابستون🔥👇
۰ ثانیه
۰ دقیقه
۰ ساعت
۵ farshid barati
onAttache
جامعه جاوا (اندروید) ایجاد شده در ۰۷ بهمن ۱۳۹۸

سلام وقت بخیر.

استاد من متوجه نشدم چرا باید 

eventListener= (MyDialogEventListener) context;

مساوی هم کرد داخل onAttach ایا داخل متود دیگه ای نمیشه و اینکه چرا باید مساوی باشن

؟!

سلام 

یه نمونه از MyDialogEventListener به نام eventListener ایجاد کردیم 

حالا باید مقداری که از MainActivity گرفته رو داخلش قرار بدیم اینجاcontextهمون contextی هست که در MainAvtivity وجود داره  حالا  این نمونه ای (eventListener)که ایجاد کردیم را با casting کردن context از نوع MyDialogEventListener مقدار دهی میکنیم که اگر onOkButtonClickedوcancelButtonClicked صدا زده شده شوند ورودیشون خالی(null) نباشه البتهcancelButtonClicked خودش هیچ مقداری به عنوان ورودی نداره 

eventListener.onOkButtonClicked(editText.getText().toString());

اگر اینکار رو نکنیم خطای null pointer مثل 

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.dialogfragment, PID: 31876
    java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.dialogfragment.MyDialog$MyDialogEventListener.onOkButtonClicked(java.lang.String)' on a null object reference
        at com.example.dialogfragment.MyDialog$1.onClick(MyDialog.java:43)
        at android.view.View.performClick(View.java:7125)
        at android.view.View.performClickInternal(View.java:7102)
        at android.view.View.access$3500(View.java:801)
        at android.view.View$PerformClick.run(View.java:27336)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

رو به رو میشیم 

اما آیا جای دیگه ای نمیشه مقدار دهیش کرد؟

بله میشه مثلا بالای همون 

eventListener.onOkButtonClicked(editText.getText().toString());

میشه نوشت 

eventListener=(MyDialogEventListener) getContext();

اما قطعا بهتره در همون onAttach که ActivityوFragmentرو به هم متصل میکنه ویه جورایی حکم همون سازنده رو داره اینکارو انجام بدیم 

این فهم من بود انشاالله مفید بوده باشه 

سید شهریار انباز ۱۰ بهمن ۱۳۹۸، ۱۶:۱۴

اینو منم پاسخ بدم، شاید بقیه هم واسشون گنگ باشه که context از کجا اومد!!

خود من قبل اینکه استاد حل کنه، فیلمو استوپ کردم و به روش دیگه نوشتم.

یعنی در کلاس MyDialog یک سازنده ساختم و از متد onAttach استفاده نکردم، الزامی هم به استفاده اش نیست:

private OkClickListener okClickListener;
public MyDialog(OkClickListener okClickListener) {
    this.okClickListener = okClickListener;
}

و در MainActivity:

btnShowDialog.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
	    MyDialog myDialog = new MyDialog(new MyDialog.OkClickListener() {
	        @Override
	        public void onClick(String text) {
	            tvShow.setText(text);
	        }
	        @Override
	        public void onCanselClick() {
	            tvShow.setText("Cansel is Clicked!");
	        }
	    });
	    myDialog.show(getSupportFragmentManager(), null);
	}
});

btnShow همون باتنیه که داخل لیوت اکتیویتی هست.

اما جریان context اینه، چون متدها داخل خود MainActivity بازنویسی شدن، بنابراین مثل این میمونه که بگیم داخل context هم (که والد MainActivity هست) نوشته شدن، بنابراین وقتی:

eventListener= (MyDialogEventListener) context;

یا میشد به این شکل نوشت:

eventListener= (MyDialogEventListener) getActivity();

حتی میشد داخل متدهای دیگه(مثه onCreateDialog و ...) اما قبل از عملیات کلیک اونو مقدار دهی کرد، یا اصلا در خط معرفی پراپرتی از getContext() یا getActivity() استفاده کنیم و ...

محسن موحد ۲۲ اسفند ۱۳۹۸، ۲۰:۳۷

سلام دوستان نمی‌دونم چرا این مورد این شکلی پیچیده شده یه متدی هست با نام getActivity() که شما تو هر فرگمنتی فراخوانی بکنی به اون اکتیویتی که فرگمنت توش نمایش داده می‌شه دسترسی داشته باشید و با findViweById می‌تونید به هر ویویی تو اکتیویتی main دسترسی داشته باشید و هر مقداری بخواهید از EditText‌موجود تو فرگمنت دریافت و در ویوی مورد نظر که از اکتیویتی Main فایند کردید ست کنید و یه مورد دیگه این که برای حالت onCancel این متد به صورت پشفرض برای فرگمنت تعریف شده هست و اصلا لازم نیست ما دوباره اون رو ایجاد کنیم کافی هست که ما اون متد رو فراخوانی کنیم. نمی‌دونم چقدر درست بود قضاوتش با استاد شاهینی و رفقا 

سالار غیور کلیبر ۱۴ فروردین ۱۳۹۹، ۱۲:۴۱

درود

من با نظر آقا سالار هم عقیده هستم چرا باید روش پیچیده‌تر رو انتخاب کرد؟  

مثلا : استفاده از کد زیر بجای پیاده سازی اینترفیس  مشکلش چیه؟

 

okBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (editText.length() > 0) {
                    View view1 = LayoutInflater.from(getContext()).inflate(R.layout.activity_main, null, false);
                    TextView textView = view1.findViewById(R.id.tv_main);
                    textView.setText(editText.getText().toString());
                    dismiss();
                }
            }
        });
پژمان آزاد ۰۶ مرداد ۱۳۹۹، ۲۱:۴۰

سلام دوست عزیز

شما میتونید که بجای استفاده از method onAttach() از کانستراکتور هم استفاده کنید و از طرفی هم باید مثل آموزش استاد Activity رو impelement کنید ولی باید در خود کانستراکتور نیز eventListener رو برابر با contex کنید و عمل cast کردن هم انجام بدین

Reza Ahmadzadeh ۲۵ مرداد ۱۳۹۹، ۱۹:۳۷