آموزش TabLayout با استفاده از ViewPager و Fragments
سلام دوستان با آموزش TabLayout با استفاده از ViewPager و Fragments باز بازگشتیم خب اصلا این Tablayout به چه دردی میخوره ؟! در جواب به این سوال یکسری از متدها برای پیاده سازی متریال دیزان استفاده از Tablayout و دسته بندی اکتیویتی های مختلف است پس دو کار برای ما انجام می دهد و استفاده از آن هم مثل آب خوردن است زیاد دیگه سرتون رو درد نمیارم میرم بخش کد.در ادامه با ما همراه باشید. برای استفاده از Tablayout نیاز به اضافه کردن Design Support در فایل گریدل هست مثل همیشه باید قند شکنمون رو روشن کنیم علتش رو هم در این پست گفته ایم می توانید آن را مطالعه کنید
خب پس فایل Gradle را باز کرده و خط زیر رو در آن قرار دهید.
1 | compile 'com.android.support:appcompat-v7:23.2.0' |
فقط دوستان توجه کنند باید Desgin مربوط به Sdk که شما نصب کردید را قرار دهید در این جا ما از Sdk ورژن 23 استفاده کرده ایم ممکن است برای شما به طور مثال 25 باشد پس تغییرات رو خودتان اعمال کنید.
در اینجا ما باید سه فایل xml ایجاد کرده این سه فایل همان View های ما برای ViewPager خواهند بود و اسم آنها به ترتیب tab.xml , tab2.xml و Tab3.xml خواهند بود.
تب اول
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?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:orientation="vertical"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Tab 1" android:textAppearance="?android:attr/textAppearanceLarge"/> </RelativeLayout> |
تب دوم
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?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:orientation="vertical"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Tab 2" android:textAppearance="?android:attr/textAppearanceLarge"/> </RelativeLayout> |
تب سوم
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?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:orientation="vertical"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Tab 1" android:textAppearance="?android:attr/textAppearanceLarge"/> </RelativeLayout> |
خب تا اینجا خوب پیش رفتیم حالا باید 3 تا کلاس جاوا مرتبط با این 3 Layout که ساخته شده بسازیم همانند زیر می شود کلاس های ما.
tab1.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; /** * Created by Jfp on 2/3/2017. */ //Our class extending fragment public class Tab1 extends Fragment { //Overriden method onCreateView @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //Returning the layout file after inflating //Change R.layout.tab in you classes return inflater.inflate(R.layout.tab, container, false); } } |
tab2.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; /** * Created by jfp on 2/3/2017. */ //Our class extending fragment public class Tab1 extends Fragment { //Overriden method onCreateView @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //Returning the layout file after inflating return inflater.inflate(R.layout.tab2, container, false); } } |
tab3.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; /** * Created by jfp on 2/3/2017. */ //Our class extending fragment public class Tab1 extends Fragment { //Overriden method onCreateView @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //Returning the layout file after inflating return inflater.inflate(R.layout.tab3, container, false); } } |
حال زمان ساخت Pager.java می رسد این کلاس ارتباط بین ViewPager را با Fragment های ساخته شده برقرار می کند
فایل Pager به شکل زیر می شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; /** * Created by تبح on 2/3/2017. */ //Extending FragmentStatePagerAdapter public class Pager extends FragmentStatePagerAdapter { //integer to count number of tabs int tabCount; //Constructor to the class public Pager(FragmentManager fm, int tabCount) { super(fm); //Initializing tab count this.tabCount= tabCount; } //Overriding method getItem @Override public Fragment getItem(int position) { //Returning the current tabs switch (position) { case 0: Tab1 tab1 = new Tab1(); return tab1; case 1: Tab2 tab2 = new Tab2(); return tab2; case 2: Tab3 tab3 = new Tab3(); return tab3; default: return null; } } //Overriden method getCount to get the number of tabs @Override public int getCount() { return tabCount; } } |
زمان حذف Actionbar می رسد وارد فایل style.xml شده سپس تغییرات زیر را اعمال کنید.
1 2 3 4 5 6 7 8 9 10 | <resources> <!-- Base application theme. --> <!-- changing it to no actionbar --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources> |
خب کلاس های خودمان رو هم ساختیم حالا باید صفحه اصلی برنامه رو بسازیم که این کلاس ها و View ها در آن نمایش داده خواهند شد
فایل Activiy_Main.xnl همانند زیر می شود در آن View Pager و Tab را قرار داده ایم
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <LinearLayout android:id="@+id/main_layout" android:orientation="vertical" 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" tools:context=".MainActivity"> <!-- our toolbar --> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> <!-- our tablayout to display tabs --> <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorPrimary" android:minHeight="?attr/actionBarSize" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/> <!-- View pager to swipe views --> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="fill_parent"/> </LinearLayout> |
و در آخر کد java بخش Mainactivity که به شکل زیر می شود در زیر بخش main را گسترش داده و از بخش AppCompatActivity ابزار TabLayout را فراخوانی کرده ایم (علت این فراخوانی برای کلیک بروی هر یک از Tab هاست)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import android.support.design.widget.TabLayout; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.Toolbar; //Implementing the interface OnTabSelectedListener to our MainActivity //This interface would help in swiping views public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener{ //This is our tablayout private TabLayout tabLayout; //This is our viewPager private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Adding toolbar to the activity Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); //Initializing the tablayout tabLayout = (TabLayout) findViewById(R.id.tabLayout); //Adding the tabs using addTab() method tabLayout.addTab(tabLayout.newTab().setText("Tab1")); tabLayout.addTab(tabLayout.newTab().setText("Tab2")); tabLayout.addTab(tabLayout.newTab().setText("Tab3")); tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); //Initializing viewPager viewPager = (ViewPager) findViewById(R.id.pager); //Creating our pager adapter Pager adapter = new Pager(getSupportFragmentManager(), tabLayout.getTabCount()); //Adding adapter to pager viewPager.setAdapter(adapter); //Adding onTabSelectedListener to swipe views tabLayout.setOnTabSelectedListener(this); } @Override public void onTabSelected(TabLayout.Tab tab) { viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } } |
آموزش به پایان رسید انشااالله در آینده با آموزش های بیشتری باز خواهیم گشت .
سلام و خسته نباشید و ممنون از آموزشتون.
ببخشید چطور میشه داخل هر کدوم از این تب ها، از لیست ویو استفاده کنیم؟
ممنون میشم اگه آموزشش رو بذارین.
مرسی.
خیلی ساده است باید در هر فرگمنت listview قرار دهید سپس find کرده و همان کاری های که در اکتیویتی های معمولی انجام می شود را انجام دهید.
به زودی آموزشش قرار خواهد گرفت.
سلام.
بسیار عالی .
روی api 14 جواب نمیده؟
سلام جواب می دهد.
سلام خسته نباشید
من میخام مقادیری رو به این فرگمنت هایی که در tab layout تعریف کردم ارسال کنم، چطور باید انجام بشه؟
ممنونم
ازbundle یا shared preferences میتونید استفاده کنید
با سلام. اگه تو یه تب یه دکمه باشه و قصد ما این باشه که با کلیک بر روی اون یک اتفاق در تب دیگه بیوفته باید چکار کرد. بین تب ها چطور ارتباط برقرار کنیم؟؟
برای برقراری ارتباط از باندل و shared preferences میتونید استفاده کنید.برای اینکاری هم که گفتین بستگی داره چکاری میخواد باشه
چجوری میشه بیشتر از 3 تا تب بزاریم
مقدار زیر را در tablayout قرار دهید.
به طور مثال
موفق باشید.
سلام خسته نباشید
من یه سرچ ویو داخل اکتیویتی دارم بعد میخوام متن سرچ ویو به تب هام بدم که متن رو داخل دیتابیس سرچ کنم ،متن رو میتونم داخل دیتابیس سرچ کنم ولی فرگمنت های تب لایوتم رو نمیتونم تغییر بدم ، حتی اداپتر رو نیو میکنم و فرگمنت جدید میدم تغییری نمیکنه هرچی دفعه اول بهش دادم همونه
سلام باید به آداپتورتون notifydatasetchanged بزنید تا تغییر کنید
این کار رو هم کردم ولی نشد اگه راه ارتباطی دیگه ای باشه مثل تلگرام که کد رو واستون بفرستم یه برسی بکنید ممنون میشم
telegram : @mahdi_jive
سلام خیر امکان پذیر نیست .
سلام ممنون از آموزش خوبتون
من طبق همین آموزش ۵ فرگمنت رو در tablayout قرار دادم و از viewpager هم استفاده کردم.
برنامه مد نظر من برنامه ایه که ۵ دسته بندی اصلی داره وقتی تو فرگمنت یا همون دسته اول تعدادی عکس و متن قرار میدم و به فرگمنت دوم میرسم تو فرگمنت دوم از یه جایی دیگه عکس جدید قبول نمیکنه و وقتی اجرا میگیرم هنگام جابجایی از اکتیویتی اول به اکتیویتی دوم امولاتور کرش میکنه و از برنامه بیرون میاد و مشکلش فقط با پاک کردن اون عکس حل میشه! این در صورتیه که همون عکس در یک اکتیویتی دیگه از همین برنامه براحتی اجرا میشه!
ممنون میشم اگه راهنمایی بفرمایید…
سلام و درود خطایی که برای شما پیش میادش Memory Leak گفته می شود می توانید در لینک زیر مطلب زیر را مطالعه کنید .
https://programchi.ir/2017/07/10/memory-leak-%DB%8C%D8%A7-%DA%A9%D9%85%D8%A8%D9%88%D8%AF-%D8%AD%D8%A7%D9%81%D8%B8%D9%87-%DA%86%DB%8C%D8%B3%D8%AA-%D8%9F/
و درمورد چگونگی حل مشکل شما عکسی که قرار می دهید احتمالا حجم بالایی دارد حجم آن را کم کنید و اندازه آن را به 500 * 500 کاهش دهید و از نوع عکس Jpg استفاده کنید.
موفق باشید.
سلام و خسته نباشید خدمت دوستان و اساتید محترم ,
من داخل پروژم TabLayout و ViewPager دارم که 5تا تب داره و توی اونها لیست ویو هست که اطلاعاتو از دیتابیس داخلی توش نشون میده . روش پیاده سازیه تبها و ویوپیجرم هم تا اونجا دیدم شبیه مطالب شماست خوشبختانه . ولی یه مشکل دارم اونم اینه که وقتی روی تب اول میرم از قسمت لاگ ها که نگاه میکنم متوجه میشم که onCreate تب دو هم همزمان باهاش اجرا میشه ,روی دومی هم به همین ترتیب ، روی سومی هیچی چون با دومی اجرا شده ، و بقیه عم تقریبا به این ترتیب …. البته ظاهرا مشکلی نداره توی نمایش و اجراش ولی خب نباید اینطوری باشه و باید هر تب فقط کد خودشو اجرا کنه . بعدم مثلا روی تب 4 و 5 که سوییچ میکنی اطلاعات آپدیت نمیشه باید یه بار بری روی تب های قبلی دوباره بیای روی تب 5 تا درست نشون بده .. خلاصه گیرافتادیم ، اگه میشه راهنمایی کنید .
سپاس فراوان …
سلام شما باید یک فایل داشته باشید که به صورت استاتیک مقادیر توش پره بشه هر دفعه پر شدن داخل متغیر ها باید داینامیک باشه فقط به صورت پیشفرض شما باید یک فایل شامل یکسری متغیر داشته باشید سپس در متود setOnTabChangedListener بیاید مقادیر تب بعدی رو با استفاده از یکسری شرط پر کنید برای اینکه لود تب ها رو محدود کنید می تونید از کد زیر استفاده کنید
موفق باشید.
سلام ممنون از اموزشتون خیلی کمک کرد اما من مشکلی که دارم اینه که توی شبیه ساز برنامه کار میکنه اما وقتی میارم روی گوشی واقعی از برنامه میپره بیرون میشه کمک کنید لطفا خیلی نیاز دارم .
ممنون
سلام ، بسیار ممنونم از توجه و پیگیری شما به سوالات .
بعد از چند روز سرچ و تست کردن با استفاده از موارد زیر ، گویا تونستم محدودیت رو بالاخره ایجاد کنم :
در داخل فرگمنت ها :
(دستورات مد نظر هم داخل تابع ;()loadData تعریف میشه)
بجز روش فوق هرکاری کردم جواب نداد …
بازم بابت پاسختون بسیار سپاسگذارم .
خواهش می کنم.
سلام من مثل همین برنامه رو نوشتم ولی خط های زیر رو خطا میگیره
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
viewPager = (ViewPager) findViewById(R.id.pager);
toolbar & tabLayout & viewPager ک داخل پرانتزن قرمز میشه…
سلام
از Alt+Enter برای import کلاس ها استفاده کنید.
سلام
ویو پیجر با تب ها حرکت نمی کنه
ویو پیجر جدا میره و تب ها هم جدا
چیکتر باید بکنیم که باهم بره؟
سلام
اولا که ایولا به پاسخگویی
دوم فک میکنم مشکلم رو جوابش رو تو کامنت بچه ها دیدم اما بازهم میپرسم اگه جواب بهرتی هست ممنون میشم
من یه سری محصول دارم که تو دسته بندی های مختلف هستند و تو دیتابیسم هم دو تا جدول دارم یکی برا محصلات یکی برا کتگوری
حالا میخوام ابتدا تب لیوت اطلاعات کتگوری رو بگیره و به تعداد دسته ها تب ایجاد کنه که این رو فک کنم با طول ارایه ای که از دیتا مدل کتگوری میگیرم بشه درستش کرد
و بعد اینکه هر تب اطلاعات اون دسته رو فقط نمایش بده که برا دریافت این اطلاعات فک کنم باید تو setOnTabChangedListener یه ریکوعست بزنم به سرو و محصولات دسته رو بگیرم درسته ؟؟؟
اولین باره از تب لیوت استفاده میکنم
سلام تمامی بخش ها را دست گفتید اگر به همین شکلی که گفتید عمل کنید مشکلی پیش نمی آید.
سلام مجدد هنگام ایجاد تب لیوت تعداد تب های ایجاد شده درسته یعنی به تعداد دسته بندی هامک ایجاد میشه
اما برای پیج تایتل مشکل دارم
راه ارتباطی دیگه ای هست بتونم از شما کمک بگیرم
سلام و درود از طریق تلگرام با من در ارتباط باشید البته پاسخگویی بین 1 الی 2 روز انجام می شود.
موفق و موید باشید.
ممنون
عالی فقط ایدی رو لطف میکنید بزارید یا ایمیل کنید
@bbong9811
سلام آقای جعفری پور
من آموزش شما رو پیاده سازی کردم و الان میخوام که داخل تب اولم یه دکمه بزارم که یه توست رو نمایش بده وقتی دکمه رو درون فایل xml میزارم و می رم فایل tab1.java و در قسمت public View onCreateView که دکمه رو معرفی کنم از find view by id خطا میگیره? قبلا من قسمت on create کد هامو مینوشتم الان شده on create view چی کار کنم? کد ها رو کجا باید بنویسم?
سلام و درود
در همان بخش tab1 شما باید از view عمل find رو انجام دهیم به شکل زیر تغییرش بدید هر tab رو
موفق باشید.
سلام
ممنون از آموزش خوبتون
اما من سوالم اینجاست که آیا میشه دستورات را غیر از Mainactivity هم نوشت.
یعنی غیر از صفحه اول میشه در صفحات دیگر هم از این TabLayout استفاده کرد.
خیلی لازمه راهنمایی بفرمائید
اقا سلام . من 3 تا آیتم دارم که در هر 3 تاش باید دیتاهاش از سمت سرور گرفته بشه . اقا این 3 ایتم وقتی عوض میشه مصلا میرم ایتم 0 و دوباره برمیگیردم 2 ، دیتاش دوباره گرفته میشه . باید چیکار کنم که این ایتم دوباره RELOAD نشه .