۱۳۹۴/۱۱/۱۶, ۰۶:۲۹ ب.ظ
آموزش پیاده سازی الگوی Fragment communication
Fragment Communication Design Pattern
یا
Inter-Fragment Communication
در ارتباط با استفاده از fragmentها و نحوه انتقال اطلاعات بین انها و ذخیره اطلاعات در طول چرخه حیات Fragment ، مبحث پیاده سازی الگوی Fragment Communication هستش
برای اموزش این الگو از یک سناریو انتقال اطلاعات از FragmentA به FragmentB استفاده شده . که FragmentA میاد تعداد کلیک شده بر روی یک Button رو به سمت FragmentB جهت پردازش ( نمایش در TextView) ارسال میکنه
ابتدا یک توضیح کلی در مورد نحوه عملکرد این روش بگم که در این روش میایم با ساخت و پیاده سازی یک Interface اقدام به تبادل اطلاعات میکنیم به این صورت که MainActivity میاد و Interface ساخته شده رو پیاده سازی میکنه و FragmentA با استفاده از این پیاده سازی اقدام به ارسال داده به سمت MainActivity میکنه و MainActivity هم داده مورد نظر رو به سمت FragmentB اسال میکنه.
برای این کار ابتدا یک Interface طرای میکنیم و اسمش رو FragmentCommunication میزاریم ( اسم دلخواه هستش)
کد:
public interface FragmentCommunication {
public void Response(String data);
}
برای این اموزش ما از یک متد ساده ارسال داده از نوع String استفاده کردیم
شما میتونید با توجه به برنامه خودتون متدهای بیشتری رو بهش اضافه کنید
حال دوتا Fragment به نام های FragmentA و FragmentB می سازیم به صورت زیر
کد:
public class FragmentA extends Fragment implements View.OnClickListener {
FragmentCommunication fragmentCommunication;
int counter = 0;
Button btnclick;
public FragmentA() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null){
counter = 0;
} else {
counter = savedInstanceState.getInt("counter");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_a, container, false);
btnclick = (Button) view.findViewById(R.id.btnclick);
btnclick.setOnClickListener(this);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
fragmentCommunication = (FragmentCommunication) getActivity();
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btnclick) {
counter++;
fragmentCommunication.Response("You Click " + counter + " Times");
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("counter",counter);
}
@Override
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
}
}
حالا یک نمونه سازی از Interface FragmentCommunication میسازیم که با استفاده از تابع OnActivityCreated این نمونه رو از MainActivity یا تابع getActivity دریافت میکنیم
تابع OnActivityCreated در چرخه حیات Fragment زمانی رخ میده که Activity والد و خود fragment به صورت کامل ایجاد شده و قابل دسترسی باشن.
تابع OnClick یه پیاده سازی از View.OnClickLinstener هستش که برای کلید Button پیاده سازی شده.
وقتی که بر روی Button کلیک میشه میایم و با استفاده از fragmentCommunication نمونه سازی شده تایع تعریف شده در Interface مربوطه رو صدا میزینم که قبلا توسط MainActivity باید پیاده سازی شده باشه. یعنی در واقع ما داریم تابع پیاده سازی شده respone (مروبطه به Interface) رو که در MainActivity هستش (پیاده سازی شده) صدا میزنیم.
تابع OnSaveInstanceState هم برای ذخیره اطلاعات در چرخه حیات Fragment هستش . که داده های ما از بین نره.
FragmentB
کد:
public class FragmentB extends Fragment {
TextView tv;
public FragmentB() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_b, container, false);
tv = (TextView) view.findViewById(R.id.tvshow);
if (savedInstanceState !=null) {
tv.setText(savedInstanceState.getString("tv"));
}
return view;
}
public void changedata(String data) {
tv.setText(data);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("tv",tv.getText().toString());
}
}
در FragmentB ما یک تابع نیاز داریم تا از طریق اون بتونیم داده های ارسال شده از سمت MainActivity رو دریافت کنیم
که در اینجا تابع changedata این کار رو برای ما انجام میده. یعنی داده ارسال شده رو دریافت کرده و در TextView نمایش میده
MainActivity.java
کد:
import android.app.Fragment;
import android.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity implements FragmentCommunication {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void Response(String data) {
FragmentManager fragmentManager = getFragmentManager();
FragmentB fragmentB = (FragmentB) fragmentManager.findFragmentById(R.id.fragmentb);
fragmentB.changedata(data);
}
}
در MainActivityمیایم و Interface ایجاد شده یعنی FragmentCommunication رو پیاده شده Implement میکنیم و با استفاده ار تابع Response پیاده سازی شده اقدام به نمونه سازی از FragmentB کرده و تابع changedata مربوط به FragmentB رو صدا میزنیم و داده دریافت شده از سمت FragementA به سمت FragmentB ارسال میکنیم ( data )
activity_main.xml
کد:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.mahdi.fragmentcommanicationdesignpattern.MainActivity">
<fragment
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:name="com.example.mahdi.fragmentcommanicationdesignpattern.FragmentA"
tools:layout="@layout/fragment_a"
android:id="@+id/fragmenta"/>
<fragment
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:name="com.example.mahdi.fragmentcommanicationdesignpattern.FragmentB"
tools:layout="@layout/fragment_b"
android:id="@+id/fragmentb"/>
</LinearLayout>
fragment_a.xml
کد:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFBBCC"
tools:context="com.example.mahdi.fragmentcommanicationdesignpattern.FragmentA">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_margin="40dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_fragment_a"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnclick"
android:text="Click Me"
android:layout_marginTop="70dp"
android:layout_marginLeft="40dp"/>
</FrameLayout>
fragment_b.xml
کد:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FFCC"
tools:context="com.example.mahdi.fragmentcommanicationdesignpattern.FragmentB">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="40dp"
android:text="@string/hello_fragment_b"/>
<TextView
android:id="@+id/tvshow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:layout_marginTop="70dp"
android:text="You Click 0 Time"/>
</FrameLayout>
موفق و پیروز باشید
چندتا تصویر از محیط طراحی شده آموزش فوق: