بایگانی برچسب: آموزش برنامه نویسی اندروید مشهد

چگونه برنامه نویسی را شروع کنیم ؛ ۸ گام برای ساخت اپلیکیشن از ابتدا

چگونه برنامه نویسی را شروع کنیم

  • بهترین روش برای یادگیری کد نویسی چیست؟
  • چگونه تبدیل به یک برنامه نویس شویم؟
  • چطور یک برنامه بنویسیم؟

اینها از جمله پرسش هایی هستند که اغلب مبتدیان مشتاق به برنامه نویسی می پرسند و بدون شک شما نیز درباره ی این موضوع جستجوهایی را در اینترنت داشته اید. اما اگر شما درباره ی این سوالات جستجو نکرده، لازم است بدانید که ما در ادامه ۳ گام را برای پاسخ دادن به این سوالات معرفی می کنیم:

  • مرحله اول: زبان برنامه نویسی انتخاب کنید
  • مرحله ۲: زبان برنامه نویسی را بیاموزید
  • مرحله ۳: یک برنامه بنویسید و دانشتان را از این طریق در ذهن ثبت کنید.

جواب های زیادی برای مراحل ۱ و ۲ وجود دارد و با جستجوی ساده در اینترنت با آنها مواجه خواهید شد.

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

در ادامه ی این مطلب از آکادمی برنامه نویسان سعی می کنیم فرآیند  شروع و ایجاد طرح اولیه تا ساخت برنامه را برایتان ارائه دهیم.

پیش نیازها ی چگونه برنامه نویسی را شروع کنیم

اکثر برنامه ها به یک پایگاه داده نیاز دارند و در نتیجه اگر قصد دارید یک برنامه ی جدید را برای خودتان بسازید، به احتمال زیاد به زبان پرس و جوی پایگاه داده (SQL) نیاز خواهید داشت. مگر اینکه برنامه ای داشته باشید که نیاز به برقراری ارتباط با sql نداشته باشد، مانند flappy bird.

علاوه براین، اگر به دنبال ساخت برنامه برای وب هستید، در نتیجه نیاز دارید تا اساس DevOps را بشناسید و برای ایجاد محیط client/server و توسعه ی آن قادر به اجرای برنامه در محیط واقعی باشید.

در شرایطی که فقط قصد دارید به عنوان یک front-end توسعه دهنده وب فعالیت داشته باشید، HTML، CSS، جاوا اسکریپت و داشتن مهارت در codepen یا JSfiddle برایتان ضروری می باشد. در شرایطی که فقط به جاوا اسکریپت مسلط هستید و نمی خواهید زبان برنامه نویسی دیگری را یاد بگیرید، می توانید node.js را امتحان کنید، چون این پلت فرم جاوا اسکریپت برای back-end می باشد (علاوه براین، می توانید از MongoDB به عنوان پایگاه داده استفاده کنید چون بر اساس جاوا اسکریپت می باشد)

در غیر این صورت، اگر میخواهید یک برنامه وب کامل را ایجاد کنید، باید یکی از زبان های زیر را یاد بگیرید:

  • RUBY
  • پایتون
  • PHP
  • Java
  • GO
  • C#

در شرایطی که می خواهید بازی بسازید، نیاز به یادگیریLua می باشد، هر چند که c# یک انتخاب عالی برای ساخت بازی های سه بعدی می باشد. برای توسعه ی اپلیکیشن های تلفن همراه شما نیاز  دارید swiff/objective-c را برای توسعه ی ios و جاوا را برای برنامه نویسی اندروید بیاموزید.

گام اول: خودتان را بشناسید

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

برای مثال:

  • از کدام برنامه ها بیشترین استفاده را میکنید؟
  • بدون کدام برنامه ها نمی توانید زندگی کنید؟
  • آیا به بازی علاقه مند هستید؟
  • آیا به طراحی علاقه مند هستید؟
  • و غیره

بعد از شناسایی علایق، می توانید تصمیم بگیرید که به چه چیزی علاقه مند هستید و از چه کاری لذت میبرید.

مرحله ۲: ایده پردازی کنید

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

در اینجا منظور این نیست که اگر برای مثال میخواهید یک بازی بسازید، counterstike بعدی را طراحی کنید، بلکه شما باید یک بازی ساده تر از flappy bird را طراحی و بسازید.

بنابراین، بر اساس علایقتان و ایده ای که برای ساخت یک برنامه ساده در ذهن دارید کار را شروع کنید. اصلا مهم نیست که برنامه قبلا وجود داشته یا خیر.

در ادامه چند مثال ارائه می دهید که این موضوع و ایده پردازی را برایتان آسان تر کند:

  • اگر به آشپزی علاقه مند هستید، یک برنامه که دستور پخت غذاهای خانگی را آموزش دهد می تواند ایده ی خوبی باشد
  • اگر علاقه مند هستید که توییتر چطور کار میکند، سعی کنید یک نمونه ی بسیار ساده از توییتر را بسازید
  • اگر فردی بسیار فراموش کار هستید، سعی کنید یک برنامه برای خودتان بسازید
  • اگر به کارت بازی علاقه مند هستید، سعی کنید یک نمونه ی ساده از آن را بسازید

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

۳- قابلیت های اصلی برنامه تان را لیست کنید

اگر به فکر ساخت یک برنامه هستید، قابلیت ها و توانایی های آن را لیست کنید. با قرار گرفتن قابلیت ها در یک لیست باعث میشود تا نگاه بهتری به برنامه داشته باشید و موارد غیر ضروری را حذف کنید. برای مثال می توانید مشخص کنید که آیا برنامه ی شما واقعا نیاز به ورود به فیسبوک دارد یا خیر؟

خیلی خوب است که برنامه تان کامل باشد و تمام قابلیت های عالی را داشته باشد، اما برای شروع کار خیلی ضروری نیست و باید با نمونه های ساده شروع به کار کنید. هیچ وقت سعی نکنید یک برنامه همه جانبه داشته باشید. مگر اینکه واقعا علاقه ی زیادی به چالش داشته باشید و با سختی ها دلسرد نشوید.

برای مثال در ساخت برنامه های مانند Reddit ویژگی های زیر ضروری می باشند:

  • ایجاد حساب کاربری
  • بازیابی رمزهای عبور
  • تغییر رمز عبور
  • ارسال لینک های جدید
  • ارسال نظر روی لینک
  • افزایش یا کاهش لینک
  • داشتن پروفایل برای نمایش history/activity

اما در مقابل ویژگی های زیر ضروری نیست و برای ساخت اولین برنامه ها غیرضروری هستند.

  • اشتراک گذاری مطالب در شبکه های اجتماعی
  • حذف نظرات
  • ویرایش نظرات
  • حذف حساب کاربری

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

آموزش برنامه نویسی در مشهد

۴- طراحی برنامه

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

مدام یادداشت کنید و طرح را تغییر دهید تا زمانیکه کاملا بتوانید از طرح نهایی راضی شوید. البته بخاطر داشته باشید که، طرح کاملا ساده باشد.

آموزش برنامه نویسی اندروید در مشهد

۵- فلوچارت جریان کاری برنامه را رسم کنید

خیلی خوب و مهم است که بدانید برنامه تان چه چیز هایی لازم دارد و چه عناصری برای آن لازم می باشد و کاربران چطور با آن ارتباط برقرار می کنند. فلوچارت ui در اینجا یعنی اینکه کاربر چطور باید از ابتدا تا آخر از برنامه استفاده کند. برای هر گام نمودار را رسم کنید و سناریوهای مختلف را ترسیم کنید.

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

۶- پایگاه داده طراحی کنید

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

برای برنامه هایی که نیاز دارید تا با سرور ارتباط برقرار کنید (به عنوان مثال یک برنامه کامل تحت وب fullstock)) یا اگر برنامه تان با یک API ارتباط برقرار می کند (مثلا بخواهید اطلاعات را از Yahoo weather دریافت کنید) حتما باید نمودار توالی را رسم کنید تا نحوه ی عملکرد هر فعالیت را شناسایی نمایید.

طراحی ux

UX Wireframe

تا این قسمت از کار، بر روی back end تمرکز داشتید و حالا باید بتوانید به front end نیز دقت کنید. با توجه به اینکه انسان ها موجوداتی بصری هستند، در نتیجه لازم است تا زمان بیشتری را برای درک اینکه چه کاری باید انجام دهید تا دید بصری داشته باشید، اختصاص دهید. خوشبختانه ابزارهای زیادی موکاپ و wireframing برای کمک به رسم جریان UX/UIبه صورت آنلاین وجود دارد (برای مثال framebox, mockflow, Gliffy و غیره)

گام ۶٫۵ (اختیاری): طراحی UI

این گام کاملا اختیاری می باشد و در توسعه ی برنامه در سمت front end به صورت حرفه ای تر می تواند موثر باشد. علاوه بر این، با این گام می توانید متوجه شوید که برنامه بعد از تبدیل شدن به اپلیکیشن نهایی چطور بنظر میرسد و در نتیجه راحت تر می توانید کدنویسی کنید.

اگر قصد دارید طراحی رابط کاربری را انجام دهید، به احتمال زیاد این کار را قبل از انجام هرکاری شروع خواهید کرد. این کار در مرحله ۲ نیز انجام خواهد شد

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

گام ۷: تحقیق برای بهترین راه حل

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

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

به دنبال راه حل باشید

به نموداری که در مرحله دو کشیدید نگاه کنید. چه چیزهایی در این نمودار وجود دارند که اصلا به نحوه ی ساخت آنها فکر نمیکنید؟

برای مثال، آیا کاربر نیاز به ایجاد حساب کاربری دارد؟ آیا برنامه نیاز به بروزرسانی در زمان واقعی دارد؟

در بسیاری از مواقع، بهترین کار استفاده از توابع بروزرسانی در زمان واقعی (مانند firebase)، مسیریابی/شبکه (مانند AFNetworking برای ios)، احراز هویت و قطعات مرتبط با رابط کاربری می باشد (مانند flipboard یا pintrerest-esque)

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

در هر صورت، بهترین کار مطالعه ی کارها و روش هایی می باشد که سایر توسعه دهندگان قبلا استفاده نموده اند. برای این منظور می توانید از github استفاده کنید.

انتخاب ابزار برای شروع

اگر شما در حال ساخت یک برنامه تحت وب هستید، شاید بتوانید yeoman را به منظور کمک در سرعت بخشیدن به پروژه استفاده نمایید.

اگر در حال ساخت یک برنامه React هستید، میتوانید از کیت های استارتر موجود در پیاده سازی های FLUX استفاده نمایید.HTML5Boilerplate و Bootstrap قالب های رایج Front end برای برنامه ی شما محسوب میشوند. در اغلب موارد Boilerplate از Glup یا Grunt برای مدیریت وظایف استفاده میکند.

از آنجا که به احتمال زیاد میخواهید با استفاده از برخی قطعات موجود با راه حل ها استفاده کنید، در نتیجه باید اجازه ی نصب مرورگر داده شود تا وابستگی ها مدیریت گردند (np برای کسانی که از node.js استفاده می کنند و cocoaPods برای توسعه دهندگان ios). نگران نباشید، اغلب این ابزارها به شما روش نصب را آموزش می دهند.

گام هشتم: ساخت برنامه

در این مرحله شما آماده هستید تا برنامه مورد نظرتان را بسازید. اما چند نکته وجود دارد که باید رعایت کنید.

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

چک لیست تهیه کنید

شما باید بر روی توابع اصلی برنامه تمرکز داشته باشید. بنابراین، اگر با یکی از کارهای مانند سیستم نظر سنجی کار نمیکند، نباید بلافاصله شروع به ساخت یک پروفایل view کنید. به عبارت دیگر، اگر شما در حال ساخت یک فرم هستید، باید روی کدهای سمت front و back end به صورت همزمان کار کنید تا زمانیکه کار به طور کامل انجام شود.

به طور خلاصه می توان گفت، از کارهایی که باید انجام شود چک لیست تهیه نمایید.

اول تست کنید

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

بنابراین این یک ایده ی خوب می باشد که کارهای کوچک را شروع کنید و به انجام دادن تست توسعه (TDD) عادت کنید؛ مخصوصا زمانی که تازه کار هستید.

ابزارهای تست زیادی برای این منظور وجود دارند، مانند Jasmine یا karma برای جاوا اسکریپت، Rspec برای Ruby، PyTest برای پایتون، PHPUnit برای PHP و Quick به عنوان یک جایگزین xctest برای توسعه دهندگان ios

علاوه براین، اگر در حال ساخت یک برنامه ios یا اندروید هستید، استفاده از Crashlytics یک ایده ی خوب می باشد.

از گیت استفاده کنید

Git یک سیستم کنترل نسخه می باشد که مخزن کاملی از تغییرات موجود بر روی برنامه می باشد که قابلیت ردیابی کامل تغییرات را دارد. بهترین کار در همان ابتدای شروع برنامه نویسی، یادگیری نحوه ی کار با گیت می باشد. با استفاده از گیت می توانید براحتی اشتباهاتتان را اصلاح کنید و داده های از دست رفته را بازیابی نمایید. علاوه براین، اگر قصد دارید به صورت گروهی روی یک برنامه کار کنید، استفاده از گیت ضروری می باشد. github محبوب ترین سرویس میزبانی از مخزن git برای پروژه های منبع باز می باشد و Bitbucket برای مخازن خصوصی مورد استفاده قرار میگیرد.

گوگل

در گام ۷ به google-fu اشاره کردیم، اما دوباره باید بگوییم که یادگیری اینکه گوگل یک مهارت مهم برای برنامه نویسان می باشد بسیار ضروری است. اگر در یک قطعه از کد با مشکل برخورد کرده باشید، اما ندانید که چطور آن را برطرف کنید، گوگل بهترین راه حل خواهد بود.

در stackoverflow سوال بپرسید

به احتمال بسیار زیاد، در حین جستجو برای پاسخ سوالات با stackoverflow برخورد کرده اید. یکی از بهترین راه ها برای دست یافتن به جواب سوالاتتان، بدون شک سوال پرسیدن در stackoverflow خواهد بود.

مربی آموزش برنامه نویسی پیدا کنید

بسیاری از افراد معتقدند که stackoverflow برای مبتدیان زیاد مناسب نیست، زیرا مبتدیان نمی دانند که چطور باید سوالات خود را بیان کنند. اما راه حل چیست؟

در این شرایط، هیچ چیز به اندازه ی استفاده از برنامه نویس با تجربه نمی تواند راه را برایتان آسان کند. در نتیجه بهتر است در جلسات زنده در Codementor، استفاده کنید که نرخ هر مربی ۱۵ دلار در دقیقه می باشد. در طول این جلسات می توانید از چت ویدئویی با توسعه دهندگان با تجربه تبادل نظر کنید و کدهای خود را با آنها به اشتراک گذاشته و آنها نحوه ی اصلاح و تغییر در کد را به شما آموزش خواهند داد.

سخن آخر چگونه برنامه نویسی را شروع کنیم ?

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

اضافه کردن فیلتر جستجو با RecyclerView در اندروید

آموزش اندروید مشهد

در مطالب قبل درباره ی Recyclerview صحبت کردیم و نکاتی را در مورد ترکیب آن با Cardview و اضافه کردن Swipe برای توابع حذف و غیره اشاره کردیم. در این مقاله قصد داریم نحوه ی اضافه کردن قابلیت فیلتر جستجو به recyclerview را آموزش دهیم. ساخت جستجو در اندروید کار بسیار ساده ای می باشد و از ویجت نوار ابزار جستجو برای ورود متن جستجو استفاده میشود. برای نشان دادن این موضوع، یک مثال با لیست تماس و جستجو بر اساس نام و شماره تماس را ارائه خواهیم داد.

 

 

()RecyclerView Search Filter – getFilter

اندروید کلاس های قابل فیلتر شدن برای فیلتر کردن داده ها با استفاده از یک فیلتر یا شرط را فراهم می کند. معمولا متد getfilter()  مجبور است در کلاس آداپتور که شرط فیلتر کردن برای جستجو در آن قرار دارد، اصطلاحا override شود. در قطعه کد زیر یک مثال از متد getfilter() نمایش  داده شده که یک مخاطب را بر اساس نام و شماره تماس از لیست مخاطبان جستجو می کند.

@Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String charString = charSequence.toString();
                if (charString.isEmpty()) {
                    contactListFiltered = contactList;
                } else {
                    List<Contact> filteredList = new ArrayList<>();
                    for (Contact row : contactList) {

                        // name match condition. this might differ depending on your requirement
                        // here we are looking for name or phone number match
                        if (row.getName().toLowerCase().contains(charString.toLowerCase()) || row.getPhone().contains(charSequence)) {
                            filteredList.add(row);
                        }
                    }

                    contactListFiltered = filteredList;
                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = contactListFiltered;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                contactListFiltered = (ArrayList<Contact>) filterResults.values;

                // refresh the list with filtered data
                notifyDataSetChanged();
            }
        };
    }

 

مثال json

برای این مثال ساخت جستجو در اندروید ، قصد داریم تا از json که لینک آن را قرار داده ایم، استفاده کنیم. این جیسون شامل لیستی از مخاطبین می باشد که هر مخاطب نام، شماره تلفن و تصویر پروفایل دارد.

https://acdev.ir/wp-content/uploads/2019/01/json/contacts.json

[{
        "name": "Tom Hardy",
        "image": "https://api.androidhive.info/json/images/tom_hardy.jpg",
        "phone": "(541) 754-3010"
    },
    {
        "name": "Johnny Depp",
        "image": "https://api.androidhive.info/json/images/johnny.jpg",
        "phone": "(452) 839-1210"
    }
]

 

ایجاد پروژه ی جدید

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

۱- یک پروژه ی جدید در اندروید استودیو از مسیر file/new project ایجاد و basic activity را از الگوها انتخاب کنید.

۲- build.gradle را در زیر فولدر app باز کنید و وابستگی های Recyclerview، Glide  و Volley را اضافه کنید.

build.gradle
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // ...
 
    // recycler view
    implementation 'com.android.support:recyclerview-v7:26.1.0'
 
    // glide image library
    implementation 'com.github.bumptech.glide:glide:4.3.1'
 
    // volley http library
    implementation 'com.android.volley:volley:1.0.0'
    implementation 'com.google.code.gson:gson:2.6.2'
 
}

۳- منابع زیر را به فایل های string.xml، dimens.xml و colors.xml اضافه کنید.

strings.xml
<resources>
    <string name="app_name">RecyclerView Search</string>
    <string name="action_settings">Settings</string>
    <string name="toolbar_title">Contacts</string>
    <string name="action_search">Search</string>
    <string name="search_hint">Type name…</string>
</resources>
dimens.xml
<resources>
    <dimen name="fab_margin">16dp</dimen>
    <dimen name="activity_margin">16dp</dimen>
    <dimen name="thumbnail">40dp</dimen>
    <dimen name="row_padding">10dp</dimen>
    <dimen name="contact_name">15dp</dimen>
    <dimen name="contact_number">12dp</dimen>
</resources>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#111</color>
    <color name="colorPrimaryDark">#FFF</color>
    <color name="colorAccent">#ea3732</color>
    <color name="contact_name">#333333</color>
    <color name="contact_number">#8c8c8c</color>
</resources>

 

۴- فایل  res.zip را دانلود و آیکون های مورد نیاز برای جستجو که در این فولدر قرار دارند را به پروژه اضافه نمایید.

۵- یک کلاس به نام MyApplication.java را ایجاد و کلاس را از Application گسترش دهید. این کلاس در volley مقداردهی اولیه میشود.

MyApplication.java
package info.androidhive.recyclerviewsearch;
 
/**
 * Created by ravi on 16/11/17.
 */
 
import android.app.Application;
import android.text.TextUtils;
 
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
 
public class MyApplication extends Application {
 
    public static final String TAG = MyApplication.class
            .getSimpleName();
 
    private RequestQueue mRequestQueue;
 
    private static MyApplication mInstance;
 
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }
 
    public static synchronized MyApplication getInstance() {
        return mInstance;
    }
 
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
 
        return mRequestQueue;
    }
 
    public <T> void addToRequestQueue(Request<T> req, String tag) {
        // set the default tag if tag is empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }
 
    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }
 
    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

 

۶- AndroidManifest.xml را باز کنید و Myapplication را به تگ <application> اضافه کنید. علاوه براین، مجوز Intertnet را برای فراخوانی http اضافه نمایید.

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.recyclerviewsearch">
 
    <uses-permission android:name="android.permission.INTERNET" />
 
    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
 
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>

 

۷- در این مرحله نیاز داریم تا جیسون آنالیز خوانده شود و به یک کلاس pojo برای مرتب کردن جیسون نیاز داریم. یک کلاس به نام Contact.java ایجاد و name، image و phone number را اضافه کنید.

Contact.java
package info.androidhive.recyclerviewsearch;
 
/**
 * Created by ravi on 16/11/17.
 */
 
public class Contact {
    String name;
    String image;
    String phone;
 
    public Contact() {
    }
 
    public String getName() {
        return name;
    }
 
    public String getImage() {
        return image;
    }
 
    public String getPhone() {
        return phone;
    }
}

 

۸- یک کلاس به نام MyDividerItemDecoration.java را ایجاد کنید. این گام کاملا اختیاری بوده اما برای اضافه کردن حاشیه ی بیشتر به RecyclerView divider می باشد. این یک کلاس تقسیم کننده ی اختیاری برای اضافه کردن حاشیه ی چپ به خط تقسیم می باشد.

package info.androidhive.recyclerviewsearch;
 
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.View;
 
/**
 * Created by ravi on 17/11/17.
 */
 
public class MyDividerItemDecoration  extends RecyclerView.ItemDecoration {
 
    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };
 
    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
 
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
 
    private Drawable mDivider;
    private int mOrientation;
    private Context context;
    private int margin;
 
    public MyDividerItemDecoration(Context context, int orientation, int margin) {
        this.context = context;
        this.margin = margin;
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(orientation);
    }
 
    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }
 
    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }
 
    public void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
 
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left + dpToPx(margin), top, right, bottom);
            mDivider.draw(c);
        }
    }
 
    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();
 
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top + dpToPx(margin), right, bottom - dpToPx(margin));
            mDivider.draw(c);
        }
    }
 
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
 
    private int dpToPx(int dp) {
        Resources r = context.getResources();
        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
    }
}

 

نوشتن کلاس آداپتور با فیلتر

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

۹- یک لایه به نام user_row_item.xml ایجاد و لایه ی زیر را اضافه کنید. این لایه آیتم مخاطب در لیست را به عنوان خروجی ارائه می دهد. این لایه شامل دو textview برای ارائه ی name،       phone number و یک imageview برای نمایش تصویر پروفایل می باشد.

user_row_item.xml
<?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="wrap_content"
    android:background="?attr/selectableItemBackground"
    android:clickable="true"
    android:paddingBottom="@dimen/row_padding"
    android:paddingLeft="@dimen/activity_margin"
    android:paddingRight="@dimen/activity_margin"
    android:paddingTop="@dimen/row_padding">
 
    <ImageView
        android:id="@+id/thumbnail"
        android:layout_width="@dimen/thumbnail"
        android:layout_height="@dimen/thumbnail"
        android:layout_centerVertical="true"
        android:layout_marginRight="@dimen/row_padding" />
 
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/thumbnail"
        android:fontFamily="sans-serif-medium"
        android:textColor="@color/contact_name"
        android:textSize="@dimen/contact_name" />
 
    <TextView
        android:id="@+id/phone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/name"
        android:layout_toRightOf="@id/thumbnail"
        android:textColor="@color/contact_number"
        android:textSize="@dimen/contact_number" />
 
</RelativeLayout>

 

۱۰- یک کلاس به نام ContactsAdapter.java ایجاد و آن را از کلاسFilterable به صورت implement پیاده سازی کنید تا از شما خواسته شود تا متد getfilter() را override کنید.

ContactsAdapter.java
package info.androidhive.recyclerviewsearch;
 
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
 
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * Created by ravi on 16/11/17.
 */
 
public class ContactsAdapter extends RecyclerView.Adapter<ContactsAdapter.MyViewHolder>
        implements Filterable {
    private Context context;
    private List<Contact> contactList;
    private List<Contact> contactListFiltered;
    private ContactsAdapterListener listener;
 
    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView name, phone;
        public ImageView thumbnail;
 
        public MyViewHolder(View view) {
            super(view);
            name = view.findViewById(R.id.name);
            phone = view.findViewById(R.id.phone);
            thumbnail = view.findViewById(R.id.thumbnail);
 
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // send selected contact in callback
                    listener.onContactSelected(contactListFiltered.get(getAdapterPosition()));
                }
            });
        }
    }
 
 
    public ContactsAdapter(Context context, List<Contact> contactList, ContactsAdapterListener listener) {
        this.context = context;
        this.listener = listener;
        this.contactList = contactList;
        this.contactListFiltered = contactList;
    }
 
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.user_row_item, parent, false);
 
        return new MyViewHolder(itemView);
    }
 
    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        final Contact contact = contactListFiltered.get(position);
        holder.name.setText(contact.getName());
        holder.phone.setText(contact.getPhone());
 
        Glide.with(context)
                .load(contact.getImage())
                .apply(RequestOptions.circleCropTransform())
                .into(holder.thumbnail);
    }
 
    @Override
    public int getItemCount() {
        return contactListFiltered.size();
    }
 
    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String charString = charSequence.toString();
                if (charString.isEmpty()) {
                    contactListFiltered = contactList;
                } else {
                    List<Contact> filteredList = new ArrayList<>();
                    for (Contact row : contactList) {
 
                        // name match condition. this might differ depending on your requirement
                        // here we are looking for name or phone number match
                        if (row.getName().toLowerCase().contains(charString.toLowerCase()) || row.getPhone().contains(charSequence)) {
                            filteredList.add(row);
                        }
                    }
 
                    contactListFiltered = filteredList;
                }
 
                FilterResults filterResults = new FilterResults();
                filterResults.values = contactListFiltered;
                return filterResults;
            }
 
            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                contactListFiltered = (ArrayList<Contact>) filterResults.values;
                notifyDataSetChanged();
            }
        };
    }
 
    public interface ContactsAdapterListener {
        void onContactSelected(Contact contact);
    }
}

 

در متد getfilter()، رشته ی جستجو برای متد performfiltering() ارسال میشود. جستجو برای یک مخاطب با نام، شماره تلفن با رشته ی جستجو ارائه می گردد.

شما باید شرایط جستجو را متناسب با منابع برنامه تان تنظیم کنید.

رابط contactsadapterlistner() متد فراخوانی oncontactselected() را هر زمان که یک مخاطب از لیست انتخاب شود، فراهم خواهد کرد.

اضافه کردن ویجت جستجو و لیست فیلتر کردن

در این مرحله نیاز داریم تا Searchview را در نوار ابزار فعال کنیم و از Recyclerview با کمک آنالیز و خواندن جیسون و انتقال متن جستجو به آداپتور خروجی بگیریم.

۱۱- menu_main.xml را ایجاد یا باز کنید که زیر res/meun قرار گرفته و ویجت searchview را اضافه و آنرا برای همیشه قابل نمایش قرار دهید.

menu_main.xml
<menu 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"
    tools:context="info.androidhive.recyclerviewsearch.MainActivity">
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_search_black_24dp"
        android:orderInCategory="100"
        android:title="@string/action_search"
        app:showAsAction="always"
        app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>

 

۱۲- زیر فولدر res/xml ، یک فایل xml به نام searchable.xml  ایجاد کنید (اگر این فایل از قبل وجود ندارد آنرا ایجاد کنید)

searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:hint="@string/search_hint"
    android:label="@string/app_name" />

 

۱۳- AndroidManifest.xml و configure the search را مانند زیر باز کنید.

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.recyclerviewsearch">
 
    <uses-permission android:name="android.permission.INTERNET" />
 
    <application ...>
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
 
            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
 
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
 
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>

 

۱۴- فایل های لایه را از main activity باز کنید که شامل activity_main.xml و content_main.xml می باشد و اجزای recyclerview را اضافه نمایید.

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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="info.androidhive.recyclerviewsearch.MainActivity">
 
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
 
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@android:color/white"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
 
    </android.support.design.widget.AppBarLayout>
 
    <include layout="@layout/content_main" />
 
</android.support.design.widget.CoordinatorLayout>
content_main.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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="info.androidhive.recyclerviewsearch.MainActivity"
    tools:showIn="@layout/activity_main">
 
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical" />
 
</RelativeLayout>

 

۱۵- در نهایت mainactivity.java را باز و کد های نشان داده شده در زیر را اضافه کنید.

در متد fetchcontacts() یک volley برای بیرون کشیدن جیسون درخواست می کند. بیرون کشیدن یا fetch کردن جیسون با کمک Gson به صورت مرتب انجام شده و تمام مخاطبین به یک لیست اضافه میشوند. فراخونی mAdapter.notifyDataSetChanged() باعث میشود تا از recyclerview خروجی گرفته شود.

در onCreateOptionsMenu() منو inflate شده و searchview نمایش داده میشود.

searchView.setOnQueryTextListener() به تغییر کاراکترها در حین نوشتن در فیلد جستجو گوش میدهد. متن وارد شده برای جستجو تجزیه و تحلیل شده و با کمک mAdapter.getFilter().filter(query) به کلاس آداپتور ارسال میشود و سپس recyclerview با داده های فیلتر شده ی جدید بروز رسانی می گردد.

onContactSelected() زمانیکه یک مخاطب از لیست انتخاب شود، فراخوانی خواهد شد.

MainActivity.java
package info.androidhive.recyclerviewsearch;
 
import android.app.SearchManager;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
 
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
 
import org.json.JSONArray;
 
import java.util.ArrayList;
import java.util.List;
 
public class MainActivity extends AppCompatActivity implements ContactsAdapter.ContactsAdapterListener {
    private static final String TAG = MainActivity.class.getSimpleName();
    private RecyclerView recyclerView;
    private List<Contact> contactList;
    private ContactsAdapter mAdapter;
    private SearchView searchView;
 
    // url to fetch contacts json
    private static final String URL = "https://api.androidhive.info/json/contacts.json";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
 
        // toolbar fancy stuff
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle(R.string.toolbar_title);
 
        recyclerView = findViewById(R.id.recycler_view);
        contactList = new ArrayList<>();
        mAdapter = new ContactsAdapter(this, contactList, this);
 
        // white background notification bar
        whiteNotificationBar(recyclerView);
 
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.addItemDecoration(new MyDividerItemDecoration(this, DividerItemDecoration.VERTICAL, 36));
        recyclerView.setAdapter(mAdapter);
 
        fetchContacts();
    }
 
    /**
     * fetches json by making http calls
     */
    private void fetchContacts() {
        JsonArrayRequest request = new JsonArrayRequest(URL,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        if (response == null) {
                            Toast.makeText(getApplicationContext(), "Couldn't fetch the contacts! Pleas try again.", Toast.LENGTH_LONG).show();
                            return;
                        }
 
                        List<Contact> items = new Gson().fromJson(response.toString(), new TypeToken<List<Contact>>() {
                        }.getType());
 
                        // adding contacts to contacts list
                        contactList.clear();
                        contactList.addAll(items);
 
                        // refreshing recycler view
                        mAdapter.notifyDataSetChanged();
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // error in getting json
                Log.e(TAG, "Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(), "Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
 
        MyApplication.getInstance().addToRequestQueue(request);
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
 
        // Associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView = (SearchView) menu.findItem(R.id.action_search)
                .getActionView();
        searchView.setSearchableInfo(searchManager
                .getSearchableInfo(getComponentName()));
        searchView.setMaxWidth(Integer.MAX_VALUE);
 
        // listening to search query text change
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                // filter recycler view when query submitted
                mAdapter.getFilter().filter(query);
                return false;
            }
 
            @Override
            public boolean onQueryTextChange(String query) {
                // filter recycler view when text is changed
                mAdapter.getFilter().filter(query);
                return false;
            }
        });
        return true;
    }
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
 
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_search) {
            return true;
        }
 
        return super.onOptionsItemSelected(item);
    }
 
    @Override
    public void onBackPressed() {
        // close search view on back button pressed
        if (!searchView.isIconified()) {
            searchView.setIconified(true);
            return;
        }
        super.onBackPressed();
    }
 
    private void whiteNotificationBar(View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int flags = view.getSystemUiVisibility();
            flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
            view.setSystemUiVisibility(flags);
            getWindow().setStatusBarColor(Color.WHITE);
        }
    }
 
    @Override
    public void onContactSelected(Contact contact) {
        Toast.makeText(getApplicationContext(), "Selected: " + contact.getName() + ", " + contact.getPhone(), Toast.LENGTH_LONG).show();
    }
}

 

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

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

آکادمی برنامه نویسان برگزار کننده دوره های آموزش اندروید مشهد و کلاس های برنامه نویسی در مشهد می باشد جهت ثبت نام در این دوره ها با ما در تماس باشید . 

کار با RecyclerView در اندروید

آموزش اندروید

RecyclerView نسخه ی پیشرفته ی ListView می باشد که عملکرد بهتری داشته و مزایای بیشتری نسبت به آن دارد. با استفاده از RecyclerView و Cardview، لیست های نمایش اطلاعات می توانند به آسانی و همچنین زیبا ایجاد شوند. در این مطلب اطلاعات کاملی در مورد RecyclerView ارائه خواهیم داد و نمونه هایی را در این زمینه معرفی می کنیم با آموزش Recyclerview در اندروید با ما همراه باشید.

دانلود پروژه

در این آموزش می آموزید که چطور یک RecyclerView ساده را با یک لایوت سفارشی ایجاد کنید. علاوه براین، یک کلاس آداپتور می نویسیم و list driver یا جدا کننده لیست ها و یک listener را برای کلیک کردن روی ردیف اضافه خواهیم کرد. RecyclerView که ما در این مطلب طراحی می کنیم، یک لیست از فیلم ها را نمایش می دهد که دارای عنوان، ژانر و سال تولید می باشد.

در قطعه کد زیر، ویجت RecyclerView با ویژگی های مورد نیاز را مشاهده می کنید.

<android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

قبل از شروع مطمئن شوید که اندروید استودیو نصب و به آخرین نسخه بروز رسانی شده باشد. در این مطلب از  اندروید استودیو  ۳٫۰ RC 2 استفاده می کنیم.

۱- در اندروید استودیو به مسیر file/new project بروید و تمام جزئیات مورد نیاز برای ایجاد پروژه ی جدید را وارد نمایید و در نهایت Blanck Activity را انتخاب کنید.

۲- build.grade را باز کنید و  وابستگی RecyclerView با کد com.android.support:RecyclerView-v7:26.1.0  را اضافه و پروژه را بازسازی کنید

build.gradle
apply plugin: 'com.android.application'
 
android {
    compileSdkVersion 26
    buildToolsVersion '26.0.2'
    // ..
}
 
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    //..
 
    // RecyclerView
    implementation 'com.android.support:recyclerview-v7:26.1.0'
}

۳- با آخرین نسخه ی ابزارهای ساخت، اندروید استودیو دو فایل لایه را برای هر اکتیویتی ایجاد می کند. برای main activity، دو فایل activity_main.xml (شامل CoordinatorLayout و AppBarLayout می باشد) و content_main.xml (برای محتوای واقعی) را ایجاد می کند. فایل content_main.xml و ویجت RecyclerView  را اضافه کنید .

content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_main"
    tools:context=".MainActivity">
 
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical" />
 
</RelativeLayout>

۴- colors.xml که در زیر res/values قرار دارد را باز کنید و رنگ های زیر را به آن اضافه نمایید.

colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="year">#999999</color>
    <color name="title">#222222</color>
</resources>

۵- dimens.xml در زیر res/values را باز نموده و dimen های زیر را اضافه کنید.

dimens.xml
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="fab_margin">16dp</dimen>
    <dimen name="row_padding_vertical">10dp</dimen>
</resources>

آموزش Recyclerview در اندروید

نوشتن کلاس آداپتور

بعد از اضافه کردن ویجت RecyclerView، حال باید کلاس آداپتور را برای آماده کردن داده ها برای RecyclerView بنویسیم. آداپتور RecyclerView مشابه با ListView بوده اما روش های override کردن متفاوتی دارد.

۶- یک کلاس به نام movie.java را ایجاد و عنوان، ژانر و سال تولید را مشخص کنید. علاوه براین، متدهای getter/setter را برای هر متغیر اضافه کنید.

Movie.java
package info.androidhive.recyclerview;
 
public class Movie {
    private String title, genre, year;
 
    public Movie() {
    }
 
    public Movie(String title, String genre, String year) {
        this.title = title;
        this.genre = genre;
        this.year = year;
    }
 
    public String getTitle() {
        return title;
    }
 
    public void setTitle(String name) {
        this.title = name;
    }
 
    public String getYear() {
        return year;
    }
 
    public void setYear(String year) {
        this.year = year;
    }
 
    public String getGenre() {
        return genre;
    }
 
    public void setGenre(String genre) {
        this.genre = genre;
    }
}

۷- یک لایه xml به نام movie_list_row.xml با کد زیر را ایجاد کنید. این فایل لایه یک سطر از RecyclerView را برای نمایش نام فیلم، ژانر و سال تولید آن به عنوان خروجی ارائه می دهد.

movie_list_row.xml
<?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="wrap_content"
    android:background="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:focusable="true"
    android:orientation="vertical"
    android:paddingBottom="@dimen/row_padding_vertical"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/row_padding_vertical">
 
    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:textColor="@color/title"
        android:textSize="16dp"
        android:textStyle="bold" />
 
    <TextView
        android:id="@+id/genre"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/title" />
 
    <TextView
        android:id="@+id/year"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:textColor="@color/year" />
 
</RelativeLayout>

۸- یک کلاس به نام movieAdapter.java را ایجاد و قطعه کد زیر را وارد نمایید. در اینجا متد onCreateViewHolder ()، فایل movie_list_row.xml را اصطلاحا inflates می کند. در متد onBindViewHolder()، اطلاعات مربوط به فیلم از قبیل عنوان، ژانر و سال برای هر سطر در نظر گرفته میشود.

MoviesAdapter.java
package info.androidhive.recyclerview;
 
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
 
import java.util.List;
 
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {
 
    private List<Movie> moviesList;
 
    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView title, year, genre;
 
        public MyViewHolder(View view) {
            super(view);
            title = (TextView) view.findViewById(R.id.title);
            genre = (TextView) view.findViewById(R.id.genre);
            year = (TextView) view.findViewById(R.id.year);
        }
    }
 
 
    public MoviesAdapter(List<Movie> moviesList) {
        this.moviesList = moviesList;
    }
 
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.movie_list_row, parent, false);
 
        return new MyViewHolder(itemView);
    }
 
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Movie movie = moviesList.get(position);
        holder.title.setText(movie.getTitle());
        holder.genre.setText(movie.getGenre());
        holder.year.setText(movie.getYear());
    }
 
    @Override
    public int getItemCount() {
        return moviesList.size();
    }
}

۹- در این مرحله باید mainactivity.java را باز کنید و تغییرات زیر را روی آن اعمال نمایید. متد prepareMovieData() در اینجا داده های نمونه را به list view اضافه می کند.

MainActivity.java
package info.androidhive.recyclerview;
 
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
 
import java.util.ArrayList;
import java.util.List;
 
public class MainActivity extends AppCompatActivity {
    private List<Movie> movieList = new ArrayList<>();
    private RecyclerView recyclerView;
    private MoviesAdapter mAdapter;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
 
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
 
        mAdapter = new MoviesAdapter(movieList);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(mAdapter);
 
        prepareMovieData();
    }
 
    private void prepareMovieData() {
        Movie movie = new Movie("Mad Max: Fury Road", "Action & Adventure", "2015");
        movieList.add(movie);
 
        movie = new Movie("Inside Out", "Animation, Kids & Family", "2015");
        movieList.add(movie);
 
        movie = new Movie("Star Wars: Episode VII - The Force Awakens", "Action", "2015");
        movieList.add(movie);
 
        movie = new Movie("Shaun the Sheep", "Animation", "2015");
        movieList.add(movie);
 
        movie = new Movie("The Martian", "Science Fiction & Fantasy", "2015");
        movieList.add(movie);
 
        movie = new Movie("Mission: Impossible Rogue Nation", "Action", "2015");
        movieList.add(movie);
 
        movie = new Movie("Up", "Animation", "2009");
        movieList.add(movie);
 
        movie = new Movie("Star Trek", "Science Fiction", "2009");
        movieList.add(movie);
 
        movie = new Movie("The LEGO Movie", "Animation", "2014");
        movieList.add(movie);
 
        movie = new Movie("Iron Man", "Action & Adventure", "2008");
        movieList.add(movie);
 
        movie = new Movie("Aliens", "Science Fiction", "1986");
        movieList.add(movie);
 
        movie = new Movie("Chicken Run", "Animation", "2000");
        movieList.add(movie);
 
        movie = new Movie("Back to the Future", "Science Fiction", "1985");
        movieList.add(movie);
 
        movie = new Movie("Raiders of the Lost Ark", "Action & Adventure", "1981");
        movieList.add(movie);
 
        movie = new Movie("Goldfinger", "Action & Adventure", "1965");
        movieList.add(movie);
 
        movie = new Movie("Guardians of the Galaxy", "Science Fiction & Fantasy", "2014");
        movieList.add(movie);
 
        mAdapter.notifyDataSetChanged();
    }
}

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

آموزش Recyclerview در اندروید

افزودن  Divider/Separator (جدا کننده) به RecyclerView

شما می توانید با استفاده از DividerItemDecoration که توسط کتابخانه پشتیبانی میشود، یک خط جدا کننده بین سطرها ایجاد نمایید. آیتم های زیباسازی را مانند زیر به RecyclerView اضافه کنید.

recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
 
// set the adapter
recyclerView.setAdapter(mAdapter);

با اجرای برنامه متوجه خواهید شد که یک خط جداکننده بین هر سطر قرار گرفته است

ساخت خط تقسیم سفارشی با حاشیه

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

۱۰- یک کلاس به نام MyDividerItemDecoration.java را ایجاد و کلاس را از ItemDecoration گسترش دهید و از متد addItemDecoration() برای نمایش تقسیم کننده استفاده کنید.

MyDividerItemDecoration.java
package info.androidhive.recyclerview;
 
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue;
import android.view.View;
 
/**
 * Created by Ravi on 30/10/15.
 * updated by Ravi on 14/11/17
 */
public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {
 
    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };
 
    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
 
    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
 
    private Drawable mDivider;
    private int mOrientation;
    private Context context;
    private int margin;
 
    public MyDividerItemDecoration(Context context, int orientation, int margin) {
        this.context = context;
        this.margin = margin;
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
        setOrientation(orientation);
    }
 
    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }
 
    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }
 
    public void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
 
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left + dpToPx(margin), top, right - dpToPx(margin), bottom);
            mDivider.draw(c);
        }
    }
 
    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();
 
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top + dpToPx(margin), right, bottom - dpToPx(margin));
            mDivider.draw(c);
        }
    }
 
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
 
    private int dpToPx(int dp) {
        Resources r = context.getResources();
        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
    }
}

۱۱- MainActivity.java را باز کنید و ظاهر مورد نظر را با استفاده از متد addItemDecoration() را قبل از تنظیم کردن آداپتور، تنظیم کنید. در قطعه کد زیر حاشیه را ۱۶ dp در نظر گرفته و به گوشه های چپ و راست خط تقسیم کننده اضافه کرده ایم.

recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
 
// set the adapter
recyclerView.setAdapter(mAdapter);

با اجرای برنامه متوجه تغییرات در خط تقسیم کننده در هر ردیف خواهید شد.

آموزش کامل recyclerview

نمایش اسکرول کردن افقی RecyclerView

اگر میخواهید RecyclerView به صورت افقی نمایش داده شود، باید یک خط از قطعه کد زیر را تغییر دهید. تمام مواردی که در مدیریت لایه لازم دارید، مانند LinearLayoutManager.HORIZONTAL در زیر قرار گرفته است. فراموش نکنید که عرض ردیف با WRAP_CONTENT مشخص میشود.

// horizontal RecyclerView
// keep movie_list_row.xml width to `wrap_content`
RecyclerView.LayoutManager mLayoutManager = 
new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);

اضافه کردن آیتم فراخوانی کلیک در RecyclerView

RecyclerView متد OnItemClickListener را برای تشخیص کلیک کردن ندارد و باید این کلاس را با گسترش RecyclerView.OnItemTouchListener بنویسید.

۱۲- یک کلاس به نام RecyclerTouchListener.java ایجاد کنید و از آن RecyclerView.OnItemTouchListener را گسترش دهید. متوجه خواهید شد که رابط ClickListener به اینجا اضافه خواهد شد.

در نهایت آیتم فراخوانی کلیک را به RecyclerView با کمک کد زیر اضافه کنید.

RecyclerTouchListener.java
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
 
public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
 
    private GestureDetector gestureDetector;
    private ClickListener clickListener;
 
    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
        this.clickListener = clickListener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
 
            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clickListener != null) {
                    clickListener.onLongClick(child, recyclerView.getChildPosition(child));
                }
            }
        });
    }
 
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
 
        View child = rv.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildPosition(child));
        }
        return false;
    }
 
    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
    }
 
    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
 
    }
 
    public interface ClickListener {
        void onClick(View view, int position);
 
        void onLongClick(View view, int position);
    }
}

در نهایت با استفاده از کد زیر  click listener را به  recycler view اضافه کنید.

recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, int position) {
                Movie movie = movieList.get(position);
                Toast.makeText(getApplicationContext(), movie.getTitle() + " is selected!", Toast.LENGTH_SHORT).show();
            }
 
            @Override
            public void onLongClick(View view, int position) {
 
            }
        }));

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

کد نهایی آموزش Recyclerview در اندروید

در زیر کد کامل MainActivity.java را مشاهده می کنید.

MainActivity.java
package info.androidhive.recyclerview;
 
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Toast;
 
import java.util.ArrayList;
import java.util.List;
 
public class MainActivity extends AppCompatActivity {
    private List<Movie> movieList = new ArrayList<>();
    private RecyclerView recyclerView;
    private MoviesAdapter mAdapter;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
 
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
 
        mAdapter = new MoviesAdapter(movieList);
 
        recyclerView.setHasFixedSize(true);
 
        // vertical RecyclerView
        // keep movie_list_row.xml width to `match_parent`
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
 
        // horizontal RecyclerView
        // keep movie_list_row.xml width to `wrap_content`
        // RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
 
        recyclerView.setLayoutManager(mLayoutManager);
 
        // adding inbuilt divider line
        recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
 
        // adding custom divider line with padding 16dp
        // recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
 
        recyclerView.setAdapter(mAdapter);
 
        // row click listener
        recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, int position) {
                Movie movie = movieList.get(position);
                Toast.makeText(getApplicationContext(), movie.getTitle() + " is selected!", Toast.LENGTH_SHORT).show();
            }
 
            @Override
            public void onLongClick(View view, int position) {
 
            }
        }));
 
        prepareMovieData();
    }
 
    /**
     * Prepares sample data to provide data set to adapter
     */
    private void prepareMovieData() {
        Movie movie = new Movie("Mad Max: Fury Road", "Action & Adventure", "2015");
        movieList.add(movie);
 
        movie = new Movie("Inside Out", "Animation, Kids & Family", "2015");
        movieList.add(movie);
 
        movie = new Movie("Star Wars: Episode VII - The Force Awakens", "Action", "2015");
        movieList.add(movie);
 
        movie = new Movie("Shaun the Sheep", "Animation", "2015");
        movieList.add(movie);
 
        movie = new Movie("The Martian", "Science Fiction & Fantasy", "2015");
        movieList.add(movie);
 
        movie = new Movie("Mission: Impossible Rogue Nation", "Action", "2015");
        movieList.add(movie);
 
        movie = new Movie("Up", "Animation", "2009");
        movieList.add(movie);
 
        movie = new Movie("Star Trek", "Science Fiction", "2009");
        movieList.add(movie);
 
        movie = new Movie("The LEGO Movie", "Animation", "2014");
        movieList.add(movie);
 
        movie = new Movie("Iron Man", "Action & Adventure", "2008");
        movieList.add(movie);
 
        movie = new Movie("Aliens", "Science Fiction", "1986");
        movieList.add(movie);
 
        movie = new Movie("Chicken Run", "Animation", "2000");
        movieList.add(movie);
 
        movie = new Movie("Back to the Future", "Science Fiction", "1985");
        movieList.add(movie);
 
        movie = new Movie("Raiders of the Lost Ark", "Action & Adventure", "1981");
        movieList.add(movie);
 
        movie = new Movie("Goldfinger", "Action & Adventure", "1965");
        movieList.add(movie);
 
        movie = new Movie("Guardians of the Galaxy", "Science Fiction & Fantasy", "2014");
        movieList.add(movie);
 
        // notify adapter about data set changes
        // so that it will render the list with new data
        mAdapter.notifyDataSetChanged();
    }
 
}

دانلود پروژه

قسمت بعدی آموزش ؟

امیدوارم در این مقاله درک پایه ایی نسبت به RecyclerView پیدا کرده باشید در قسمت های بعد مباحث پیشرفته تر RecyclerView با ترکیب آن با CardView خواهیم پرداخت و امکاناتی مانند حذف کردن جستجو و …. به آن اضافه خواهی کرد.

  1. آموزش Recyclerview و Cardview در اندروید

برای یادگیری حرفه ایی برنامه نویسی اندروید شما می توانید در کلاس های برنامه نویسی در مشهد  و یا دوره های غیر حضوری آکادمی برنامه نویسان مشهد ثبت نام کنید

اضافه کردن ( کشیدن و رها کردن ) RecyclerView swipe برای حذف و undo

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

در این مطلب قصد داریم با اضافه کردن swipe ( کشیدن و رها کردن ) عملیات هایی مانند حذف و undo را به اپلیکیشن جی میل به recyclerview اضافه کنیم. با ما همراه باشید تا در این آموزش RecyclerView با ساخت یک پروژه ی جدید، این روند را بهتر درک کنید.

RecyclerView Swipe ( کشیدن و رها کردن ) چطور کار می کند؟ با ItemTouchHelper

به کمک کلاس ItemTouchHelper شما می توانید یک swipe را به recycler view اضافه کرده و سپس  عملیات کشیدن و رها کردن را در  پیاده سازی کنید . swipe کردن سطر، باعث میشود تا سطر از recyclerview حذف شود اما داده های موجود را بروزرسانی نمی کند.  شما می توانید یک سطر خالی که با swipe کردن یک سطر نمایش داده میشود را مشاهده کنید. لازم به ذکر است که باید حواستان به بروز رسانی لیست حذف شده ی آیتم ها با پاک شدن از آداپتور مجموعه داده باشد.

ItemTouchHelper.SimpleCallback نوعی روش فراخوانی مانند onmove() ،onswipe و ()onchilddraw برای زمانی می باشد که سطر swipe میشود. نمایش پس زمینه، حذف کردن آیتم ها از آداپتور می توانند با استفاده از متدهای فراخوانی انجام شوند.

در قطعه کد زیر ItemTouchHelper برداشته و به recyclerview اضافه میشود. این کد باید کمی تغییر داده شود تا swipe  و undo به درستی انجام شوند.

RecyclerView recyclerView = findViewById(R.id.recycler_view);
 
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
    @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return false;
    }
 
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        // Row is swiped from recycler view
        // remove it from adapter
    }
 
    @Override
        public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
            // view the background view
        }
    };
         
// attaching the touch helper to recycler view
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);

تعریف جهت دهی های swipe

جهت دهی های swipe می توانند برای ایجاد ()simplecallback تصمیم گیری کنند. در این مقاله ما از جهت دهی های چپ به راست استفاده می کنیم. برای استفاده از سایر جهت دهی ها، باید با اپراتور | ترکیب کنید. با دستور زیر جهت های چپ، راست، بالا و پایین را تعریف می کنیم.

new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)

طراحی لایه ها

طرح بندی لایه ها برای اضافه کردن پس زمینه ی ردیف ها اهمیت زیادی دارد. بسیاری از افراد پس زمینه را روی یک بوم یا canvas با متد ()onChildDraw ایجاد می کنند. البته اگر پس زمینه کمی پیچیده باشد، این فرآیند بسیار خسته کننده خواهد شد. طراحی آن با  لایه های xml خیلی ساده تر می باشد، بنابراین پس زمینه و پیش زمینه را با روش ساده و با کمک framelayout مشخص می کنیم و لایه ی پیش زمینه را در بالا قرار می دهیم.

پیش زمینه معمولا در recyclerview قابل مشاهده می باشد و زمانیکه swipe بر روی پس زمینه انجام میشود، در یک موقعیت ثابت قابل مشاهده خواهد بود.

آموزش RecyclerView

مثال JSON، منوی رستوران

در این قسمت یک مثال JSON که شامل منوی رستوران و تصویر مناسب و نام می باشد را ارائه می دهیم. در این مثال قصد داریم تا این JSON را استفاده کنیم تا آیتم های غذا در لیست recyclerview نمایش داده شوند.

https://api.androidhive.info/json/menu.json

ایجاد پروژه جدید

برای ادامه ی کار در این آموزش RecyclerView نیاز به اطلاعات کافی در مورد ItemTouchHelper داریم تا یک پروژه ی جدید را شروع کنیم و خروجی مورد نظرمان را بدست آوریم.

۱- یک پروژه ی جدید در اندروید استودیو را از مسیر file/new project ایجاد و در نهایت basic activity را به عنوان قالب انتخاب کنید.

۲- bulid.gradle را که زیر پوشه ی app قرار دارد باز نموده و وابستگی های volley و recyclerview را اضافه کنید.

build.gradle
dependencies {
    implementation 'com.android.support:recyclerview-v7:26.1.0'
  
    // glide image library
    implementation 'com.github.bumptech.glide:glide:3.7.0'
     
    // volley http library
    implementation 'com.android.volley:volley:1.0.0'
    implementation 'com.google.code.gson:gson:2.6.2'
}

۳- منابع زیر را به strings.xml و dimens.xml و colors.xml اضافه کنید.

strings.xml
<resources>
    <string name="app_name">Recycler Swipe</string>
    <string name="action_settings">Settings</string>
    <string name="my_cart">My Cart</string>
    <string name="delete">DELETE</string>
</resources>
dimens.xml
<resources>
    <dimen name="activity_padding_horizontal">16dp</dimen>
    <dimen name="padd_10">10dp</dimen>
    <dimen name="ic_delete">30dp</dimen>
    <dimen name="thumbnail">90dp</dimen>
</resources>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#111</color>
    <color name="colorPrimaryDark">#FFF</color>
    <color name="colorAccent">#ea3732</color>
    <color name="bg_row_background">#fa315b</color>
    <color name="item_name">#535353</color>
    <color name="description">#a9a9a9</color>
</resources>

۴- styles.xml را باز کنید و به زیر استایل ها اضافه کنید تا تم  lighter به پروژه تان اضافه شود. این کار باعث میشود تا متن تیره تر از پیش زمینه ی سفیدی که در تولبار داریم به نظر برسد.

styles.xml
<resources>
 
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
 
    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
 
    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Light" />
 
    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
 
</resources>

۵- یک کلاس به نام MyApplication.java ایجاد کنید و آنرا از applications گسترش دهید (extend). این یک کلاس تک هست که برای ایجاد کتابخانه ی volley به کار میرود.

MyApplication.java
import android.app.Application;
import android.text.TextUtils;
 
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
 
public class MyApplication extends Application {
 
    public static final String TAG = MyApplication.class
            .getSimpleName();
 
    private RequestQueue mRequestQueue;
 
    private static MyApplication mInstance;
 
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }
 
    public static synchronized MyApplication getInstance() {
        return mInstance;
    }
 
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
 
        return mRequestQueue;
    }
 
    public <T> void addToRequestQueue(Request<T> req, String tag) {
        // set the default tag if tag is empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }
 
    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }
 
    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

۶-  کلاس AndroidManifest.xml را باز کنید و کلاس MyApplication را به گره application اضافه کنید.مجوزهای internet را درست مانند زمانی که http را فراخوانی می کنیم اضافه کنید.

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.androidhive.recyclerviewswipe">
 
    <uses-permission android:name="android.permission.INTERNET" />
 
    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>

تا این مرحله از کار، منابع آماده هستند. حال باید recyclerview را اضافه کنیم و داده ها را با تجزیه و تحلیل جیسون خروجی بگیریم.

۷-  فایل لایه ی MainActivity.java را باز کنید و recyclerview را اضافه نمایید. از قسمت my activity ما به دو فایل لایه ی activity_main.xml و content_main.xml نیاز داریم.

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="info.androidhive.recyclerviewswipe.MainActivity">
 
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
 
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@android:color/white"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
 
    </android.support.design.widget.AppBarLayout>
 
    <include layout="@layout/content_main" />
 
</android.support.design.widget.CoordinatorLayout>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="info.androidhive.recyclerviewswipe.MainActivity"
    tools:showIn="@layout/activity_main">
 
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical" />
     
</android.support.constraint.ConstraintLayout>

۸-یک کلاس به نام Item.class ایجاد کنید و قطعه کد زیر را اضافه نمایید. کلاس POJO شامل آیتم های منو به نام های name، price، description و آدرس تصویر thumbnail می باشد.

Item.java
/**
 * Created by ravi on 26/09/17.
 */
 
public class Item {
    int id;
    String name;
    String description;
    double price;
    String thumbnail;
 
    public Item() {
    }
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getDescription() {
        return description;
    }
 
    public void setDescription(String description) {
        this.description = description;
    }
 
    public double getPrice() {
        return price;
    }
 
    public void setPrice(double price) {
        this.price = price;
    }
 
    public String getThumbnail() {
        return thumbnail;
    }
 
    public void setThumbnail(String thumbnail) {
        this.thumbnail = thumbnail;
    }
}

۹- یک لایه ی xml به نام cart_list_item.xml  زیر res/layout ایجاد کنید. این لایه هر سطر در recyclerview را با کمک کلاس آداپتور خارج می کند. در اینجا ما یک imageview را برای thumbnail  و چند textviews را برای نمایش آیتم name،  description و price اضافه کرده ایم.

cart_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
 
    <RelativeLayout
        android:id="@+id/view_background"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bg_row_background">
 
        <ImageView
            android:id="@+id/delete_icon"
            android:layout_width="@dimen/ic_delete"
            android:layout_height="@dimen/ic_delete"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="@dimen/padd_10"
            android:src="@drawable/ic_delete_white_24dp" />
 
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginRight="@dimen/padd_10"
            android:layout_toLeftOf="@id/delete_icon"
            android:text="@string/delete"
            android:textColor="#fff"
            android:textSize="13dp" />
 
    </RelativeLayout>
 
    <RelativeLayout
        android:id="@+id/view_foreground"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:padding="@dimen/padd_10">
 
        <ImageView
            android:id="@+id/thumbnail"
            android:layout_width="@dimen/thumbnail"
            android:layout_height="@dimen/thumbnail"
            android:layout_marginRight="@dimen/activity_padding_horizontal"
            android:scaleType="centerCrop" />
 
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/thumbnail"
            android:ellipsize="end"
            android:fontFamily="sans-serif-medium"
            android:maxLines="1"
            android:textColor="@color/item_name"
            android:textSize="17dp" />
 
        <TextView
            android:id="@+id/description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/name"
            android:layout_marginTop="5dp"
            android:layout_toRightOf="@id/thumbnail"
            android:textColor="@color/description"
            android:textSize="12dp" />
 
        <TextView
            android:id="@+id/price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_toRightOf="@id/thumbnail"
            android:textColor="@color/colorAccent"
            android:textStyle="bold" />
 
    </RelativeLayout>
</FrameLayout>

۱۰- یک کلاس به نام CartListAdapter.java را ایجاد کنید. این کلاس آداپتور برای پر کردن لایه ها با داده های مناسب در recyclerview استفاده میشود. ما همچنین دو متد اضافه برای کلاس removeItem() و restoreItem() اضافه کردیم تا عملیات حذف و اضافه کردن را به recyclerview انجام دهند.

CartListAdapter.java
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
 
import com.bumptech.glide.Glide;
 
import java.util.List;
 
public class CartListAdapter extends RecyclerView.Adapter<CartListAdapter.MyViewHolder> {
    private Context context;
    private List<Item> cartList;
 
    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView name, description, price;
        public ImageView thumbnail;
        public RelativeLayout viewBackground, viewForeground;
 
        public MyViewHolder(View view) {
            super(view);
            name = view.findViewById(R.id.name);
            description = view.findViewById(R.id.description);
            price = view.findViewById(R.id.price);
            thumbnail = view.findViewById(R.id.thumbnail);
            viewBackground = view.findViewById(R.id.view_background);
            viewForeground = view.findViewById(R.id.view_foreground);
        }
    }
 
 
    public CartListAdapter(Context context, List<Item> cartList) {
        this.context = context;
        this.cartList = cartList;
    }
 
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.cart_list_item, parent, false);
 
        return new MyViewHolder(itemView);
    }
 
    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        final Item item = cartList.get(position);
        holder.name.setText(item.getName());
        holder.description.setText(item.getDescription());
        holder.price.setText("₹" + item.getPrice());
 
        Glide.with(context)
                .load(item.getThumbnail())
                .into(holder.thumbnail);
    }
 
    @Override
    public int getItemCount() {
        return cartList.size();
    }
 
    public void removeItem(int position) {
        cartList.remove(position);
        // notify the item removed by position
        // to perform recycler view delete animations
        // NOTE: don't call notifyDataSetChanged()
        notifyItemRemoved(position);
    }
 
    public void restoreItem(Item item, int position) {
        cartList.add(position, item);
        // notify item added by position
        notifyItemInserted(position);
    }
}

۱۱- در این مرحله، قصد داریم  یک توابع swipe را به recyclerview اضافه کنیم. برای این منظور یک کلاس به نام RecyclerItemTouchHelper.java ایجاد کرده و کلاس را از ItemTouchHelper.SimpleCallback گسترش داده و متدهای مورد نیاز را override می کنیم.

()getDefaultUIUtil با ItemTouchHelper استفاده میشود تا زمانیکه UI تغییر می کند، تشخیص داده شود. ما از این تابع برای حفظ پس زمینه در حالت و موقعیت استاتیک و انتقال پیش زمینه استفاده میکنیم.

در ()onChildDrawOver، موقعیت X از پیش زمینه در حالیکه کاربر swipe می کند، تغییر داده میشود

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

RecyclerItemTouchHelper.java
import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
 
/**
 * Created by ravi on 29/09/17.
 */
 
public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
    private RecyclerItemTouchHelperListener listener;
 
    public RecyclerItemTouchHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
        super(dragDirs, swipeDirs);
        this.listener = listener;
    }
 
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return true;
    }
 
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (viewHolder != null) {
            final View foregroundView = ((CartListAdapter.MyViewHolder) viewHolder).viewForeground;
 
            getDefaultUIUtil().onSelected(foregroundView);
        }
    }
 
    @Override
    public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
                                RecyclerView.ViewHolder viewHolder, float dX, float dY,
                                int actionState, boolean isCurrentlyActive) {
        final View foregroundView = ((CartListAdapter.MyViewHolder) viewHolder).viewForeground;
        getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
                actionState, isCurrentlyActive);
    }
 
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        final View foregroundView = ((CartListAdapter.MyViewHolder) viewHolder).viewForeground;
        getDefaultUIUtil().clearView(foregroundView);
    }
 
    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView,
                            RecyclerView.ViewHolder viewHolder, float dX, float dY,
                            int actionState, boolean isCurrentlyActive) {
        final View foregroundView = ((CartListAdapter.MyViewHolder) viewHolder).viewForeground;
 
        getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
                actionState, isCurrentlyActive);
    }
 
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
    }
 
    @Override
    public int convertToAbsoluteDirection(int flags, int layoutDirection) {
        return super.convertToAbsoluteDirection(flags, layoutDirection);
    }
 
    public interface RecyclerItemTouchHelperListener {
        void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
    }
}

۱۲- در نهایت، MainActivity.java را باز کنید و تغییرات را مانند زیر انجام دهید.

متد () prepareCart، جیسون را از url میگیرد و بعد از تجزیه و تحلیل، آیتم ها را به آداپتور لیست داده اضافه میکند.

RecyclerItemTouchHelper در اینجا ایجاد شده و به recyclerview اختصاص داده شده است. در اینجا تنها جهت چپ را تعریف کرده ایم.

متد onSwiped() زمانی فراخوانی میشود کهswipe  ارائه شود. گام مهم در اینجا حذف آیتم های ردیف می باشد. mAdapter.removeItem برای حذف سطر از recyclerview فراخوانی میشود.

هنگامی که سطر حذف میشود، snackbar برای نمایش یک پیام با گزینه ی undo استفاده میشود. بالای کلیک undo، سطر دوباره با متد mAdapter.restoreItem() به حالت قبل برمیگردد.

متغیرهای deletedItem و deletedIndex برای ذخیره سازی موقت آیتم های حذف شده و ایندکس تا زمانیکه snackbar نمایش داده میشود، کاربرد دارد.

MainActivity.java
import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
 
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
 
import org.json.JSONArray;
 
import java.util.ArrayList;
import java.util.List;
 
public class MainActivity extends AppCompatActivity implements RecyclerItemTouchHelper.RecyclerItemTouchHelperListener {
 
    private static final String TAG = MainActivity.class.getSimpleName();
    private RecyclerView recyclerView;
    private List<Item> cartList;
    private CartListAdapter mAdapter;
    private CoordinatorLayout coordinatorLayout;
 
    // url to fetch menu json
    private static final String URL = "https://api.androidhive.info/json/menu.json";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle(getString(R.string.my_cart));
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
        recyclerView = findViewById(R.id.recycler_view);
        coordinatorLayout = findViewById(R.id.coordinator_layout);
        cartList = new ArrayList<>();
        mAdapter = new CartListAdapter(this, cartList);
 
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        recyclerView.setAdapter(mAdapter);
 
        // adding item touch helper
        // only ItemTouchHelper.LEFT added to detect Right to Left swipe
        // if you want both Right -> Left and Left -> Right
        // add pass ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT as param
        ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, this);
        new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
 
 
        // making http call and fetching menu json
        prepareCart();
    }
 
    /**
     * method make volley network call and parses json
     */
    private void prepareCart() {
        JsonArrayRequest request = new JsonArrayRequest(URL,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        if (response == null) {
                            Toast.makeText(getApplicationContext(), "Couldn't fetch the menu! Pleas try again.", Toast.LENGTH_LONG).show();
                            return;
                        }
 
                        List<Item> items = new Gson().fromJson(response.toString(), new TypeToken<List<Item>>() {
                        }.getType());
 
                        // adding items to cart list
                        cartList.clear();
                        cartList.addAll(items);
 
                        // refreshing recycler view
                        mAdapter.notifyDataSetChanged();
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // error in getting json
                Log.d(TAG, "Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(), "Error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
 
        MyApplication.getInstance().addToRequestQueue(request);
    }
 
    /**
     * callback when recycler view is swiped
     * item will be removed on swiped
     * undo option will be provided in snackbar to restore the item
     */
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position) {
        if (viewHolder instanceof CartListAdapter.MyViewHolder) {
            // get the removed item name to display it in snack bar
            String name = cartList.get(viewHolder.getAdapterPosition()).getName();
 
            // backup of removed item for undo purpose
            final Item deletedItem = cartList.get(viewHolder.getAdapterPosition());
            final int deletedIndex = viewHolder.getAdapterPosition();
 
            // remove the item from recycler view
            mAdapter.removeItem(viewHolder.getAdapterPosition());
 
            // showing snack bar with Undo option
            Snackbar snackbar = Snackbar
                    .make(coordinatorLayout, name + " removed from cart!", Snackbar.LENGTH_LONG);
            snackbar.setAction("UNDO", new View.OnClickListener() {
                @Override
                public void onClick(View view) {
 
                    // undo is selected, restore the deleted item
                    mAdapter.restoreItem(deletedItem, deletedIndex);
                }
            });
            snackbar.setActionTextColor(Color.YELLOW);
            snackbar.show();
        }
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds cartList to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
}

در نهایت  برنامه را اجرا کنید و تست های لازم را انجام دهید. مطمئن شوید که دستگاه تلفن شما به اینترنت متصل است. خروجی برنامه را در تصویر زیر مشاهده می کنید.

آموزش RecyclerView

RecyclerView

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

کتاب آموزش اندروید استودیو (Android Studio)

آموزش اندروید استدیو

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

دوره آموزش اندروید

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

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

سر فصل های کتاب آموزش اندروید استودیو

  • کتاب آموزش Android Studio نحوه نصب و پیکر بندی Android Studio را آموزش می دهد
  • نحوه ایجاد پروژه در Android Studio و انواع اکتیویتی در اندروید استودیو
  • بررسی ساختار پروژه در  Android Studio و امکانات راهبری برنامه نویسی
  • استفاده از ویرایشگر کد و امکانات آن
  • ایجاد رابط کاربری با دو روش کد نویسی و نمای گرافیکی از دیگر مباحث کتاب آموزش Android Studio می باشد.
  • معرفی سرویس های گوگل پلی و نحوه به کارگیری آنها در پروژه
  • آموزش خطایابی در اندروید استودیو و بدست آوردن اطلاعات خطاهای ایجاد شده
  • آماده سازی و انتشار پروژه

کتاب آموزش Android Studio برای چه افرادی مناسب است

کتاب آموزش  Android Studio علاوه بر کسانی که تازه شروع به برنامه نویسی اندروید کرده اند می تواند مرجعی مناسب برای برنامه نویسان حرفه ایی اندروید باشد.

پیش نیاز های این کتاب آشنایی با برنامه نویسی شئی گرا و تجربه برنامه نویسی با زبان جاوا می باشد .

 

توضیحات کتاب آموزش اندروید استودیو

نویسنده : Belén Cruz Zapata

موضوع :   Android Studio Essentials

تعداد صفحات : 126

فرمت : کتاب PDF

ناشر : PACKT

زبان : انگلیسی

دانلود کتاب

اجرای پروژه – آموزش برنامه نویسی اندروید

آموزش برنامه نویسی اندروید ( اجرای پروژه ) : در جلسه قبل ساخت برنامه اندروید شما یک پروژه ایجاد کردید که در آن متن Hello World برای نمایش وجود دارد . حال شما می توانید این برنامه را برروی یک موبایل واقعی و یا برروی یک شبیه ساز اجرا کنید.در صورتیکه یک موبایل برای اینکار ندارید به قسمت اجرا برروی شبیه ساز بروید.

اجرای پروژه برروی گوشی موبایل ( آموزش برنامه نویسی اندروید )

دوره آموزش اندروید

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

  1. موبایل خود را با استفاده از کابل USB به کامپیوتر وصل کنید.در صورتیکه از ویندوز استفاده می کنید احتمالا نیاز به نصب درایور USB داشته باشید .
  2. گزینه USB debugging را برروی موبایل از مسیر Settings > Developer options فعال کنید.
    نکته : از اندروید ۴٫۲ به بعد گزینه Developer options به صورت پیش فرض مخفی است برای مشاهده آن باید به مسیر Settings > About phone رفته و به گزینه Build number را هفت بار ضربه بزنید.و بعد به صفحه قبل برگشته و گزینه Developer options را پیدا کنید.

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

  1. در Android Studio پروژه تان را انتخاب کرده و برروی Run در toolbar کلیک کنید.
  2. در پنجره Select Deployment Target موبایل خود را انتخاب کرده و برروی OK کلیک کنید.

Android Studio اپلیکشن را برروی موبایل نصب کرده و سپس اجرا می کند.

آموزش برنامه نویسی اندروید :

اجرای پروژه برروی یک شبیه ساز

قبل از اجرا ی برنامه برروی شبیه ساز نیاز به ساخت Android Virtual Device (AVD) است وظیفه AVD تعریف مشخصات دیوایسی است که قرار است در شبیه ساز اندریود اجرا شود  که می تواند شامل موبایل اندرویدی تبلت و یا TV اندرویدی باشد.

  1. Android Virtual Device Manager را از مسیر Tools > Android > AVD Manager و یا با کلیک برروی آیکون AVD Manager avd-manager-studio در تولبار اجرا کنید.
  2. در پنجره Your Virtual Devicesدکمه Create Virtual Device را کلیک کنید.
  3. در پنجره Select Hardware یک موبایل را انتخاب کرده مثلا Nexus 6 و سپس برروی Next کلیک کنید.
  4. پنجره System Image را تغییر نداده و برروی Next کلیک کنید.
  5. تنظیمات پنجره Verify the configuration را نیز به صورت پیش فرض پذیرفته و برروی Finish کلیک کنید.

پروژه را از مسیر زیر اجرا کنید:

  1. در اندروید استدیو آیکون Run as-run تولبار را کلیک کنید
  2. در پنجره Select Deployment Target شبیه ساز را انتخاب کرده و برروی OK کلیک کنید.

بعد از چند دقیقه شبیه ساز اجرا شده و پروژه در صفحه آن  نمایش داده خواهد شد.

آموزش برنامه نویسی اندروید

 

ساخت برنامه اندروید

به سری آموزش های ساخت برنامه اندروید خوش آمدید.در این آموزش ها  به صورت گام به گام مراحل ایجاد پروژه و کد نویسی به همراه نمونه کد ارائه  می شود  که شما می توانید از این کدها در برنامه هایان استفاده کنید.

دوره آموزش اندروید

دراین آموزش ساخت برنامه اندروید به شما نحوه ایجاد یک پروژه در اندروید استدیو و همچنین ساختار آن توضیح داده می شود.

  1. در اندروید استدیو یک پروژه جدید ایجاد کنید:
    •    در صورتیکه  پروژه بازی نداشته باشید در پنجره Welcome to Android Studio برروی گزینه Start a new Android Studio project کلیک کنید
    • و در صورتیکه پروژه ایی باز باشد از مسیر   File > New Project.
  2. در پنجره New Project مقادیر زیر را وارد کنید
    • Application Name: My First App
    • Company Domain: example.com
      همچنین امکان تغییر نام پکیج و مکان آن وجود دارد.
  3. Next را کلیک کنید.
  4. پنجره Target Android Devices تغییر ندهید و برروی Next کلیک کنید.
    گزینه Minimum Required SDK  برای پشتیبانی پروژه از نسخه های قدیمی اندروید که شامل سطوح API می باشد استفاده می شود و برای اینکه پروژه از موبایل های بیشتری پشتیبانی کند  شما باید ورژن های پایین تری را انتخاب کنید.
  5. در پنجره Add an Activity to Mobile  گزینه Empty Activity انتخاب کرده و برروی Next کلیک کنید.
  6. در پنجره Customize the Activity مقادیر پیش فرض را قبول کرده و برروی Next کلیک کنید.

حال نگاهی به فایل های مهم پروژه می اندازیم. ابتدا مطمئن شوید که پنجره Project  باز است (گزینه View > Tool Windows > Project را انتخاب کنید) و همچنین نمای Android در بالا انتخاب شده باشد در این صورت فایل های زیر را خواهید دید:

app > java > com.example.myfirstapp > MainActivity.java

این فایل بعد از ایجاد پروژه جدید در اندروید استدیو ظاهر می شود که شامل کلاسی است که در آن یک اکتیویتی وجود دارد زمانیکه شما برنامه را اجرا می کنیدActivity اجرا شده و فایل layout ی که شامل متن Hello world! است را نمایش می دهد.

app > res > layout > activity_main.xml

در این فایل XML فایل layout اکتیویتی تعریف شده است که شامل یک TextView با مقدار Hello world! است.

app > manifests > AndroidManifest.xml

فایل manifest مهمترین فایل یک پروژه اندروید است که تنظیمات ، خواص و دسترسی های پروژه در آن تعریف می شود.

Gradle Scripts > build.gradle

اندروید استدیو برای کامپایل و ایجاد یک پروژه از Gradle استفاده می کند.

اجرای پروژه (جلسه بعد آموزش برنامه نویسی اندروید )

 

ساخت برنامه اندروید

معرفی ابزارهای جدید اندروید استودیو (آموزش تصویری اندروید استودیو)

در این آموزش تصویری اندروید استودیو به بررسی ابزارهای محیط توسعه اندروید (اندروید استدیو )و امکانات جدید آن پرداخته می شود.

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

دوره آموزش اندرویدآموزش تصویری اندروید استودیو

کتاب آموزش برنامه نویسی اندروید با استفاده از فریم ورک MoSync

کتاب آموزش برنامه نویسی اندروید با استفاده از فریم ورک MoSync :

برنامه نویسی برای گوشی های اندروید دو شیوه است :

شیوه اول برنامه نویسی Native اندروید است . با استفاده از زبان جاوا برای اندروید برنامه می نویسید . شیوه دوم برای اندروید اصطلاحا Mobile Web Application است و….

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

نویسنده  کتاب آموزش برنامه نویسی اندروید : میلاد فشی
فرمت کتاب: PDF
تعداد صفحات کتاب آموزش برنامه نویسی اندروید :۲۷۴
حجم فایل: ۳٫۴۸ مگابایت

رمز فایل : www.acdev.ir

دانلود کتاب