PDA

View Full Version : دستور "ری‌پلیس" در فرگمنت، و سفید شدن صفحه



sco1385
دوشنبه 05 خرداد 1393, 17:11 عصر
من این دستور ری‌پلیس یک فرگمنت، یعنی رفتن از یک فرگمنت به فرگمنت دیگر را، در فایل جاوای یک فرگمنت قرار دادم.



ImageView myImageView = (ImageView) rootView.findViewById(R.id.imageView1);

myImageView.setOnClickListener(new View.OnClickListener() {


@Override
public void onClick(View v) {

FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction t = fragmentManager.beginTransaction();
Fragment myFragment = new Ensan();
t.replace(R.id.ViewPager_PlaceHolder, myFragment);
// t.addToBackStack(null);
t.commit();
//break;
//}


}


});


حال وقتی که روی تصویر کلیک می‌کنم. در کلیک اول عکس‌العملی نشان نمی‌دهد. اما در کلیک دوم، صفحه سفید می‌شود. و البته در همان فرگمنت مبداء می‌ماند و اصلاً به فرگمنت مقصد هم نمی‌رود.

کجای کد من اشکال دارد.

این فرگمنت، فهرستِ اپ من است، که از آنجا باید کاربران به فرگمنت‌های دیگر هدایت شوند.

این هم کد کل فرگمنت:



import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;


public class Fehrest_First extends Fragment {


// Every fragment must have a default empty constructor.
public Fehrest_First(){}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

// Get the view from fehrest_first.xml
View rootView = inflater.inflate(R.layout.fehrest_first, container, false);

// در حالت پُرتریت نگاه داشتن صفحه
getActivity().setRequestedOrientation(ActivityInfo .SCREEN_ORIENTATION_PORTRAIT);
---
---
---
---
---
return rootView;

}// end of on create.
}



لطفاً راهنمایی کنید.

sco1385
سه شنبه 06 خرداد 1393, 21:00 عصر
استادان گرامی

در بخش فهرست متوقف شدم.

دستور آن‌کلیک را در مین‌اکتیویتی قرار دادم، و از پراپرتی آن‌کلیکِ وجت استفاده کردم، این مشکل وجود دارد.

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

لطفاً راهنمایی کنید تا یک قدم به جلو بروم.

سالگرد شریعتی نزدیک است، و دوست دارم این برنامه تا آن زمان، منتشر شود.

متشکرم

shahin bahari
سه شنبه 06 خرداد 1393, 21:44 عصر
سلام
خیلی بعید میدونم بشه از داخل فرگمنت دستور تعویض فرگمنت رو داد!!!
این تغییر باید از داخل خود اکتیویتی صورت بگیره!
یه interface باید نوشت که وقتی دکمه داخل فرگمنت فشار داده شد, listener اون که داخل اکتیویتی هست فرگمنت رو replace کنه.
کلا اگه پروژه عقب هست و میخواید سریع انجام شه به جای تغییر فرگمنت و این حرف ها اکتیویتی رو عوض کنید. (گرچه فرگمنت رو یاد بگیرید میبینید خیلی ساده هست)

sco1385
سه شنبه 06 خرداد 1393, 23:48 عصر
من به خوبی فرگمنت ها رو خوندم.

تمامی مقالات موجود به زبان انگلیسی و فارسی رو خوندم.

الان هم برنامه ای رو ساختم که از داخل یک فرگمنت فرگمنت دیگری را فراخوانی کنه.

البته درست است که فرگمنت ها با هم ارتباط ندارند، و کانال ارتباطی آنان اکتیویتی والد است.

و در این رابطه مثلاً از دستور اینتنت نمی‌شود استفاده کرد، و از داخل یک فرگمنت، به فرگمنت دیگر و یا اکتیوتی دیگر رفت.

اما از داخل یک فرگمنت با استفاده از فرگمنت منیجر، ترنس‌زکشن و دستور ری‌پلیس، و آن هم حتماً از طریق دستور آن‌کلیک لیسینر، و دستورات نوشته شده در درون دستور آن‌کلیکِ لیسنر مربوطه، به فرگمنت دیگر رفت.

اما اگر بخواهیم صرفاً از دستور آن‌کلیک و وارد کردن دستور کلیک در بخش پراپرتی فایل اکس ام ال استفاده کنیم، باید دستور آن‌کلیک را همانطور که شما گفتید، در داخل اکتیویتی والد نوشت.

من از هر دو روش در برنامه دیگر کانون استفاده کردم و الان برنامه موجود است. اما به طور عجیبی همان دستور در این برنامه من با مشکل عمل می‌کند. البته اون برنامه از دراور استفاده می‌کند، و این برنامه من از تب استرایپ.

متاسفانه من نتوانستم مقاله‌ای را بیابم که طبق دستور شما یک اینترفیس بتوانم بسازم. روش درست و مطمئن همان است که شما فرمودید و آن ساختن اینترفیس است. اما متاسفانه علی‌رغم تلاش بیسار در سرج تمام سایت‌های اندروید، آموزشی پیدا نکردم. و زبان جاوا را هم تنها در حدی که احتیاجات مقدماتی اندروید را برطرف کند می‌شناسم.

ممنون

sco1385
سه شنبه 06 خرداد 1393, 23:57 عصر
The general rule for events generated by a view in a fragment is that:

· if the event listener was declared in the "fragment class", using the event listener and callback method approach, then the event will be handled first by the fragment.

· If the android:onClick resource is used, however, the event will be passed directly to the activity containing the fragment.

shahin bahari
چهارشنبه 07 خرداد 1393, 00:34 صبح
راستش تا حالا این که از داخل فرگمنت میشه فرگمنت جاری رو عوض کرد یا نه رو امتحان نکردم ولی مطمئن هستم از دااخل اکتیویتی بدون مشکل میشه تغییر داد.
درمورد Intent هم میشه برای فراخوانی و مقدار اولیه دادن به فرگمنت استفاده کرد و محدودیتی نیست ( گرچه خود من از یه چی شبیه Constructor استفاده میکنم . خود Constructor فرگمنت رو نمیشه تغییر داد!)
برسیم به قضیه ی اینترفیس. شما این کد رو توی فرگمنت اضافه کنید:
public class TestFragment extends Fragment{

private changeRequest event;

public interface changeRequest{
abstract void onRequest();
}



@Override
public void onAttach(Activity activity) {
try{
event=(changeRequest) activity;
}catch(Exception e){
throw new ClassCastException("you must implements \"change request\" in your activity");
}
super.onAttach(activity);
}
}
حالا توی رویداد دکمه مینویسید:
event.onRequest();

کارمون تو قسمت فرگمنت تموم شد. توی اکتیویتی اولش که کلاس رو از اکتیویتی مشتق کرده اضافه میکنیم:
implements changeRequest
بعد از اضافه کردن این خط روی اسم کلاس یه اروری ایجاد میشه که اگه روش وایسید یه پنجره باز میشه و گزینه add unimplemented methods رو میزنید. خودش یه تابع به کلاس اضافه میکنه و جایی هست که دستور تغییر فرگمنت یا هر چیز دیگه رو میتونید بنویسید.

sco1385
چهارشنبه 07 خرداد 1393, 01:16 صبح
حالا توی رویداد دکمه مینویسید:
event.onRequest();


منظورتان در فایل اکس ام ال در قسمت پراپرتی یک وجت است؟

یا اینکه یک متد آن‌کلیک بگذارم و این دستور را در آن فرار بدم؟

sco1385
چهارشنبه 07 خرداد 1393, 01:24 صبح
کل کلاسی که گذاشتید را در فرگمنت قرار بدم؟. حتی خط اول که اکستند می‌کند؟

در کجا قرار بدم؟ در داخل متد oncreate یا در خارج آن؟

شرمنده از این همه سوال

sco1385
چهارشنبه 07 خرداد 1393, 01:40 صبح
روی "تکست فرگمنت" TestFragment، این ارور رو میده:



Illegal modifier for the local class TestFragment; only abstract or final is permitted


و روی changeRequest این ارور رو میده:



changeRequest cannot be resolved to a type
و
The member interface changeRequest can only be defined inside a top-level class or interface

rubiks.kde
چهارشنبه 07 خرداد 1393, 14:24 عصر
شی FragmentTransaction رو به صورت final تعریف کنید و ببیند به خاطر اسکوپ نباشه.

sco1385
چهارشنبه 07 خرداد 1393, 15:26 عصر
امتحان کردم و فرقی نکرد و مشکل هم‌چنان برقرار است.

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

وقتی بر روی لینک کلیک می‌کنم، در بار اول عکس‌العملی نشان نمی‌دهد، و همیشه در کلیک دوم است که عمل کرده و صفحه سفید می‌آید!

shahin bahari
پنج شنبه 08 خرداد 1393, 01:28 صبح
منظورتان در فایل اکس ام ال در قسمت پراپرتی یک وجت است؟

یا اینکه یک متد آن‌کلیک بگذارم و این دستور را در آن فرار بدم؟
توی فایل جاوای فرگمنت وتوی رویداد دکمه.


کل کلاسی که گذاشتید را در فرگمنت قرار بدم؟. حتی خط اول که اکستند می‌کند؟

در کجا قرار بدم؟ در داخل متد oncreate یا در خارج آن؟
نه این شکل کلی کلاس فرگمنت بود! onCreate و OnAttach 2 تا از متد های این کلاس هستند. دیگه من onCreate و onCreateView و این حرف ها رو فرض کردم که خودتون مینویسید....

sco1385
پنج شنبه 08 خرداد 1393, 13:19 عصر
الان این کد که در داخل فرگمنت دادم درست است.



import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.TextView;


public class TestFragment extends Fragment{

private changeRequest event;

// Every fragment must have a default empty constructor.
public TestFragment(){}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

// Get the view from ensan.xml
View rootView = inflater.inflate(R.layout.testfragment, container, false);

TextView myTextView = (TextView) rootView.findViewById(R.id.textView1);


myTextView.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
event.onRequest();
}
});

return rootView;


}// end of on create.


public interface changeRequest{
abstract void onRequest();
}



@Override
public void onAttach(Activity activity) {
try{
event=(changeRequest) activity;
}catch(Exception e){
throw new ClassCastException("you must implements \"change request\" in your activity");
}
super.onAttach(activity);
}

}

shahin bahari
پنج شنبه 08 خرداد 1393, 18:20 عصر
درسته.
حالا فقط کافیه اون اکتیویتی که فرگمنت رو میسازه implements changeRequest کنید.

sco1385
پنج شنبه 08 خرداد 1393, 18:59 عصر
خب. مین اکتیویتی را ایمپله‌منت کردم.

یک ایمپورت تقاضا کرد، و یکی هم
add unimplemented methods که انجام دادم و اخطاری هم نیست.

حالا وقتی روی متن کلیک می‌کنم، کلیک عمل می‌کند، اما متاسفانه باز در همان صفحه می‌ماند و صفحه اول محو شده و صفحه سفید و خالی میاید. مثل قبل.

ببینید در دستور کلیک من اشکالی نیست؟

دستوری که در داخل بلاک کلیک "فرگمنت" نوشتم:






TextView myTextView = (TextView) rootView.findViewById(R.id.textView1);


myTextView.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
event.onRequest();

switch (v.getId()) {
case R.id.textView1:



FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
final FragmentTransaction t = fragmentManager.beginTransaction();
Fragment myFragment = new Azadi();
t.replace(R.id.ViewPager_PlaceHolder, myFragment);
// t.addToBackStack(null);
t.commit();
break;
}

}
});



اگر دستور ایراد نداشته باشد. دیگر راهی ندارد جز این که خودم را بیاندازم توی حوض!!

راهنمایی لطفاً / این آخرین مرحله کار است، یعنی فهرست برنامه را درست کنم تا کاربر با کلیک روی آیتم‌های آن، به فرگمنت‌های دیگر برود.

shahin bahari
جمعه 09 خرداد 1393, 01:06 صبح
دستوری که در داخل بلاک کلیک "فرگمنت" نوشتم:








خوب قرار شد که وقتی کلیک میشه یه رویداد رو به اکتیویتی بفرسته و اکتیویتی عوض کردن فرگمنت رو انجام بده. این یعنی نیازی نیست که شما داخل رویداد دکمه دستورات عوض شدن فرگمنت رو قرار بدید و دستور event.onRequest(); داخلش باشه کافیه!
این دستورات تغییر فرگمنت رو به داخل اون متدی که داخل اکتیویتی براتون ساخته انتقال بدید!

sco1385
جمعه 09 خرداد 1393, 03:45 صبح
من متوجه ایجاد متد آن‌ریکوپست در اکتیویتی نشده بودم.

الان کاملا متوجه شیوه کار شدم.

فقط سوال این که: من خواستم در دستور آن‌ریکوپست در اکتیویتی یک دستور سوپیچ قرار بدم، با این صورت:



@Override
public void onRequest() {

switch (v.getId()) {
case R.id.textView1:


FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction t = fragmentManager.beginTransaction();
Fragment myFragment = new Azadi();
t.replace(R.id.ViewPager_PlaceHolder, myFragment);
t.addToBackStack(null);
t.commit();
break;
}
}



اما در قسمت v.getId روی v اخطار می‌دهد ، که گویا باید یک متغیر تعریف کرد.

اصلاْ این دستورات درست است؟
اخطار v را چگونه حل کنم؟
ممنون

shahin bahari
جمعه 09 خرداد 1393, 20:31 عصر
سوییچ برای چی هست؟! این یه رویداد مستقیم هست و داخلش نیازی به تصمیم گیری نیست! حذف کنید اون قسمت سوییچ رو کلا!

sco1385
جمعه 09 خرداد 1393, 21:34 عصر
الان در فرگمنت من ده تا تکست‌ویو است که باید به آنها دستور کلیک اضافه کنم، در این صورت تکلیف چیست؟

shahin bahari
شنبه 10 خرداد 1393, 00:40 صبح
آها! خوب زود تر میگفتید.
کافیه به رویدادمون یه آرگومان اضافه کنیم! یعنی جایی که تو فرگمنت interface رو نوشتید این شکلی بشه:
public interface changeRequest{
abstract void onRequest(int i);
}

بعد توی رویداد هر کلید یه عدد خاص میزارید. مثلا برای کلید 0:
event.onRequest(0);
برای کلید 1:
event.onRequest(1);
الی آخر.....

حالا توی اکتیویتی یه سوییچ بزارید که اگه مقدار i برابر 0 بود بره فرگمنت 0 اگه 1 بود بره فرگمنت 1 الی آخر....

sco1385
شنبه 10 خرداد 1393, 01:19 صبح
آیا در فرگمنت باید برای هر تکست‌ویو یک دستور کلیک لیسنر جدا بنویسم؟ و در داخلش یک event.onRequest(); بگذارم، و یک شماره هم بهش بدم؟ درست فهمیدم؟

sco1385
شنبه 10 خرداد 1393, 01:28 صبح
من الان این کد را در مین اکتیویتی قرار دادم



// اینترفیس برای مدیریت کلیک فرگمنت
@Override
public void onRequest(int i) {

switch (i) {

case 1:
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction t = fragmentManager.beginTransaction();
Fragment myFragment = new Ensan();
t.replace(R.id.ViewPager_PlaceHolder, myFragment);
t.addToBackStack(null);
t.commit();
break;

case 2:
Intent myIntent_Kanoun1 = new Intent(Intent.ACTION_VIEW, Uri.parse("http://talar.shandel.info"));
startActivity(myIntent_Kanoun1);
break;

}
}


اولی که قرار است به یک فرگمنت دیگر برود درست عمل نمی کند.

اما دومی مرورگر را باز می‌کند و به سایت مربوطه می‌رود.

سفید شدن صفحه به این دستور شما ربطی ندارد.

برنامه من باید مشکلی داشته باشد.

الان کد من درست است

ممنون

sco1385
شنبه 10 خرداد 1393, 02:14 صبح
سوال بعدی اینکه :

الان اگر بخواهم از یک فرگمنت دیگر هم، یک ایونت ری‌کوپست رو بفرستم، چه تغییراتی را باید ایجاد کرد؟

من الان در اون فرگمنت جدید، یک لیسینر ایجاد کردم، و یک ایونت داخلش گذاشتم، و به ایونتش مثلاْ شماره یازده رو دادم.

آیا می‌توان در اکتیویتی، در همان سوپیج قبلی، یک کیس ایجاد کنم، و به کیس عدد یازده رو بدم، و دستورات را در اون کیس بنویسم؟

ممنون

shahin bahari
شنبه 10 خرداد 1393, 19:31 عصر
بله میشه. توی فرگمنت اون قسمت onAttach رو بنویسید + private changeRequest event;

sco1385
یک شنبه 11 خرداد 1393, 21:22 عصر
من یکی از اکتیوتی‌های پیش‌گزینه اندروید به نام actionbar taps with viewpager را انتخاب کردم، که هنگام ساخت اکتیویتی پیشنهاد می‌شود.

و تمام دستورات مربوط به اینترفیس را روی آن انجام دادم.

متاسفانه مثل پروژه‌ی قبلی باز هم صفحه سفید می‌شود و صفحه به فرگمنت جدید منتقل نمی‌شود.

فکر کنم بهتر است پروژه را بفرستم تا شاید دوستان درستش کنند.

ممنون

sco1385
دوشنبه 12 خرداد 1393, 03:17 صبح
دوستان عزیز

یک پروژه نمونه از مشکلی که دارم، در اینجا قرار می‌دهم. که از اینترفیس استفاده شده است. یک لینک به سایت می‌رود، که درست عمل می‌کند، ولی لینک دیگر، که باید به فرگمنت دیگر برود، به فرگمنت دیگر نمی‌رود، و فقط صفحه سفید می‌شود.

لطفاً ببینید ایراد کار کجاست.

ممنون از لطفتان

فایل را از آدرس زیر دریافت نمائید : 2.1 مگابایت

http://jmp.sh/KPbrOH4

یادتان باشد که پروژه از appcompat_v7 استفاده می‌کند.

ای پی آی 19

تارگت 4.4.2

مینیمم ای پی آی 11

زنده باشید