استارت‌آپ و کارآفرینی

تجربه‌ی هیجان‌انگیز با Picasso در ListView اندروید

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

grid

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

  • لیستی از داده‌ها از سرور دانلود می‌شود. برای مثال شامل عنوان و توضیحات مربوط به آیتم و نیز آدرس URL عکس‌ها.
  • قرار دادن داده‌های متنی مرتبط در لیست. این عملیات در متد ()getview از کلاس ArrayAdaptor انجام می‌شود.
  • دانلود عکس‌ آیتم‌ها یکی پس از دیگری. این کار هم در متد ()getview انجام می‌شود اما با این تفاوت که هر عکس در همان لحظه‌‌ی نمایش آیتم در صفحه‌ی نمایش گوشی دانلود می‌شود.

بحث اصلی این مقاله مورد سوم است که روش‌های مختلفی برای انجام آن در اینترنت وجود دارد. در اینجا یک ضرب‌المثل بسیار مفید به کارمان می‌آید “چرا دوباره چرخ را اختراع کنیم؟ “. کتابخانه‌ای به نام Picasso تمام کار را برای شما انجام می‌دهد و می‌توانید با خیال راحت به بخش‌های دیگر اپلیکیشن  خود که مهم‌تر هستند بپردازید. روش استفاده از Picasso بسیار ساده‌تر از آنست که فکرش را بکنید. ابتدا باید در اندروید استودیو در build.gradle  پروژه خود در بخش depencencies کد زیر را وارد کنید:

dependencues{ 
	compile 'com.squareup.picasso:picasso:2.5.2'
}

و در بالا سمت راست صفحه ویرایش کد اندروید استودیو لینک Sync Now را کلیک نمایید تا gradle  بتواند این کتابخانه را بشناسد و استفاده کند. به gradle  اجازه دهید تا کارش را به اتمام برساند. سپس به کلاسی که از ArrayAdaptor  ارث‌بری کرده‌اید رفته و در متد ()getview  کد زیر را وارد کنید.

Picasso.with(viewHolder.iv_thumb.getContext())
                .load(vid.get_v_thumbnail())
                .placeholder(R.drawable.icon_play2)
                .noFade()
                .into(viewHolder.iv_thumb);

کد کامل کلاس ArrayAdaptor  در زیر آمده است:

public class AdaptorVideoList extends ArrayAdapter<ClssVideo> {
    // View lookup cache
    Context context;
    String TAG_CLASS="TAG_AdaptorVideoList";
    private static class ViewHolder {
        TextView video_title;
        ImageView iv_thumb;


    }

    public AdaptorVideoList(Context context, ArrayList<ClssVideo> arrAids) {
        super(context, R.layout.custom_list_video_item, arrAids);

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Get the data item for this position
        ClssVideo vid = getItem(position);
        // Check if an existing view is being reused, otherwise inflate the view
        ViewHolder viewHolder = null; // view lookup cache stored in tag
        if (convertView == null) {
            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.custom_list_video_item, parent, false);
            viewHolder.video_title = (TextView) convertView.findViewById(R.id.text1_title);

            viewHolder.iv_thumb=(ImageView)convertView.findViewById(R.id.iv_thumb);
            convertView.setTag(viewHolder);
        }
        else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        // Populate the data into the template view using the data object
        viewHolder.video_title.setText(vid.get_v_title());
        
        Picasso.with(viewHolder.iv_thumb.getContext())
                .load(vid.get_v_thumbnail())
                .placeholder(R.drawable.icon_play2)
                .noFade()
                .into(viewHolder.iv_thumb);

        return convertView;
    }

تجربه‌ی شخصی من

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

15 نظرات
  1. مصطفی نصیری می گوید

    ضمن تشکر فراوان از مقاله خوبتون
    خواستم بگم که من این کتابخونه رو قبلا امتحان کرده بودم اما مشکلی که داشت این بود که هنگام اسکرول عکس ها چشمک میزدن (reload میشدن) البته من از RecyclerView استفاده کردم. در جایی خوندم که احتمالا مربوط به میزان حافظه کش میشه که نمیتونه همه عکس ها رو توی حافظه نگه داره. خواستم بپرسم که شما احیانا به همچین مشکلی بر نخوردید؟

    1. روح می گوید

      منم این مشکل رو داشتم، نمیدونم ایراد از کجاست، ولی وقتی از Glide استفاده کردم این مشکل نبود.

    2. بهروز خضری می گوید

      شاید چون از ViewHolder استفاده نکردید، من از universal image loader استفاده کردم، لود کردن عکس هاش روانتر هست، روش کش کردن عکس هاش رو هم بیشتر دوس داشتم.

  2. مصطفی نصیری می گوید

    اشکال از ViewHolder که نیست مسلما چون همونطور که می دونید در RecyclerView الگوی طراحی ViewHolder الزاما پیاده سازی میشه
    کتابخونه ای که گفتید هم تست کردم ولی با اسکرول کردن دائما عکس ها تغییر می کرد یعنی مثلا وقتی پایین لیست میرفتی همون عکسای بالا بود و بعد عوض میشد 😐
    کتابخونه Volley خوب عمل میکنه تو این زمینه اما متاسفانه پیاده سازی Disk Cache تو والی دردسر داره

    1. بهروز خضری می گوید

      الزاما پیاده سازی میشه یا پیاده سازی می کنید؟ من با این توضیح شما و آقای قاسمی ببشتر ازمینشان پیدا کردم مشکل تون همین ViewHolder هست.
      http://www.androidhive.info/2016/01/android-working-with-recycler-view/
      اینو ببینید.

      1. مصطفی نصیری می گوید

        خب RecyclerView از پایه وابسته به ViewHolder دیگه. در واقع ViewHolder Pattern به صورت ضمنی اجرا میشه توی RecyclerView. یعنی اصلا پیاده سازی این الگو اختیاری نیست!

  3. adicom.ir می گوید

    مرسی
    عالی بود

  4. مرتضی می گوید

    سلام یک سوال داشتم در کتابخانه picasso اگه بخوایم height تصویر به نسبت width تصویر تغییر کنه باید چکار کنیم ؟ البته من از fit و centercrop استفاده کردم ولی باعث شد که دیگه تصویر رو نشون نده .

  5. طه می گوید

    سلام به دوستان و همکاران ممنون از نظرات

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

    البته من رو گوشی خودم که رم بالایی داره همیشه تست کردم شاید تو گوشی های پایین تر به مشکل بر بخورم
    بررسی می کنم حتما

    1. طه می گوید

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

      با تشکر

  6. مهدی می گوید

    منم استفاده از Picasso رو ترجیح میدم ولی توی یه پروژه چون سرورمون https بود ساپورت نمیکرد بجاش از ImageLoader کتابخونه‌ی Volley استفاده کردم. (چون توی پروژم از Volley استفاده کرده بودم).

  7. ستار می گوید

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

  8. ستار می گوید

    باز هم بر اساس تحقیقات بنده کتابخانه glide سریعتر و روانتر از picaso میباشد
    میتونید خودتون تو این ویدئو مشاهده کنید:
    https://www.youtube.com/watch?v=U4QCnptbzUw

  9. corenta می گوید

    سلام !
    مگه بدون پیکاسو هم میشه اپ نوشت ؟ !!!
    از دیگر مزایایی که این اپ داره کش کردن تصاویر به صورت اتوماتیک هست ، این قابلیت به نظر من کلیدی ترین ویژگی این کتابخانه واقعا بی نقص هست .
    وقتی از پیکاسو تو لیست ویو ها استفاده کنید تا وقتی که ایمیج ویو وارد صفحه نشه(منظورم آیتم هایی از لیست هست که با اسکرول کردن کم کم میان بالا) عکس رو لود نمیکنه که از نظر مدیریت منابع بسیار عالیه
    و دریگر اینکه میتونید عکس رو بادیت کنید ، مثلا لبه های عکس رو گرد کنید و …

  10. mpi می گوید

    با سلام
    دوستان شما چطور با استفاده از کتابخانه هایی مثل : Glide,Valley,… یه سری تصاویر رو از یک URL دریافت می کنید (که اون url هم فایل json نیست) و در لیست نمایش میدید ؟
    با تشکر

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.