11

I have a RecyclerView with Cardviews. I want sliding images inside this CardView, just like in OLX app. What is the best way to do so? I think about puting viewpager inside cardview. Is it ok or maybe I should try something else?

I did it with ViewPager but it looks like too slow. Here is a part of viewpager adapter.

 @Override
public Object instantiateItem(ViewGroup collection, int position) {

    LayoutInflater inflater = LayoutInflater.from(mContext);
    ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.viewpager_custom, collection, false);
    collection.addView(layout);

    ImageView image = (ImageView) layout.findViewById(R.id.viewPagerImageView);
    image.setImageResource(mPics[position]);

    return layout;
}

enter image description here

Sufian
  • 6,405
  • 16
  • 66
  • 120
SERG
  • 3,907
  • 8
  • 44
  • 89
  • 1
    What is the direction? Vertical or horizontal? – Sufian Oct 30 '15 at 09:58
  • 1
    Do you want the sliding to be user interactive (i.e. user drags the slides) or otherwise automatic? – frogatto Oct 30 '15 at 11:04
  • @abforce, yes it should be user interactive – SERG Oct 30 '15 at 11:18
  • or maybe it is faster to use GestureDetector.SimpleOnGestureListener on ImageView? for changing images – SERG Oct 30 '15 at 11:32
  • In OLX they are using view pager but they are modifying view pager by taking smooth user gesture on swipe. So you also have to use ViewPager and override its gesture functionality according to you. – Surender Kumar Oct 31 '15 at 10:39
  • @SurenderKumar but if i use viewpager in over 40 items in recyclerview the app run slowly – SERG Nov 01 '15 at 08:09
  • you have to load the viewpager with some little items and load more items after the items over like we load more items when listview end reacher. – Surender Kumar Nov 02 '15 at 04:54
  • 1
    I suggested you try this http://stackoverflow.com/questions/27077878/how-to-create-scrollable-page-of-carousels-in-android/27311842#27311842 – Mohammad Hossein Gerami Nov 02 '15 at 16:32

2 Answers2

7

You are going the right way.

Just do one thing load compressed bitmaps instead of uncompressed ones. You are directly setting bitmap resource to your imageview. Either use a library like Picasso https://github.com/square/picasso/

or use google's official source for loading large bitmaps efficiently.

Firstly copy this method in your activity:

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

Then this method to decode bitmaps:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

Then load your bitmap like this:

@Override
public Object instantiateItem(ViewGroup collection, int position) {

    LayoutInflater inflater = LayoutInflater.from(mContext);
    ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.viewpager_custom, collection, false);
    collection.addView(layout);

    ImageView image = (ImageView) layout.findViewById(R.id.viewPagerImageView);
    image.setImageBitmap(
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, reqwidth, reqheight));

    return layout;
}
Vishavjeet Singh
  • 1,385
  • 11
  • 13
1

I would use the following library on GitHub to implement this change. It lets you swipe hotizontally and remove the item from the ListView once you are done with it.

Use the example below to help you:

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

    mItems = new ArrayList<>(30);
    for (int i = 0; i < 30; i++) {
        mItems.add(String.format("Card number %2d", i));
    }

    mAdapter = new CardViewAdapter(mItems);

    mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);

    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mRecyclerView.setAdapter(mAdapter);

    SwipeableRecyclerViewTouchListener swipeTouchListener =
            new SwipeableRecyclerViewTouchListener(mRecyclerView,
                    new SwipeableRecyclerViewTouchListener.SwipeListener() {
                        @Override
                        public boolean canSwipe(int position) {
                            return true;
                        }

                        @Override
                        public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) {
                            for (int position : reverseSortedPositions) {
                                mItems.remove(position);
                                mAdapter.notifyItemRemoved(position);
                            }
                            mAdapter.notifyDataSetChanged();
                        }

                        @Override
                        public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) {
                            for (int position : reverseSortedPositions) {
                                mItems.remove(position);
                                mAdapter.notifyItemRemoved(position);
                            }
                            mAdapter.notifyDataSetChanged();
                        }
                    });

    mRecyclerView.addOnItemTouchListener(swipeTouchListener);

Hope this helps :)

Michele La Ferla
  • 6,775
  • 11
  • 53
  • 79