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

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

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

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

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

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

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

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

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

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

اکثر برنامه ها به یک پایگاه داده نیاز دارند و در نتیجه اگر قصد دارید یک برنامه ی جدید را برای خودتان بسازید، به احتمال زیاد به زبان پرس و جوی پایگاه داده (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 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

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

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

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

برخی از ویژگی های Android Studio عبارتند از :

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

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

سرفص های فیلم آموزش Android Studio عبارتند از :

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

فیلم آموزش android studio

لینک های دانلود فیلم آموزش Android Studio

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

دانلود -بخش اول

دانلود – بخش دوم

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

Want to develop Android apps? You need Android Studio—the only IDE fully supported by Google for Android app development. This course is fully revised for 2016, covering all the essential features in the latest iteration of Android Studio (v2.0) and critical resources such as the Java Development Kit and Intel HAXM. David Gassner introduces the Android Studio interface, helps you set up your environment, and provides handy shortcuts for writing and debugging code. He also shows how to monitor CPU and memory usage; use templates, breakpoints, and watch expressions; and add version control by integrating Android Studio with GitHub.

Topics include:

    • Installing Android Studio on Mac and Windows
    • Creating Android Studio projects
    • Setting up the development environment, including HAXM and the new Android emulator
    • Importing existing code into Android Studio projects
    • Exploring the interface, including the editor and project windows
    • Managing project builds and dependencies
    • Creating new Java classes
    • Refactoring code
    • Using templates
    • Using breakpoints and watch expressions
    • Updating apps with Instant Run
  • Using Git for version control

امضا برنامه اندروید – آموزش امضاء کردن apk در اندروید استودیو

امضا برنامه اندروید – آموزش امضاء کردن apk در اندروید استودیو : برای آپلود کردن و همچنین به روز رسانی apk در فروشگاه گوگل و بازار نیاز به امضاء کردن apk می باشد . معمولا در زمان توسعه و خطایابی برنامه ، apk هایی که می سازیم فاقد امضاء است که قابل آپلود برروی مارکت ها نمی باشد. در مارکت ها هر اپلیکیشن باید دارای امضاء باشد که این امضاء شامل مشخصات توسعه دهنده و یک کلید مخفی می باشد تا مارکت بدین وسیله بتواند منبع آن سورس را اعتبار سنجی کند.

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

در اندروید استودیو ویزاردی برای این موضوع ایجاد شده است که طی مراحل پایین می توانید از آن برای ایجاد apk امضاء شده استفاده کنید :

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

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

مرحله ۲ : ایجاد یک امضاء :

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

نکته : در صورتیکه از قبل امضاء دارید از همان امضاء قبلی با انتخاب گزینه choose existing استفاده کنید به خصوص زمانیکه یک اپلیکیشن را برای آپدیت های جدید امضاء می کنید در صورتیکه امضاء ها متفاوت باشند اپلیکیشن آپدیت نخواهد شد.

مرحله ۳ : در این پنجره مواردی همچون مسیر ذخیره سازی امضاء ، کلمه عبور ،یک نام مستعار وکلمه عبور برای آن ، مدت زمان اعتبار امضاء و اطلاعات مربوط به خودتان که برای ایجاد certificate استفاده می شود را وارد کنید.

آموزش امضاء کردن apk در اندروید استدیو

مرحله ۴ : در این پنجره برروی Next کلیک کرده و به مرحله بعد بروید

آموزش ساخت apk

مرحله ۵ : در این قسمت مسیر ذخیره سازی apk را انتخاب کرده و Build Type را برروی release قرار دهیدو برروی finish کلیک کنید .

apk-signing-06

مرحله ۶ : در پنجره event Log فرایند ساخت apk نمایش داده می شود و در انتها لینک مسیری که apk ساخته شده است نمایش داده خواهد شد و شما می توایند با کلیک برروی آن به apk دسترسی پیدا کنید.

آموزش امضاء کردن apk در اندروید استدیو

در انتها هم می توانید apk بدست آمده را برروی یک مجازی ساز و یا موبایل نصب کنید.

آموزش امضاء کردن apk در اندروید استودیو

 

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