ساخت Fragment در اندروید

تاریخ انتشار

9 دی 1397

نظرات

بدون کامنت

زمان مطالعه

تقریبا 6 دقیقه

نویسنده

شرکت پدیده تجارت

Build Fragment on Android

Fragment چیست؟

Fragment را می توان بعنوان یک زیر مجموعه و یا یک بخش از اکتیویتی، در نظر گرفت.  Fragment نیز مانند اکتیویتی از دو قسمت xml وjava تشکیل شده.هر اکتیویتی می تواند چندین فرگمنت را در خود جای دهد و هر فرگمنت می تواند در چندین اکتیویتی استفاده شود.بنابراین فرگمنت به تنهایی قابلیت اجرا ندارد.

به عبارت دیگر می توان گفت وقتی می خواهیم در طراحی نرم افزار اندروید اکتیویتی ثابت باشد و تنها قسمتی از اکتیویتی تغییر کند از فرگمنت ها استفاده می کنیم. پس فرگمنت مانند یک برچسب روی اکتیویتی عمل می کند.

ساخت Fragment

برای ساخت Fragment  در اندروید لازم است کتابخانه ای بنام FragNavController را در گردل اد کنیم:

implementation 'com.ncapdevi:frag-nav:2.1.0'

 

در این پروژه سعی داریم دو فرگمنت ایجاد کنیم. ابتدا ظاهر فرگمنت ها را طراحی می کنیم.

یک Layout بنام fragment_one و یک Layout بنام fragment_two ایجاد کنید و سورس کدهای زیر را در آن ها وارد کنید:

fragment_one:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="number1"/>
    
    
    <Button
        android:id="@+id/btn_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="openDialog"  />
 </LinearLayout

Fragment_two:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    >
<TextView
 android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="number2"/>

    
<Button
    android:id="@+id/btn_fragment"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="openDialog"
    />

</LinearLayout>

 

همانطور که می بینید، ظاهر هر فرگمنت از یک TextView و یک Button تشکیل شده است:

ظاهر فرگمنت ها را طراحی کردیم، حالا  میریم سراغ اکتیویتی که قراره فرگمنت داخل آن نمایش داده شود.

یک اکتیویتی بنام TestFragmentActivity ایجاد کرده و داخل xml آن سورس کد زیر را وارد کنید:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/fl_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/ll_button_nv">

    </FrameLayout>


 <LinearLayout
        android:id="@+id/ll_button_nv"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        android:weightSum="2">

        <Button
            android:id="@+id/btn_openOneFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="number1" />

        <Button
            android:id="@+id/btn_openTwoFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="number2" />
</LinearLayout>
</RelativeLayout>

 

ابتدا یک RelativeLayout با طول و عرض match_parent تعریف می کنیم، سپس یک LinearLayout با طول match_parent و عرض 50 تعریف کرده و داخل آن دو Button قرار می دهیم و layout_alignParentBottom آن را true می کنیم تا پایین صفحه قرار گیرد. برای اینکه اندازه ی دو Button برابر باشد، داخل LinearLayout، weightSum را برابر 2 قرار می دهیم، همچنین داخل Button ها طول را برابر صفر و layout_weight را برابر 1 قرار می دهیم.

برای اینکه یک فرگمنت داخل اکتیویتی قرار دهیم باید یک لایه ی FrameLayout ایجاد کنیم پس یک FrameLayout با طول و عرض match_parent ایجاد کرده وآن را بالای LinearLayout قرار می دهیم.

ظاهر اکتیویتی را هم طراحی کردیم که بصورت زیر می باشد:

کد جاوای Fragment

دو کلاس بنام های OneFragment و TwoFragment ایجاد کرده و سورس کدهای زیر را در آن ها وارد کنید:

OneFragment:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;



public class OneFragment extends Fragment {

    Button btn_fragment;
    OnTabButtons onTabButtons;

    public static OneFragment newInstance() {

        Bundle args = new Bundle();

        OneFragment fragment = new OneFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View fragmentView = inflater.inflate(R.layout.fragment_one , container , false);
        return fragmentView;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        btn_fragment = (Button) view.findViewById(R.id.btn_fragment);

        btn_fragment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                onTabButtons.onTab();
            }
        });

    }

    
    public interface OnTabButtons{
        public void onTab();
    }

    public OneFragment setOnTabButtons(OnTabButtons onTabButtons){
        this.onTabButtons = onTabButtons;
        return this;
    }
}

TwoFragment:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;


public class TwoFragment extends Fragment {

    Button btn_fragment;
    OnTabButtons onTabButtons;

    public static TwoFragment newInstance() {

        Bundle args = new Bundle();

        TwoFragment fragment = new TwoFragment();
        fragment.setArguments(args);
        return fragment;
    }

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

        View fragmentView = inflater.inflate(R.layout.fragment_two , container , false);
        return fragmentView;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        
        btn_fragment = (Button) view.findViewById(R.id.btn_fragment);

        btn_fragment.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onTabButtons.onTab();
            }
        });
    }
    

    public interface OnTabButtons {

        public void onTab();
    }

    public TwoFragment setOnTabButtons(OnTabButtons onTabButtons){
        this.onTabButtons = onTabButtons;
        return this;
    }
}

 

ابتدا باید کلاس را extend کنیم به Fragment سپس Button داخل فرگمنت را تعریف کنیم.

برای ساخت هرفرگمنت به سه متد نیاز داریم:

  • newInstance
  • onCreateView
  • onViewCreated

برای نوشتن این متدها کافیست اسم آن ها را بنویسیم ، بصورت خودکار متدها را برامون میاره.

متد  newInstanceدر واقع بین کلاس فرگمنت و اکتیویتی ارتباط برقرار می کند و در صورتی که بخواهیم اطلاعاتی از این کلاس به اکتیویتی پاس دهیم از طریق این متد این کار را انجام می دهیم.

داخل متد onCreateView، با inflater ظاهر فرگمنت را فراخوانی کرده و آن را return می کنیم و در آخر هر کاری که می خواهیم روی فرگمنت انجام دهیم ، داخل متد onViewCreate می نویسیم.

داخل متد  onViewCreate، دکمه ای که برای فرگمنت قرار دادیم findViewById کرده و برای آن setonClickListener می نویسیم.

می خواهیم وقتی روی دکمه ی داخل فرگمنت کلیک شد، اکتیویتی متوجه شود بعبارتی می خواهیم اطلاعاتی از کلاس فرگمنت به اکتیویتی پاس دهیم، پس از interface استفاده  کرده و برای اینکه بتونیم interface رو به اکتیویتی پاس دهیم ، یک متد از نوع خود کلاس فرگمنت بنام setOnTabButtons، ایجاد کرده و interface را به ورودی آن می دهیم.

حالا داخل onClick که برای دکمه ی فرگمنت نوشتیم، تابع داخل interface را فراخوانی می کنیم.

همین عملیات را درTwoFragment نیز انجام می دهیم.

کد جاوای Activiity

حالا داخل اکتیویتی که می خواهید فرگمنت در آن نشان داده شود، سورس کد زیر را وارد کنید:

import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Switch;
import android.widget.Toast;

import com.elahe.test.fragment.OneFragment;
import com.elahe.test.fragment.TwoFragment;
import com.ncapdevi.fragnav.FragNavController;

public class TestFragmentActivity extends AppCompatActivity {

    Context context = this;
    Button btn_openFrgOne , btn_openFrgTwo;

    FragNavController fragNavController;

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

        initView();
        onClick();
        initFragment(savedInstanceState);
    }

    private void initFragment(Bundle savedInstanceState) {

        fragNavController =  FragNavController.newBuilder(savedInstanceState , getSupportFragmentManager(),R.id.fl_fragment).transactionListener(new FragNavController.TransactionListener() {
            @Override
            public void onTabTransaction(Fragment fragment, int i) {

            }

            @Override
            public void onFragmentTransaction(Fragment fragment, FragNavController.TransactionType transactionType) {

            }
        }).rootFragmentListener(new FragNavController.RootFragmentListener() {
            @Override
            public Fragment getRootFragment(int i) {

                Fragment fragment = null;

                switch (i) {
                    case FragNavController.TAB1:
                        fragment = OneFragment.newInstance().setOnTabButtons(new OneFragment.OnTabButtons() {
                            @Override
                            public void onTab() {
                                Toast.makeText(context, "OneFragment", Toast.LENGTH_SHORT).show();

                            }
                        });
                        break;

                    case FragNavController.TAB2:
                        fragment = TwoFragment.newInstance().setOnTabButtons(new TwoFragment.OnTabButtons() {
                            @Override
                            public void onTab() {
                                Toast.makeText(context, "TwoFragment", Toast.LENGTH_SHORT).show();
                            }
                        });
                        break;
                }

                return fragment;
            }
        },2).build();
    }

    private void onClick() {

        btn_openFrgOne.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                fragNavController.switchTab(FragNavController.TAB1);
            }
        });

        btn_openFrgTwo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                fragNavController.switchTab(FragNavController.TAB2);
            }
        });

    }

    private void initView() {

        btn_openFrgOne = (Button) findViewById(R.id.btn_openOneFragment);
        btn_openFrgTwo = (Button) findViewById(R.id.btn_openTwoFragment);
    }


}

 

در این اکتیویتی ابتدا Context و Button ها وکتابخانه  FragNavController را تعریف می کنیم.

برای اینکه کدها نظم بهتری داشته باشند سه متد بنام های initView() وonClick() و initFragment(savedInstanceState) ایجاد کرده و آن ها را در onCreate فراخوانی می کنیم.

داخل متد initView ، Button ها را findViewById می کنیم.داخل متد  onClick برای Button ها setOnClickListener می نویسیم و داخل متد initFragment، کدهای مربوط به فرگمنت را می نویسیم.

برای ساخت فرگمنت، داخل متد initFragment با کد زیر، یک فرگمنت ایجاد می کنیم:

fragNavController =  FragNavController.newBuilder(savedInstanceState , getSupportFragmentManager(),R.id.fl_fragment).transactionListener(new FragNavController.TransactionListener() {

 

وقتی این خط رو نوشتیم دو تا متد onTabTransaction و onFragmentTransaction رو میاره که فعلا به این دو متد کاری نداریم.

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

.rootFragmentListener(new FragNavController.RootFragmentListener() {

 

با نوشتن این خط، یک متد بنام getRootFragment ، نوشته می شود که برای مشخص کردن تعداد فرگمنت ها و خود فرگمنت ها می باشد.

داخل متد getRootFragment ، ابتدا یک فرگمنت با مقدار null ایجاد کرده، سپس با دستور switch فرگمنت را مقدار دهی می کنیم.

کتابخانه ی FragNavController، بصورت خودکار 20، Tab ایجاد و آن ها را نام گذاری کرده. پس شماره ی Tab  را از کتابخانه می گیریم و می نویسیم اگر Tab1 بود مقدار فرگمنت را برابر OneFragment و اگرTab2 بود مقدار فرگمنت را برابر TwoFragment قرار دهد:

switch (i) {
    case FragNavController.TAB1:
        fragment = OneFragment.newInstance().setOnTabButtons(new OneFragment.OnTabButtons() {
            @Override
            public void onTab() {
                Toast.makeText(context, "OneFragment", Toast.LENGTH_SHORT).show();
            }
        });
        break;

    case FragNavController.TAB2:
        fragment = TwoFragment.newInstance().setOnTabButtons(new TwoFragment.OnTabButtons() {
            @Override
            public void onTab() {
                Toast.makeText(context, "TwoFragment", Toast.LENGTH_SHORT).show();
            }
        });
        break;
}

 

همچنین با فراخوانی متد     setOnTabButtons از داخل کلاس فرگمنت ، متد داخل interface ایمپورت می شود که این متد مربوط به زمانی است که روی دکمه ی داخل فرگمنت کلیک شود. ما برای آن یک Toast تنظیم کردیم، یعنی با کلیک بر روی دکمه ی داخل فرگمنت این Toast نشان داده می شود.

در آخر fragment را return می کنیم. با خطایی برخورد می کنیم که برای رفع آن باید تیکه کد },2).build();

را بعد از کروشه وارد کنیم که تعداد  فرگمنت را مشخص می کند.

مرحله ی آخر این است که با کلیک بر روی دکمه های داخل اکتیویتی، فرگمنت ها تغییر کنند. بدین منظور به متد() onClick  رفته و با دستور switchTab، مشخص می کنیم با کلیک بر روی هرButton، کدام فرگمنت نشان داده شود:

private void onClick() {

    btn_openFrgOne.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            fragNavController.switchTab(FragNavController.TAB1);
        }
    });

    btn_openFrgTwo.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            fragNavController.switchTab(FragNavController.TAB2);
        }
    });

}

 

ساخت فرگمنت به پایان رسید. با اجرا کردن app ، صفحه ی زیر نشان داده می شود:

 

با کلیک بر روی دکمه های پایین، فرگمنت مربوطه نشان داده می شود.اگر دکمه ی Number2 را کلیک کنید فرگمنت عوض شده و TextView به Number2 تغییر می کند و با کلیک بر روی دکمه ی btn_Fragment یک Toast نشان داده می شود.

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

نویسنده: الهه ابراهیمی

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

یک فنجان مشاوره رایگان
مـهـمـان پـدیــده بـاشـیـــد ...

مقالات مرتبط