گالری تصاویر با استفاده از ViewPager در برنامه نویسی اندروید

گالری تصاویر با استفاده از ViewPager در برنامه نویسی اندرویدReviewed by آریانا on Dec 19Rating: 5.0گالری تصاویر با استفاده از ViewPager در برنامه نویسی اندرویددر این آموزش ما به شما یاد خواهیم داد که چگونه از ViewPager برای ساخت یک گالری تصاویر در اپلیکیشن اندرویدتان استفاده کنید .

اگر شما بخواهید در اپلیکیشن اندرویدتان تعدادی عکس را برای کاربر توسط ole way نمایش دهید، شما می توانید از Gallery استفاده کنید.

Gallery یک view محسوب می شود که تعدادی آیتم (برای مثال عکس ها) را در یک center-locked در یک لیست که به صورت افقی می تواند اسکرول شود، به نمایش می گذارد. اما با یک باگ در سیتم عامل (که آن را بیشتر در کدهای گوگل می بینید)، Gallery زیاد به کار نمی آید. مشکلی نیست. با استفاده از ViewPager ، ما یک راه حل جایگزین به جای Gallery برای رفع این مشکل خواهیم داشت.

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

لطفا به ویدئوی دموی زیر به عنوان نتیجه ای از این پروژه نگاه کنید

طراحی activity layout

در main activity من یک ViewPager می گذارم و توسط هر پیج آن، یک عکس نشان خواهم داد. همچنین در زیر آن یک HorizontalScrollView برای نمایش تصاویر به صورت کوچک (آیکون تصاویر) می گذارم:

activity_main.xml

[code]

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

    xmlns:tools=”http://schemas.android.com/tools”

    android:layout_width=”match_parent”

    android:layout_height=”match_parent”

    android:orientation=”vertical”

    tools:context=”.MainActivity”>

 

 

<LinearLayout

        android:layout_width=”match_parent”

        android:layout_height=”0dp”

        android:layout_weight=”0.8″

        android:orientation=”horizontal”>

 

<ImageView

            android:id=”@+id/prev”

            android:layout_width=”0dp”

            android:layout_height=”wrap_content”

            android:layout_gravity=”center”

            android:layout_weight=”0.1″

            android:contentDescription=”@string/app_name”

            android:src=”@mipmap/prev” />

 

<android.support.v4.view.ViewPager

            android:id=”@+id/view_pager”

            android:layout_width=”0dp”

            android:layout_height=”wrap_content”

            android:layout_weight=”0.8″>

 

</android.support.v4.view.ViewPager>

 

<ImageView

            android:id=”@+id/next”

            android:layout_width=”0dp”

            android:layout_height=”wrap_content”

            android:layout_gravity=”center”

            android:layout_weight=”0.1″

            android:contentDescription=”@string/app_name”

            android:src=”@mipmap/next” />

</LinearLayout>

 

<HorizontalScrollView

        android:layout_width=”match_parent”

        android:layout_height=”0dp”

        android:layout_weight=”0.2″>

 

<LinearLayout

            android:id=”@+id/container”

            android:layout_width=”wrap_content”

            android:layout_height=”wrap_content”

            android:orientation=”horizontal” />

</HorizontalScrollView>

</LinearLayout>

[/code]

بعد از اجرای برنامه یک خروجی شبیه تصویر زیر خواهیم داشت:

کد برنامه نویسی اکتیویتی (Activity programmatically code):

در مرحله اول فرض کنید که شما تعدادی عکس در فولدر پروژه تان به نام  res/mipmap-hdpi دارید. سپس ما از یک تم در یک drawable array استفاده خواهیم کرد:

مهمترین متد در اکتیویتی ما این است که هر تصویر را به یک HorizontalScrollView برای گرفتن ریزعکس ها (آیکون تصاویر کوچک) تبدیل کنیم. با استفاده از BitmapFactory ، ما drawables resource را به Bitmap رمزگشایی می کنیم و آنها را برای ImageView تنظیم می کنیم. برای جلوگیری از ارور OutOfMemory ، باید یک BitmapFactory ارائه بدهید. گزینه هایی برای مدیریت این موضوع:

[code]

options = new BitmapFactory.Options();

options.inSampleSize = 3;

options.inDither = false;

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), images.get(i), options );

imageView.setImageBitmap(bitmap);

[/code]

و حالا ما یک متد inflateThumbnails() خواهیم داشت:

[code]

private void inflateThumbnails() {

for (int i = 0; i < images.size(); i++) {

View imageLayout = getLayoutInflater().inflate(R.layout.item_image, null);

ImageView imageView = (ImageView) imageLayout.findViewById(R.id.img_thumb);

imageView.setOnClickListener(onChagePageClickListener(i));

options = new BitmapFactory.Options();

options.inSampleSize = 3;

options.inDither = false;

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), images.get(i), options );

imageView.setImageBitmap(bitmap);

//set to image view

imageView.setImageBitmap(bitmap);

//add imageview

thumbnailsContainer.addView(imageLayout);

}

}

[/code]

حالا باید برای حل مسئله کلیک کردن روی دکمه Previous/Next برای تغییر صفحات ViewPager  برنامه نویسی کنیم:

[code]

private View.OnClickListener onClickListener(final int i) {

return new View.OnClickListener() {

@Override

public void onClick(View v) {

if (i > 0) {

//next page

if (viewPager.getCurrentItem() < viewPager.getAdapter().getCount() – 1) {

viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);

}

} else {

//previous page

if (viewPager.getCurrentItem() > 0) {

viewPager.setCurrentItem(viewPager.getCurrentItem() – 1);

}

}

}

};

}

[/code]

حالا ما باید با کلیک روی هر تصویر کوچک هم بتوانیم صفحات ViewPager را تغییر دهیم. با این موضوع اینگونه برخورد کنید:

[code]

private View.OnClickListener onChagePageClickListener(final int i) {

return new View.OnClickListener() {

@Override

public void onClick(View v) {

viewPager.setCurrentItem(i);

}

};

}

[/code]

در متد onCreate() ، adapter را برای ViewPager و attach کردن مقداردهی اولیه کنید. در اینجا شما می توانید همه ی کدهای main activity را ببینید:

MainActivity.java

[code]

package devexchanges.info.imagegallerybyviewpager;

 

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.Bundle;

import android.support.v4.app.FragmentStatePagerAdapter;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.ImageView;

import android.widget.LinearLayout;

 

import java.util.ArrayList;

 

public class MainActivity extends AppCompatActivity {

 

private ArrayList<Integer> images;

private BitmapFactory.Options options;

private ViewPager viewPager;

private View btnNext, btnPrev;

private FragmentStatePagerAdapter adapter;

private LinearLayout thumbnailsContainer;

private final static int[] resourceIDs = new int[]{R.mipmap.a, R.mipmap.b,

R.mipmap.c, R.mipmap.d, R.mipmap.e, R.mipmap.f, R.mipmap.g};

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

images = new ArrayList<>();

 

//find view by id

viewPager = (ViewPager) findViewById(R.id.view_pager);

thumbnailsContainer = (LinearLayout) findViewById(R.id.container);

btnNext = findViewById(R.id.next);

btnPrev = findViewById(R.id.prev);

 

btnPrev.setOnClickListener(onClickListener(0));

btnNext.setOnClickListener(onClickListener(1));

 

setImagesData();

 

// init viewpager adapter and attach

adapter = new ViewPagerAdapter(getSupportFragmentManager(), images);

viewPager.setAdapter(adapter);

 

inflateThumbnails();

}

 

private View.OnClickListener onClickListener(final int i) {

return new View.OnClickListener() {

@Override

public void onClick(View v) {

if (i > 0) {

//next page

if (viewPager.getCurrentItem() < viewPager.getAdapter().getCount() – 1) {

viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);

}

} else {

//previous page

if (viewPager.getCurrentItem() > 0) {

viewPager.setCurrentItem(viewPager.getCurrentItem() – 1);

}

}

}

};

}

 

private void setImagesData() {

for (int i = 0; i < resourceIDs.length; i++) {

images.add(resourceIDs[i]);

}

}

 

private void inflateThumbnails() {

for (int i = 0; i < images.size(); i++) {

View imageLayout = getLayoutInflater().inflate(R.layout.item_image, null);

ImageView imageView = (ImageView) imageLayout.findViewById(R.id.img_thumb);

imageView.setOnClickListener(onChagePageClickListener(i));

options = new BitmapFactory.Options();

options.inSampleSize = 3;

options.inDither = false;

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), images.get(i), options );

imageView.setImageBitmap(bitmap);

//set to image view

imageView.setImageBitmap(bitmap);

//add imageview

thumbnailsContainer.addView(imageLayout);

}

}

 

private View.OnClickListener onChagePageClickListener(final int i) {

return new View.OnClickListener() {

@Override

public void onClick(View v) {

viewPager.setCurrentItem(i);

}

};

}

}

[/code]

ایجاد هر صفحه یا فرگمنت :Page/Fragment :

هر فرگمنت ViewPager ، فقط یک ImageView را برای نمایش کامل تصاویردر بر می گیرد. در اینجا ، هنگامی که drawable  را به Bitmap رمزگشایی یم کنید، باید از خطای OutOfMemory نیز جلوگیری کنید. ما activity بالا را انجام می دهیم. علاوه بر این شما باید هنگامی که فرگمنت از بین می رود، Bitmap را بازیافت نمایید.

شما می توانید سورس کد کامل مربوط به هر صفحه یا فرگمنت را در ادامه ببینید:

PageFragment.java

[code]

package devexchanges.info.imagegallerybyviewpager;

 

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

 

public class PageFragment extends Fragment {

 

private int imageResource;

private Bitmap bitmap;

 

public static PageFragment getInstance(int resourceID) {

PageFragment f = new PageFragment();

Bundle args = new Bundle();

args.putInt(“image_source”, resourceID);

f.setArguments(args);

return f;

}

 

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

imageResource = getArguments().getInt(“image_source”);

}

 

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

return inflater.inflate(R.layout.fragment_page, container, false);

}

 

@Override

public void onViewCreated(View view, Bundle savedInstanceState) {

super.onViewCreated(view, savedInstanceState);

ImageView imageView = (ImageView) view.findViewById(R.id.image);

 

BitmapFactory.Options o = new BitmapFactory.Options();

o.inSampleSize = 4;

o.inDither = false;

bitmap = BitmapFactory.decodeResource(getResources(), imageResource, o);

imageView.setImageBitmap(bitmap);

}

 

@Override

public void onDestroy() {

super.onDestroy();

bitmap.recycle();

bitmap = null;

}

}

[/code]

برخی فایل های لازم:

برای سفارشی کردن یک ViewPager adapter بر اساس FragmentStatePagerAdapter ، ما باید به جای آن استفاده کنیم از FragmentPagerAdapter . کدهای Adapter خیلی ساده هستند:

ViewPagerAdapter.java

[code]

package devexchanges.info.imagegallerybyviewpager;

 

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentStatePagerAdapter;

 

import java.util.List;

 

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

 

private List<Integer> images;

 

public ViewPagerAdapter(FragmentManager fm, List<Integer> imagesList) {

super(fm);

this.images = imagesList;

}

 

@Override

public Fragment getItem(int position) {

return PageFragment.getInstance(images.get(position));

}

 

@Override

public int getCount() {

return images.size();

}

}

[/code]

و حالا Layout  برای هر تصویر کوچک در اکتیویتی:

item_image.xml

[code]

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

    android:layout_width=”match_parent”

    android:layout_height=”match_parent”

    android:orientation=”horizontal”>

 

<ImageView

        android:id=”@+id/img_thumb”

        android:layout_width=”80dp”

        android:layout_height=”80dp”

        android:layout_marginTop=”5dp”

        android:contentDescription=”@string/app_name”

        android:scaleType=”centerCrop” />

 

</LinearLayout>

[/code]

 

پاسخ دهید