رفتن به مطلب
انجمن اندروید ایران | آموزش برنامه نویسی اندروید و موبایل
  • android.png.1fab383bc8500cd93127cebc65b1dcab.png

پست های پیشنهاد شده

[align=center]به نام خدا[/align]

[align=center]آموزش RecyclerView قسمت 1[/align]

[align=right]سلام دوستان[/align]

[align=right]در این تاپیک قصد دارم آموزش RecyclerView در اندروید رو بنویسم که این قسمت اولش هست و انشالله در چند قسمت با این ویجت آشنا میشیم.[/align]

[align=right]RecyclerView چیست؟[/align]

[align=right]بنابر تعریف Documentation رسمی اندروید RecyclerView نسخه بهینه تر و انعطاف پذیرتری از ListView می باشد. توصیه شده وقتی که میخوایم حجم بالایی از اطلاعات رو در لیست نمایش بدیم و وقتی که قراره محتویات لیست دائما تغییر کنه (مثلا با دریافت اطلاعات از اینترنت یا مثلا حذف و اضافه آیتم ها توسط کاربر) به جای listview از RecyclerView استفاده بشه. اما اگر مثلا قراره در برنامتون یه لیست ایستا شامل مثلا 20 آیتم داشته باشید هیچ دلیلی نداره که از RecyclerView استفاده کنید و این ویجت برای ایجاد لیست های پیشرفته طراحی شده (احتمالا در آینده به طور کلی جای ListView رو بگیره)[/align]

برخی از ویژگی های RecyclerView:

[align=right]برخلاف ListView رعایت الگوی طراحی ViewHolder در RecyclerView الزامیست.[/align]

[align=right]برخلاف ListView که تنها حالت قرارگیری آیتم های لیست به صورت عمودی بود در RecyclerView می توان به چندین حالت آیتم های لیست در کنارهم قرار بگیرند[/align]

[align=right]در RecyclerView می توان به راحتی برای حذف و اضافه آیتم ها از لیست انیمیشن تعریف کرد[/align]

[align=right]عیب RecyclerView: تنها عیبی که میتوان به این ویجت گرفت، حجم بیشتر کد مورد نیاز نسبت به لیست ویو و پیچیدگی بیشتر نسبت به لیست ویو میباشد.[/align]

[align=right]مثال: لیست زیر با RecyclerView طراحی شده:[/align]

[align=center]224x380http://inducesmile.com/wp-content/uploads/2015/06/grid.jpg[/img][/align]

[align=right]نحوه کار RecyclerView

[/align]

[align=right]طرز کار RecyclerView به این صورته: به عنوان مثال اگر 100 آیتم برای نمایش در RecyclerView داشته باشیم اونوقت RecyclerView در ابتدای شروع برنامه (وقتی که تازه لیست ویو ایجاد میشه و اطلاعات داخلش قرار میگیرن) برای هر آیتم یک View ایجاد میکنه اما نه برای تمام 100 آیتم!  به عنوان مثال شما در ابتدا 12 آیتم در لیست مشاهده می کنید این یعنی فقط 12 View ایجاد شده و در حافظه قرار داره و اگر لیست رو اسکرول کنید و پایین برید برای بقیه آیتم ها View ساخته میشه اما در عین حال تمام View های قبلی که حالا در صفحه نیستن از بین نمیرن و معمولا 2 آیتم قبلی بالای لیست در حافظه نگهداری میشن و وقتی دوباره به سمت بالا اسکرول کنید RecyclerView آیتم های قبلی که در حافظه موندن رو دوباره Recycle میکنه (دلیل نامگذاری هم همینه) و به این ترتیب اسکرول کردن بسیار نرم و روان میشه. مطابق شکل زیر:[/align]

[align=center]تصویر سمت چپ یک لیست رو در ابتدای شروع برنامه نشون میده[/align]

[align=center]تصویر سمت راست لیست به پایین اسکرول شده و همونطور که در شکل مشخصه دو آیتم قبلی که بیرون صفحه هستن نگهداری میشن تا وقتی دوباره به سمت بالا اسکرول شد نیازی به ساخت دوباره آیتم ها نباشه (بازیافت)[/align]

[align=center]654x497http://www.grokkingandroid.com/wordpress/wp-content/uploads/2014/08/recycling_of_views.png[/img][/align]

[align=right]RecyclerView با سه عنصر اصلی زیر کار میکنه:[/align]

[align=right]ViewHolder: ویو هولدر یک وظیفه ساده داره: نگهداری یک آیتم از لیست. اگر یه ViewHolder خالی باشه یعنی باید یک View جدید (آیتم جدید) ایجاد بشه و داخل ویوهولدر قرار بگیره اگر هم از قبل یک View نگهداری کنه اونوقت از همون قبلی استفاده میشه (همون Recycling که توضیح دادم)[/align]

[align=right]Adapter: ادپتر دو وظیفه بسیار مهم داره: ساخت View یا همان آیتم لیست و قرار دادن اون در یک ViewHolder و چسباندن اطلاعات به هر آیتم (Data Binding)[/align]

[align=right]LayoutManager: نحوه نمایش آیتم های لیست (عمودی، افقی، گرید و ...) به عهده LayoutManager است.[/align]

[align=right]نکته مهم: اصلی ترین تفاوت های RecyclerView با لیست ویو این هست که برخلاف لیست ویو که نحوه نمایش آیتم ها به عهده خودش بود، RecyclerView اصلا با نحوه نمایش و قرارگیری آیتم ها کاری نداره و این کار رو به LayoutManager ها واگذار کرده. به عبارت بهتر: آرایش لیست هیچ ربطی به RecyclerView نداره! کار RecyclerView همونطور که از اسمش معلومه فقط بازیافته![/align]


لینک ارسال
به اشتراک گذاری در سایت های دیگر

[align=center]آموزش RecyclerView قسمت 2[/align]

[align=right]خب در این قسمت کار رو شروع می کنیم. لیستی که ما توی این برنامه میسازیم لیستی از 50 مخاطب دفترچه تلفن هست. برای سادگی کار، اطلاعات هر مخاطب فقط شامل نام و تاریخ ثبت هستش.

[/align]

[align=right] ابتدا یه پروژه به اسم دلخواهتون بسازید سپس در فایل build.gradle قسمت dependencies خط زیر رو وارد کنید:[/align]

compile 'com.android.support:recyclerview-v7:23.0.1'

حالا Gradle رو sync کنید تا کلاس های لازم به پروژتون اضافه بشه. حالا به layout اصلی برنامتون که خود اندروید استدیو ایجاد کرده یک RecyclerView به صورت زیر اضافه کنید:

<?xml version="1.0" encoding="utf-8"?>
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.mnasiri.recyclerview.MainActivity">

            android:id="@+id/contacts_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

به نام ویجت توجه کنید! همونطور که میبینید در نام ویجت نام کتابخونش هم ذکر شده.

سپس یه فایل layout میسازیم که این فایل در واقع layout آیتم های لیستمون محسوب میشه (مثل کاری که در لیست ویو انجام میدادیم). من اسم این فایل رو list_item گذاشتم:

<?xml version="1.0" encoding="utf-8"?>
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:orientation="vertical">

            android:id="@+id/contact_name_textview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="5dp" />

            android:id="@+id/contact_register_date_textview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="5dp" />

حالا یک مدل برای مخاطب میسازیم (کلاسی که بیانگر یک مخاطب هست). مدل ما بسیار ساده است:

این کلاس دو فیلد داره یکی از جنس String که نام مخاطبه و دیگری از جنس Date که بیانگر تاریخ ثبت مخاطبه. به طور پیشفرض در سازنده کلاس وقتی یک شی از این کلاس ایجاد می کنیم تاریخ فعلی گوشی براش در نظر گرفته میشه

import java.util.Date;

public class Contact {
    private String name;
    private Date registerDate;

    public Contact(String name) {
        this.name = name;
        registerDate = new Date();
    }

    public String getName() {
        return name;
    }

    public Date getRegisterDate() {
        return registerDate;
    }

    public void setName(String name) {
        this.name = name;
    }
}

کد اکتیویتی اصلیمون هم فعلا به این شکله:

ابتدا یک رفرنس به RecyclerView مون ایجاد میکنیم.

سپس با متد setLayoutManager() نوع نمایش آیتم های لیست رو مشخص می کنیم (در قسمت قبل توضیح داده شد) که ما در اینجا یک شی از کلاس LinearLayoutManager ایجاد کردیم و به این متد دادیم (توجه کنید که پارامتر سازنده کلاس LinearLayoutManager از جنس Context می باشد)

public class MainActivity extends AppCompatActivity {
    private RecyclerView contactsRecyclerView;

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

        contactsRecyclerView = (RecyclerView) findViewById(R.id.contacts_recyclerview);
        contactsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    }
}

لینک ارسال
به اشتراک گذاری در سایت های دیگر

[align=center]آموزش RecyclerView قسمت 3[/align]

[align=right]خب حالا برای اینکه آیتم هامون رو به RecyclerView اضافه کنیم به دو کلاس نیاز داریم:[/align]

[align=right]1- کلاسی که از کلاس RecyclerView.Adapter ارث بری داشته باشه (کلاس Adapter یک کلاس داخلی استاتیک درون کلاس RecyclerView هست)[/align]

[align=right]2- کلاسی که از کلاس RecyclerView.ViewHolder ارث بری داشته باشه (این کلاس هم یک کلاس داخلی استاتیکه مثل Adapter)[/align]

[align=right]چون برنامه ما ساده است من این دو کلاس رو درون اکتیویتی اصلی یعنی MainActivity.java تعریف می کنم.[/align]

[align=right]ابتدا کلاس ViewHolder مون رو میسازیم:[/align]

private class ContactHolder extends RecyclerView.ViewHolder {

       public ContactHolder(View itemView) {
           super(itemView);

       }

}

همونطور که میبینید اسم کلاس ViewHolder مون رو ContactHolder گذاشتم چون قراره View های مربوط به مخاطبینمون رو نگه داره (البته این اسم دلخواهه). نکته دیگه اینکه این کلاس باید سازنده داشته باشه و درون سازندش هم سازنده کلاس پدرش فراخوانی بشه (همونطور که در کد شده)

حالا باید کلاس Adapter مون رو بسازیم:

private class ContactsAdapter extends RecyclerView.Adapter {

        @Override
        public ContactHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return null;
        }

        @Override
        public void onBindViewHolder(ContactHolder holder, int position) {

        }

        @Override
        public int getItemCount() {
            return 0;
        }

}

خب این کلاس چند نکته داره:

- کلاس RecyclerView.Adapter یک کلاس جنریک هست به این معنی که باید نوع داده ای که این کلاس باهاش کار میکنه رو مشخص کنیم. این نوع داده باید حتما از نوع ViewHolder باشه که همونطور که می بینید ما ContactHolder رو بهش دادیم.

- Override کردن این سه متدی که میبینید در این کلاس الزامیه (چون این متدها به صورت abstract در کلاس RecyclerView.Adapter تعریف شدن و اگر این ها رو Override نکنید اندروید استدیو ارور میده)

توضیح متدها:

متد onCreateViewHolder : همونطور که در قسمت اول توضیح دادیم RecyclerView وقتی میخواد یه آیتم از لیست رو نمایش بده اول بررسی میکنه که آیا اون آیتم از قبل در حافظه وجود داره یا نه که اگر وجود داشته باشه همون رو بازیابی میکنه اما اگر وجود نداشته باشه اونموقع این متد رو فراخوانی میکنه تا یک View جدید براش ساخته بشه. در این متد View ساخته میشه و درون ViewHolder ای که تعریف کردیم قرار داده میشه و به RecyclerView داده میشه تا اون رو نشون بده. همون طور که میبینید نوع داده بازگشتی این متد از جنس ContactHolder هست.

متد onBindViewHolder : از این متد برای چسباندن اطلاعات مورد نظر به آیتم لیست استفاده میشه یعنی این متد View رو میگیره و اسم مخاطب و تاریخ ثبتش رو در اون View قرار میده.

متد getItemCount : این متد هم الزاما باید Override بشه. چرا؟ چون RecyclerView قبل از شروع کار باید بدونه که در ابتدا چند آیتم درون لیستش قراره باشه و همونطور که از اسم این متد معلومه تعداد آیتم های لیستمون رو برمیگردونه. البته این متد در حالت پیشفرض 0 رو بر میگردونه که ما در قسمت بعد اون رو تغییر میدیم.

خب حالا کلاس MainActivity.java تون باید این شکلی باشه:

public class MainActivity extends AppCompatActivity {
    private RecyclerView contactsRecyclerView;

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

        contactsRecyclerView = (RecyclerView) findViewById(R.id.contacts_recyclerview);
        contactsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    }

    private class ContactsAdapter extends RecyclerView.Adapter {

        @Override
        public ContactHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return null;
        }

        @Override
        public void onBindViewHolder(ContactHolder holder, int position) {

        }

        @Override
        public int getItemCount() {
            return 0;
        }

    }

    private class ContactHolder extends RecyclerView.ViewHolder {

        public ContactHolder(View itemView) {
            super(itemView);

        }

    }
}

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

لینک ارسال
به اشتراک گذاری در سایت های دیگر

[align=center]آموزش RecyclerView قسمت 4[/align]

[align=right]خب در این قسمت کلاس هامون رو پیاده سازی می کنیم تا بتونیم اطلاعات موردنظرمون رو داخل RecyclerView نمایش بدیم.[/align]

[align=right]همونطور که میدونید ما قراره لیستی از Contact ها رو نمایش بدیم پس به شکل زیر یک ArrayList از Contact ها با 50 عدد Contact ایجاد می کنیم. توجه داشته باشید که کد زیر رو باید در متد onCreate اکتیویتیمون قرار بدیم:[/align]

List contacts = new ArrayList<>();
for (int i = 0; i < 50; i++) {
   contacts.add(new Contact("Contact #" + i));
}

[align=right]همونطور که میبینید سازنده کلاس Contact یک پارامتر از جنس String میگیره که همون نام مخاطبمون هست. و ما هم اینجا به صورتی که مشاهده می کنید به هر Contact یک نام دادیم.[/align]

[align=right]حالا باید برای Adapter ای که ساختیم یک سازنده تعریف کنیم که این سازنده یک لیست از Contact ها رو دریافت میکنه. پس کد Adapter ما به صورت زیر میشه:[/align]

private class ContactsAdapter extends RecyclerView.Adapter {
       private List contacts;

       public ContactsAdapter(List contacts) {
           this.contacts = contacts;
       }

       @Override
       public ContactHolder onCreateViewHolder(ViewGroup parent, int viewType) {

       }

       @Override
       public void onBindViewHolder(ContactHolder holder, int position) {

       }

       @Override
       public int getItemCount() {
           return contacts.size();
       }
   }

خب همونطور که مشخصه یک فیلد به کلاسمون اضافه کردیم که اون رو در سازنده مقداردهی کردیم (لیست Contact ها) و همچنین متد getItemCount رو تغییر دادیم تا اندازه لیست رو برگردونه (درباره این متد در قسمت قبل توضیح کامل دادم)

حالا متد onCreateViewHolder رو به صورت زیر تغییر میدیم:

@Override
public ContactHolder onCreateViewHolder(ViewGroup parent, int viewType) {
   LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
   View v = inflater.inflate(R.layout.list_item, parent, false);
   return new ContactHolder(v);
}

خب دو خط اول که مشخصه. یک LayoutInflater ایجاد کردیم تا از فایل list_item یک View بسازیم. به دستور return دقت کنید: همونطور که مشخصه نوع بازگشتی این متد باید از جنس ContactHolder باشه یعنی همون ViewHolder ای که تعریف کرده بودیم. پس در دستور return یک شی از جنس ContactHolder میسازیم و View ای که ایجاد کردیم رو به سازنده کلاس ContactHolder میدیم تا اون رو درون خودش نگهداری کنه.

سپس متد onBindViewHolder رو به صورت زیر تغییر میدیم:

@Override
public void onBindViewHolder(ContactHolder holder, int position) {
   Contact contact = contacts.get(position);
   holder.tvContactName.setText(contact.getName());
   holder.tvContactRegisterDate.setText(contact.getRegisterDate().toString());
}

در این متد همونطور که میدونید برای چسباندن اطلاعات به ViewHolder هامون استفاده میشه، یک شی از جنس Contact ایجاد کردیم و مقدار اون رو از لیست Contactهامون گرفتیم. پارامتر position شماره آیتم مورد نظر از لیست رو به متد میده یعنی اگر مثلا قراره به آیتم سوم لیست اطلاعات چسبونده بشه اونوقت position برابر با 3 خواهد بود. از این پارامتر برای دریافت Contact مورد نظر از لیستمون استفاده کردیم.

پارامتر holder هم به این متد داده میشه که یعنی باید به این ViewHolder اطلاعات مورد نظرت رو بچسبونی.

در دو خط بعدی به دو TextView ای که در holder مون قرار داده اطلاعات دادیم. (البته این دو خط کد الان ارور میدن چون فعلا ViewHolder ما tvContactName و tvContactRegisterDate رو نداره)

پس حالا کلاس ViewHolder مون رو تکمیل می کنیم:

private class ContactHolder extends RecyclerView.ViewHolder {
   private TextView tvContactName, tvContactRegisterDate;

   public ContactHolder(View itemView) {
       super(itemView);
       tvContactName = (TextView) itemView.findViewById(R.id.contact_name_textview);
       tvContactRegisterDate = (TextView) itemView.findViewById(R.id.contact_register_date_textview);
   }
}

این کدها واضح هستند و نیازی به توضیح ندارند.

قدم آخر اینه که یک شی از این Adapter بسازیم و با استفاده از متد setAdapter که برای RecyclerView هست، ادپتر RecyclerView مون رو مشخص کنیم. این دو خط هم باید در متد onCreate باشند بعد از کد ایجاد لیست که در ابتدا نوشتیم:

ContactsAdapter adapter = new ContactsAdapter(contacts);
contactsRecyclerView.setAdapter(adapter);

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

public class MainActivity extends AppCompatActivity {
   private RecyclerView contactsRecyclerView;

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

       contactsRecyclerView = (RecyclerView) findViewById(R.id.contacts_recyclerview);
       contactsRecyclerView.setLayoutManager(new LinearLayoutManager(this));

       List contacts = new ArrayList<>();
       for (int i = 0; i < 50; i++) {
           contacts.add(new Contact("Contact #" + i));
       }

       ContactsAdapter adapter = new ContactsAdapter(contacts);
       contactsRecyclerView.setAdapter(adapter);
   }

   private class ContactsAdapter extends RecyclerView.Adapter {
       private List contacts;

       public ContactsAdapter(List contacts) {
           this.contacts = contacts;
       }

       @Override
       public ContactHolder onCreateViewHolder(ViewGroup parent, int viewType) {
           LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
           View v = inflater.inflate(R.layout.list_item, parent, false);
           return new ContactHolder(v);
       }

       @Override
       public void onBindViewHolder(ContactHolder holder, int position) {
           Contact contact = contacts.get(position);
           holder.tvContactName.setText(contact.getName());
           holder.tvContactRegisterDate.setText(contact.getRegisterDate().toString());
       }

       @Override
       public int getItemCount() {
           return contacts.size();
       }
   }

   private class ContactHolder extends RecyclerView.ViewHolder {
       private TextView tvContactName, tvContactRegisterDate;

       public ContactHolder(View itemView) {
           super(itemView);
           tvContactName = (TextView) itemView.findViewById(R.id.contact_name_textview);
           tvContactRegisterDate = (TextView) itemView.findViewById(R.id.contact_register_date_textview);
       }
   }
}

حالا برنامه رو اجرا کنید تا نتیجه زیر رو ببینید:

[align=center]257x461http://uupload.ir/files/77m_untitled.png[/img]

[align=right]خب کار ما تموم شد البته ما از تمام قابلیت های RecyclerView که در مطلب اول گفتم استفاده نکردیم اما امیدوارم با خوندن این آموزش ها مبانی RecyclerView رو یادگرفته باشید و برید دنبال امکانات پیشرفته تر این ویجت تا بتونید از این کتابخونه قدرتمند در پروژه هاتون استفاده کنید.

موفق باشید[/align]

[/align]

لینک ارسال
به اشتراک گذاری در سایت های دیگر
  • 2 ماه بعد...

با سلام و تشکر از آموزشتون

متود معادل با onListItemClick که در لیست ویو وجود داشت در ریسایکر ویو چیه و چطور ازش استفاده میشه ؟

لینک ارسال
به اشتراک گذاری در سایت های دیگر

چند راه برای این کار وجود داره که راه ساده ترش اینه که برای عناصر موجود توی لیستتون رویداد کلیک تعریف کنید و این کار رو باید توی کلاس ViewHolder تون انجام بدید. مثلا تو این آموزش می تونید برای TextView اولی که نام مخاطب رو نشون میده یک رویداد onClick تعریف کنید.

لینک ارسال
به اشتراک گذاری در سایت های دیگر
  • 1 ماه بعد...
  • 1 سال بعد...

سلام و ممنون بابت آموزشتون من یه برنامه ساختم که از recycler view  استفاده می کنه مشکل من در رابطه با بخش علاقه مندیه که آیتم همون لحظه اضافه نمیشه و موقع اجرای مجدد برنامه لیست آپدیت میشه . سوالمو تو همین انجمن هم مطرح کردم . 

لینک ارسال
به اشتراک گذاری در سایت های دیگر

به گفتگو بپیوندید

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

مهمان
ارسال پاسخ به این موضوع...

×   شما در حال چسباندن محتوایی با قالب بندی هستید.   حذف قالب بندی

  تنها استفاده از 75 اموجی مجاز می باشد.

×   لینک شما به صورت اتوماتیک جای گذاری شد.   نمایش به صورت لینک

×   محتوای قبلی شما بازگردانی شد.   پاک کردن محتوای ویرایشگر

×   شما مستقیما نمی توانید تصویر خود را قرار دهید. یا آن را اینجا بارگذاری کنید یا از یک URL قرار دهید.

×
×
  • اضافه کردن...