معرفی fragment ها در اندروید

شنبه 4 اردیبهشت 1395

در این مقاله قصد داریم در مورد fragment ها صحبت کنیم، و می خواهیم یک نمونه از آن ها را ایجاد نماییم و در application های خود از آن استفاده کنیم، و علاوه بر آن می خواهیم در مورد طراحی و نمایش fragment ها در یک action که شامل پیاده سازی ارتباط بین fragment ها است.

معرفی fragment ها در اندروید

Fragment چیست؟

Fragment یک بخش ماژولار است که شامل رابط کاربری نرم افزار و رفتار وجود دارد که در یک activity تعبیه شده است، که می توان آن را یا اضافه کرد و یا حذف کرد.

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

fragment  ها در یک فایل xml در پوشه ای که فایل layout در آن قرار دارد ایجاد می شود، برای استفاده از این Sdk باید از نسخه ی 3 به بعد استفاده نمایید ما به دو صورت می توانیم از fragment استفاده کنیم یا به صورت قرار دادن مناسب یک activity در یک پوشه ی layout یا اینکه از طریق کد در کلاس activty خود آن را پیاده سازی نماییم.

زمانی که از یک fragment استفاده می کنید باید حتما از کتابخانه های android support v4 استفاده کنید که در نسخه های قدیمی بتوانیم از آن استفاده کنیم.

ایجاد یک fragment:

برای ایجاد یک fragment باید از یک فایل xml و یک کلاس جاوا استفاده نماییم، برای فایل xml می تواند از هر ابزاری با هر پیچیدگی در آن استفاده شود، به عنوان مثال در زیر از یک relativelayout با یک textview داخل آن استفاده شده است.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/red" >
	
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/fragone_label_text"
        android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>

حالا تعریف کلاس:

package com.example.myfragmentdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentOne extends Fragment {
	   @Override
	    public View onCreateView(LayoutInflater inflater, 
             ViewGroup container, 
	       Bundle savedInstanceState) {
	        // Inflate the layout for this fragment
	        return inflater.inflate(R.layout.fragment_one_layout, 
                   container, false);
	    }
}

در قطعه کد بالا از چرخه های حیات اندروید استفاده نمی شود، و برای ایجاد یک لایه activity از نسخه های قدیمی تر اندروید از کتابخانه های v4 استفاده می شود، هنگامی که لایه ی fragment و کلاس ایجاد شد، fragment آماده است که در لایه ی activity استفاده شود.

اضافه کردن یک fragment به activity با استفاده از لایه ی xml

fragment را می توان با استفاده از کد جاوا داخل یک فایل xml گنجاند، یک نکته ای که قابل ذکر است این است که در کلاس هایی که استفاده می کنیم به جای اینکه از خود activity ارث بری کند از یک کلاس به نام

fragmentActivity ارث بری می نماید.

package com.example.myfragmentdemo;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;

public class FragmentDemoActivity extends FragmentActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_fragment_demo);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_fragment_demo,
                         menu);
		return true;
	}
}

حالا در فایل xml از یک fragment استفاده کرده ایم:

<RelativeLayout 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"
    tools:context=".FragmentDemoActivity" >

    <fragment
        android:id="@+id/fragment_one"
        android:name="com.example.myfragmentdemo.FragmentOne"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        tools:layout="@layout/fragment_one_layout" />
    
</RelativeLayout>

خواص کلیدی fragment در اندروید که از یک نام استفاده شده است که باید از یک کلاس مرتبط با fragment استفاده شود، و ابزار reference که باید از فایل منبع حاوی  فایل xml از یک fragment باشد.

زمانی که شما از یک fragment در صفحه ی خود استفاده می کنید ممکن است آن را به صورت پیش فرض در روی صفحه خود مشاهده نمایید.

برای اینکه بتوانید به صورت واقعی آن را مشاهده کنید روی placeholder راست کلیک نمایید و fragment مورد نظر را انتخاب نمایید، و بنابر این fragmentname داخل صفحه را با fragmentname که در گزینه ی منو قرار دارد جایگزین نمایید و پس از انتخاب قطعه در نمایش گرافیکی ظاهر خواهد شد.به صورت زیر:

افزودن و مدیریت fragment در کد:

در یک activity می توان به راحتی یک fragment را اضافه و یا حذف کرد می توان به صورت پویا هم این fragment ها را به صفحه ی خود اضافه کرد یعنی می توان هم به صورت پویا آن را حذف و ایجاد و به یک جای دیگر آن ها را انتقال داد که در حالی که برنامه در حال اجرا باشد.

زمانی که می خواهید با استفاده از کد fragment های خود را مدیریت نمایید، از یک فایل xml و یک کلاس جاوا استفاده می شود، تنها تفاوت استفاده از fragment  ها زمان استفاده داخل activity هاست، دز زیر مراحل اضافه کردن یک fragment به یک activity را با استفاده از یک کد نمایش می دهد:

1-درست کردن یک instance از یک کلاس fregment

2-ارسال یک سری آرگومان از طریق یک کلاس

3-به دست آوردن یک مرجع به عنوان مثال fragmentmanager

4-استفاده از روش begintarnsaction در مثال fragmentmanager این مثال یک نمونه fragment بر می گرداند.

5-صدا زدن روش fragmenttransaction و پاس دادن داده ها به عنوان آرگومان برای شناسایی یک منبع است.

6-صدا زدن متد commit در یک fragment در کد زیر یک قطعه تعریف شده است، یک قطعه تعریف شده داخل این کلاس به گونه ای است که توسط کلاس fragmentone با استفاده از یک linearlayout , و با استفاده از یک id استفاده خواهد شد.

FragmentOne firstFragment = new FragmentOne();		
firstFragment.setArguments(getIntent().getExtras());      

FragmentManager fragManager = getSupportFragmentManager();		
FragmentTransaction transaction = fragManager.beginTransaction();		

transaction.add(R.id.LinearLayout1, firstFragment);	
transaction.commit(); 

در کد بالا هر مرحله یک هدف واضح دارد و می توانید هر 4 خط بالا به صورت زیر هم بنویسید:

getSupportFragmentManager().beginTransaction()
        .add(R.id.LinearLayout1, firstFragment).commit();

زمانی که به یک container یک fragment اضافه می شود، ممکن است که شما آن را مورد استفاده قرار ندهید بنابر این می توانید آن را حذف نمایید به صورت زیر:

transaction.remove(firstFragment);

علاوه بر آن ممکن است شما یک fragment را با استفاده از یک متد replace نمایید، ما یک قطعه fragment داریم در کد زیر یا می توانید یک fragment ایجاد نمایید و یا اینکه دو fragment را جا به جا نمایید و بعد متد addtobackstack را صدا بزنید و در انتها متد commit را فراخوانی نمایید.

FragmentTwo secondFragment = new FragmentTwo();
transaction.replace(R.id.LinearLayout1, secondFragment);
transaction.addToBackStack(null);
transaction.commit();

مدیریت رویداد fragment:

همان طور که قبلا بیان کردیم fragment یک activity فرعی است که با طرح خود از یک کلاس و یک چرخه ی حیات تشکیل شده است، ابزارهایی که داخل یک activity استفاده می کردیم داخل fragment هم قابل استفاده خواهد بود، این سوال که چگونه یک کلاس یک رویداد را در یک fragment و یا activity که در خود یک fragment تعبیه کرده است وجود دارد جواب این سوال به چگونگی اداره کردن رویداد مربوط است .

برای پیاده سازی روش بالا دو متد وجود دارد :

1-event listener

2-متد پاسخ به تماس با استفاده از activity

Button button = (Button)findViewById(R.id.myButton);
        
button.setOnClickListener(
        new Button.OnClickListener() {
        	public void onClick(View v) {
                	  // Code to be performed when 
			  // the button is clicked
        		}
        	}
        );

در مورد متوقف کردن رویداد های کلیک در تنظیمات اندروید استفاده از ویژگی onclick در فایل xml است.

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="onClick"
    android:text="Click me" />

قاعده ی کلی برای نمایش یک fragment این است که از یک رویداد listener و با استفاده از متد callback پاسخ داده می شود.

پیاده سازی قطعه ارتباطات:

هنگامی که یک یا چند fragment در بین activity قرار می گیرد به جای قرار دادن بین دو fragment و یک activity بین یک fragment و activity قرار بگیرد، در واقع باید بین fragment ها ارتباط بر قرار کرد ولی نه به صورت مستقیم باید به صورت کپسوله سازی انجام شود.

برای بر قراری ارتباط یک قطعه با یک activity باید از یک id مشخص با استفاده از findviewbyid تعریف شود و معرفی کرد، هنگامی که id مورد نظر را دریافت کرد activity می تواند به سادگی  به متد های عمومی شی fragment پاسخ دهد.

ارتباط از یک جهت دیگر از یک fragment به activity دیگر کمی پیچیده تر است، در مرحله ی اول باید یک listener interface داشته باشیم به عنوان مثال کد زیر یک interface است که به عنوان یک ابزار داخل fragment استفاده می شود، هم چنین تعریف یک متغییر است که با اشاره به فعالیت های بعدی ذخیره خواهد شد.

public class ToolbarFragment extends Fragment {

	ToolbarListener activityCallback;

	public interface ToolbarListener {
	        public void onButtonClick(int position, String text);
	}
}

در کد بالا یک کلاسی تعریف شده است از یک واسط برای listener استفاده شده ، که با صدا زدن دکمه متد پیاده سازی خواهد شد، که برای پیاده سازی آن می توان از یک عدد صحیح و یک رشته برای تعریف آرگومان استفاده کرد. متد onAttach از کلاس fragment نیاز دارد که نادیده گرفته شود ولی پیاده سازی شود.

این روش به طور خودکار توسط خود سیستم به نام fragment مقدار دهی شده است، متدی که به activity مورد نظر ارسال می شود داخل آن از یک fragment استفاده شده است.

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    try {
       activityCallback = (ToolbarListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement ToolbarListener");
    }
}

با اجرای این مثال یک مرجع زمانی که در activity باشد در متغییر محلی activity ذخیره خواهد شد بنابر این زمانی که نوار واسط listener در activity پاس داده نشود یک exception پاس خواهد داد.

گام بعدی این است که برای فراخوانی متد مخاطبین از activity به fragment که کی و چگونه این اتفاق می افتد؟ پاسخ این است در شرایطی که activity باید توسط fragment داخل خود activity صدا زده شود در زیر یک  روش برای صدا زدن activity زمانی که روی یک دکمه کلیک می شود.

public void buttonClicked (View view) {
   activityCallback.onButtonClick(arg1, arg2);
}

کلاس activity که نوار ابزار واسط listener پیاده سازی می شود به صورت زیر است:

public class FragmentExampleActivity extends FragmentActivity implements 
ToolbarFragment.ToolbarListener {
	public void onButtonClick(String arg1, int arg2) {
      	// Implement code for callback method
	}
.
.
}

activity که تعریف کرده ایم از واسط نوار ابزار استفاده می کند و برای پیاده سازی آن استفاده می شود، که با کلیک کردن روی دکمه متد آن پیاده سازی خواهد شد.

حالا یک تعریف خلاصه از fragment ها داشته باشیم:

fragment ها یک مکانیزم قدرتمند برای ایجاد ماژول های قابل استفاده مجدد است، و می توان پس از ایجاد آن را در activity های خود استفاده نماییم.

یک fragment شامل یک فایل طرح رابط کاربری و یک کلاس تشکیل شده است، fragment اضافه شده می تواند برداشته شود و یا به صورت dynamic در زمان اجرا جایگزین شود، ارتباط بین fragment ها باید از طریق activity ها بر قرار شود.

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید