Slide Image in RecyclerView

Mục đích của bài viết là hướng dẫn cách tạo 1 slide image trong item của recycler view

1. Model, data, view, interface

1.1. Tạo model Profile

Tạo 1 model chứa thông tin Profile : gồm id, name, age, và list image

package tuananh.com.slideimageinrecyclerview.model;

import java.io.Serializable;
import java.util.List;

/**
 * Created by framgia on 27/04/2017.
 */
public class Profile implements Serializable {
    private int mId;
    private String mName;
    private int mAge;
    private List<String> mImageList;

    public Profile(int id, String name, int age, List<String> imageList) {
        mId = id;
        mName = name;
        mAge = age;
        mImageList = imageList;
    }

    public int getId() {
        return mId;
    }

    public void setId(int id) {
        mId = id;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public List<String> getImageList() {
        return mImageList;
    }

    public void setImageList(List<String> imageList) {
        mImageList = imageList;
    }

    public int getAge() {
        return mAge;
    }

    public void setAge(int age) {
        mAge = age;
    }

    public String getNameAge() {
        return String.format("%s, %d", getName(), getAge());
    }
}

1.2. View custom

1.2.1. CircleIndicator

Vẽ và bắt sự kiện scroll viewpage và vẽ lại vị trí của ảnh tương ứng trong list image

package tuananh.com.slideimageinrecyclerview.view.custom;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.os.Build;
import android.support.annotation.AnimatorRes;
import android.support.annotation.DrawableRes;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;

import tuananh.com.slideimageinrecyclerview.R;

import static android.support.v4.view.ViewPager.OnPageChangeListener;

public class CircleIndicator extends LinearLayout {
    private final static int DEFAULT_INDICATOR_WIDTH = 5;
    private ViewPager mViewpager;
    private int mIndicatorMargin = -1;
    private int mIndicatorWidth = -1;
    private int mIndicatorHeight = -1;
    private int mAnimatorResId = R.animator.scale_with_alpha;
    private int mAnimatorReverseResId = 0;
    private int mIndicatorBackgroundResId = R.drawable.blur_radius;
    private int mIndicatorUnselectedBackgroundResId = R.drawable.blur_radius;
    private Animator mAnimatorOut;
    private Animator mAnimatorIn;
    private Animator mImmediateAnimatorOut;
    private Animator mImmediateAnimatorIn;
    private int mLastPosition = -1;
    private final OnPageChangeListener mInternalPageChangeListener = new OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {
            if (mViewpager.getAdapter() == null || mViewpager.getAdapter().getCount() <= 0) {
                return;
            }
            if (mAnimatorIn.isRunning()) {
                mAnimatorIn.end();
                mAnimatorIn.cancel();
            }
            if (mAnimatorOut.isRunning()) {
                mAnimatorOut.end();
                mAnimatorOut.cancel();
            }
            View currentIndicator;
            if (mLastPosition >= 0 && (currentIndicator = getChildAt(mLastPosition)) != null) {
                currentIndicator.setBackgroundResource(mIndicatorUnselectedBackgroundResId);
                mAnimatorIn.setTarget(currentIndicator);
                mAnimatorIn.start();
            }
            View selectedIndicator = getChildAt(position);
            if (selectedIndicator != null) {
                selectedIndicator.setBackgroundResource(mIndicatorBackgroundResId);
                mAnimatorOut.setTarget(selectedIndicator);
                mAnimatorOut.start();
            }
            mLastPosition = position;
        }

        @Override
        public void onPageScrollStateChanged(int state) {
        }
    };
    private DataSetObserver mInternalDataSetObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            if (mViewpager == null) {
                return;
            }
            int newCount = mViewpager.getAdapter().getCount();
            int currentCount = getChildCount();
            if (newCount == currentCount) {  // No change
                return;
            } else if (mLastPosition < newCount) {
                mLastPosition = mViewpager.getCurrentItem();
            } else {
                mLastPosition = -1;
            }
            createIndicators();
        }
    };

    public CircleIndicator(Context context) {
        super(context);
        init(context, null);
    }

    public CircleIndicator(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public CircleIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CircleIndicator(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        handleTypedArray(context, attrs);
        checkIndicatorConfig(context);
    }

    private void handleTypedArray(Context context, AttributeSet attrs) {
        if (attrs == null) {
            return;
        }
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleIndicator);
        mIndicatorWidth =
            typedArray.getDimensionPixelSize(R.styleable.CircleIndicator_ci_width, -1);
        mIndicatorHeight =
            typedArray.getDimensionPixelSize(R.styleable.CircleIndicator_ci_height, -1);
        mIndicatorMargin =
            typedArray.getDimensionPixelSize(R.styleable.CircleIndicator_ci_margin, -1);
        mAnimatorResId = typedArray.getResourceId(R.styleable.CircleIndicator_ci_animator,
            R.animator.scale_with_alpha);
        mAnimatorReverseResId =
            typedArray.getResourceId(R.styleable.CircleIndicator_ci_animator_reverse, 0);
        mIndicatorBackgroundResId =
            typedArray.getResourceId(R.styleable.CircleIndicator_ci_drawable,
                R.drawable.blur_radius);
        mIndicatorUnselectedBackgroundResId =
            typedArray.getResourceId(R.styleable.CircleIndicator_ci_drawable_unselected,
                mIndicatorBackgroundResId);
        int orientation = typedArray.getInt(R.styleable.CircleIndicator_ci_orientation, -1);
        setOrientation(orientation == VERTICAL ? VERTICAL : HORIZONTAL);
        int gravity = typedArray.getInt(R.styleable.CircleIndicator_ci_gravity, -1);
        setGravity(gravity >= 0 ? gravity : Gravity.CENTER);
        typedArray.recycle();
    }

    /**
     * Create and configure Indicator in Java code.
     */
    public void configureIndicator(int indicatorWidth, int indicatorHeight, int indicatorMargin) {
        configureIndicator(indicatorWidth, indicatorHeight, indicatorMargin,
            R.animator.scale_with_alpha, 0, R.drawable.blur_radius, R.drawable.blur_radius);
    }

    public void configureIndicator(int indicatorWidth, int indicatorHeight, int indicatorMargin,
                                   @AnimatorRes int animatorId, @AnimatorRes int animatorReverseId,
                                   @DrawableRes int indicatorBackgroundId,
                                   @DrawableRes int indicatorUnselectedBackgroundId) {
        mIndicatorWidth = indicatorWidth;
        mIndicatorHeight = indicatorHeight;
        mIndicatorMargin = indicatorMargin;
        mAnimatorResId = animatorId;
        mAnimatorReverseResId = animatorReverseId;
        mIndicatorBackgroundResId = indicatorBackgroundId;
        mIndicatorUnselectedBackgroundResId = indicatorUnselectedBackgroundId;
        checkIndicatorConfig(getContext());
    }

    private void checkIndicatorConfig(Context context) {
        mIndicatorWidth = (mIndicatorWidth < 0) ? dip2px(DEFAULT_INDICATOR_WIDTH) : mIndicatorWidth;
        mIndicatorHeight =
            (mIndicatorHeight < 0) ? dip2px(DEFAULT_INDICATOR_WIDTH) : mIndicatorHeight;
        mIndicatorMargin =
            (mIndicatorMargin < 0) ? dip2px(DEFAULT_INDICATOR_WIDTH) : mIndicatorMargin;
        mAnimatorResId = (mAnimatorResId == 0) ? R.animator.scale_with_alpha : mAnimatorResId;
        mAnimatorOut = createAnimatorOut(context);
        mImmediateAnimatorOut = createAnimatorOut(context);
        mImmediateAnimatorOut.setDuration(0);
        mAnimatorIn = createAnimatorIn(context);
        mImmediateAnimatorIn = createAnimatorIn(context);
        mImmediateAnimatorIn.setDuration(0);
        mIndicatorBackgroundResId = (mIndicatorBackgroundResId == 0) ? R.drawable.blur_radius
            : mIndicatorBackgroundResId;
        mIndicatorUnselectedBackgroundResId =
            (mIndicatorUnselectedBackgroundResId == 0) ? mIndicatorBackgroundResId
                : mIndicatorUnselectedBackgroundResId;
    }

    private Animator createAnimatorOut(Context context) {
        return AnimatorInflater.loadAnimator(context, mAnimatorResId);
    }

    private Animator createAnimatorIn(Context context) {
        Animator animatorIn;
        if (mAnimatorReverseResId == 0) {
            animatorIn = AnimatorInflater.loadAnimator(context, mAnimatorResId);
            animatorIn.setInterpolator(new ReverseInterpolator());
        } else {
            animatorIn = AnimatorInflater.loadAnimator(context, mAnimatorReverseResId);
        }
        return animatorIn;
    }

    public void setViewPager(ViewPager viewPager) {
        mViewpager = viewPager;
        if (mViewpager != null && mViewpager.getAdapter() != null) {
            mLastPosition = -1;
            createIndicators();
            mViewpager.removeOnPageChangeListener(mInternalPageChangeListener);
            mViewpager.addOnPageChangeListener(mInternalPageChangeListener);
            mInternalPageChangeListener.onPageSelected(mViewpager.getCurrentItem());
        }
    }

    public DataSetObserver getDataSetObserver() {
        return mInternalDataSetObserver;
    }

    /**
     * @deprecated User ViewPager addOnPageChangeListener
     */
    @Deprecated
    public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener) {
        if (mViewpager == null) {
            throw new NullPointerException("can not find Viewpager , setViewPager first");
        }
        mViewpager.removeOnPageChangeListener(onPageChangeListener);
        mViewpager.addOnPageChangeListener(onPageChangeListener);
    }

    private void createIndicators() {
        removeAllViews();
        int count = mViewpager.getAdapter().getCount();
        if (count <= 0) {
            return;
        }
        int currentItem = mViewpager.getCurrentItem();
        int orientation = getOrientation();
        for (int i = 0; i < count; i++) {
            if (currentItem == i) {
                addIndicator(orientation, mIndicatorBackgroundResId, mImmediateAnimatorOut);
            } else {
                addIndicator(orientation, mIndicatorUnselectedBackgroundResId,
                    mImmediateAnimatorIn);
            }
        }
    }

    private void addIndicator(int orientation, @DrawableRes int backgroundDrawableId,
                              Animator animator) {
        if (animator.isRunning()) {
            animator.end();
            animator.cancel();
        }
        View Indicator = new View(getContext());
        Indicator.setBackgroundResource(backgroundDrawableId);
        addView(Indicator, mIndicatorWidth, mIndicatorHeight);
        LayoutParams lp = (LayoutParams) Indicator.getLayoutParams();
        if (orientation == HORIZONTAL) {
            lp.leftMargin = mIndicatorMargin;
            lp.rightMargin = mIndicatorMargin;
        } else {
            lp.topMargin = mIndicatorMargin;
            lp.bottomMargin = mIndicatorMargin;
        }
        Indicator.setLayoutParams(lp);
        animator.setTarget(Indicator);
        animator.start();
    }

    public int dip2px(float dpValue) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    private class ReverseInterpolator implements Interpolator {
        @Override
        public float getInterpolation(float value) {
            return Math.abs(1.0f - value);
        }
    }
}

1.2.2 ResizableImageView

Resize Image theo chiều rộng mà ko vỡ ảnh

package tuananh.com.slideimageinrecyclerview.view.custom;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
 * Created by TuanAnh on 4/28/2017.
 */
public class ResizableImageView extends ImageView {
    public ResizableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Drawable d = getDrawable();
        if (d != null) {
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = 0;
            height = (int) Math.ceil((float) width
                * (float) d.getIntrinsicHeight()
                / (float) d.getIntrinsicWidth());
            setMeasuredDimension(width, height);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

1.3. Tạo class create data

Khởi tạo list profile cho ứng dụng

package tuananh.com.slideimageinrecyclerview;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import tuananh.com.slideimageinrecyclerview.model.Profile;

/**
 * Created by framgia on 27/04/2017.
 */
public class CreateData {
    public static List<Profile> createProfile() {
        List<Profile> profileList = new ArrayList<>();
        profileList.add(create(1, "Đào", 22, Arrays.asList(
            "http://imageshack.com/a/img922/986/1C5zeO.jpg",
            "http://imageshack.com/a/img924/224/taTtUg.jpg",
            "http://imageshack.com/a/img923/1333/cnHzDa.jpg",
            "http://imageshack.com/a/img922/9823/TpA14D.jpg",
            "http://imageshack.com/a/img924/4017/f9pqLq.jpg",
            "http://imageshack.com/a/img922/8958/4KAmdD.jpg",
            "http://imageshack.com/a/img923/8135/nyfIov.jpg")));
        profileList.add(create(2, "Đào", 22, Arrays.asList(
            "http://imageshack.com/a/img923/2374/jBIAqT.jpg",
            "http://imageshack.com/a/img923/9599/ulegwM.jpg",
            "http://imageshack.com/a/img923/7016/HzEvo8.jpg",
            "http://imageshack.com/a/img922/1641/emfvPy.jpg",
            "http://imageshack.com/a/img923/116/yfyetV.jpg",
            "http://imageshack.com/a/img924/4846/zveut5.jpg",
            "http://imageshack.com/a/img923/472/SB341D.jpg",
            "http://imageshack.com/a/img924/4350/5ghok1.jpg")));
        profileList.add(create(3, "Đào", 22, Arrays.asList(
            "http://imageshack.com/a/img923/3835/q79WKE.jpg",
            "http://imageshack.com/a/img922/3615/sNKPpV.jpg",
            "http://imageshack.com/a/img924/7272/UXID41.jpg",
            "http://imageshack.com/a/img923/1332/sTx6qw.jpg",
            "http://imageshack.com/a/img923/3338/v0hyg5.jpg",
            "http://imageshack.com/a/img922/8435/puIYQa.jpg")));
        profileList.add(create(4, "Đào", 22, Arrays.asList(
            "http://imageshack.com/a/img922/3390/GXOW9e.jpg",
            "http://imageshack.com/a/img922/8017/Qnxgbw.jpg")));
        profileList.add(create(5, "Đào", 22, Arrays.asList(
            "http://imageshack.com/a/img924/331/ujExV6.jpg",
            "http://imageshack.com/a/img923/9503/qgUaHN.jpg",
            "http://imageshack.com/a/img924/5319/RNBJQp.jpg",
            "http://imageshack.com/a/img923/3299/nWdFeZ.jpg",
            "http://imageshack.com/a/img922/461/iIGnvU.jpg",
            "http://imageshack.com/a/img922/3748/XvWQPz.jpg",
            "http://imageshack.com/a/img922/2177/gm9ddy.jpg",
            "http://imageshack.com/a/img924/7344/JBqVbQ.jpg")));
        profileList.add(create(6, "Đào", 22, Arrays.asList(
            "http://imageshack.com/a/img924/6515/JiylGo.jpg",
            "http://imageshack.com/a/img924/6537/AfNnra.jpg",
            "http://imageshack.com/a/img924/802/rBCWs3.jpg",
            "http://imageshack.com/a/img923/9322/bO0hYw.jpg",
            "http://imageshack.com/a/img923/7392/kyiKsh.jpg")));
        profileList.add(create(7, "Đào", 22, Arrays.asList(
            "http://imageshack.com/a/img924/9423/E8Xxky.jpg",
            "http://imageshack.com/a/img922/8366/7TVQZk.jpg",
            "http://imageshack.com/a/img922/8117/3OJydD.jpg")));
        profileList.add(create(8, "Đào", 22, Arrays.asList(
            "http://imageshack.com/a/img923/6430/OK2kfH.jpg",
            "http://imageshack.com/a/img924/8688/j6RaJz.jpg",
            "http://imageshack.com/a/img924/7714/LWTaxv.jpg",
            "http://imageshack.com/a/img922/64/u9LXlR.jpg")));
        return profileList;
    }

    public static Profile create(int id, String name, int age, List<String> imageList) {
        return new Profile(id, name, age, imageList);
    }
}

1.4. ViewBindingAdapter

Function loadImage() để vẽ ảnh bằng picasso với link url đc truyền vào

package tuananh.com.slideimageinrecyclerview.view.binding;

import android.databinding.BindingAdapter;
import android.widget.ImageView;

import com.squareup.picasso.Picasso;

import tuananh.com.slideimageinrecyclerview.R;

/**
 * Created by framgia on 27/04/2017.
 */
public class ViewBindingAdapter {
    @BindingAdapter("imageUrl")
    public static void loadImage(ImageView imageView, String url) {
        Picasso.with(imageView.getContext())
            .load(url)
            .placeholder(R.drawable.image_default)
            .into(imageView);
    }
}

1.5. Interface OnClickShowImageListener

package tuananh.com.slideimageinrecyclerview.listener;

import tuananh.com.slideimageinrecyclerview.model.Profile;

/**
 * Created by TuanAnh on 4/28/2017.
 */
public interface OnClickShowImageListener {
    void onClickShowImage(Profile profile, int positionImage);
}

2. Adapter

2.1 SlideImageAdapter

2.1.1. SlideImageAdapter

Tạo Adapter cho slide image là SlideImageAdapter
Hàm khởi tạo cần truyền profile và listener onClickShowImageListener ( mục đích là bắt sự kiện OnClickListener vào ảnh để sang trang show full image)
public SlideImageAdapter(Context context, Profile profile,
OnClickShowImageListener onClickShowImageListener) {
}

package tuananh.com.slideimageinrecyclerview.view.adapter;

import android.content.Context;
import android.databinding.DataBindingUtil;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

import tuananh.com.slideimageinrecyclerview.R;
import tuananh.com.slideimageinrecyclerview.databinding.FragmentSlideProfileBinding;
import tuananh.com.slideimageinrecyclerview.listener.OnClickShowImageListener;
import tuananh.com.slideimageinrecyclerview.model.Profile;

/**
 * Created by framgia on 27/04/2017.
 */
public class SlideImageAdapter extends PagerAdapter {
    private Context mContext;
    private List<String> mImageList;
    private LayoutInflater mLayoutInflater;
    private Profile mProfile;
    private OnClickShowImageListener mOnClickShowImageListener;

    public SlideImageAdapter(Context context, Profile profile,
                             OnClickShowImageListener onClickShowImageListener) {
        mContext = context;
        mProfile = profile;
        mImageList = profile.getImageList();
        mOnClickShowImageListener = onClickShowImageListener;
        mLayoutInflater = LayoutInflater.from(context);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

    @Override
    public int getCount() {
        return mImageList == null ? 0 : mImageList.size();
    }

    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
        FragmentSlideProfileBinding binding = DataBindingUtil.inflate(mLayoutInflater,
            R.layout.fragment_slide_profile, container, false);
        binding.getRoot().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnClickShowImageListener != null) {
                    mOnClickShowImageListener.onClickShowImage(mProfile, position);
                }
            }
        });
        binding.setUrl(mImageList.get(position));
        binding.setPosition(position);
        binding.getRoot().setTag(position);
        container.addView(binding.getRoot(), 0);
        return binding.getRoot();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view.equals(object);
    }
}

2.1.2. Layout

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="position"
            type="int"/>

        <variable
            name="url"
            type="String"/>

    </data>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white">

        <ImageView
            android:id="@+id/image_slide"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            app:imageUrl="@{url}"/>
    </FrameLayout>
</layout>

2.2. ProfileAdapter

2.2.1. Tạo adapter ProfileAdapter cho reycerview

Function public void bind(Profile profile) {}

  • mBinding.setVariable(BR.viewModel, profile); -> truyền data và trong layout
  • SlideImageAdapter slideImageAdapter =
    new SlideImageAdapter(mContext, profile, mOnClickShowImageListener);
    -> khởi tạo slideImageAdapter cho viewpager trong mỗi item của recyclerview
  • mBinding.slideImageViewPager.setAdapter(slideImageAdapter); -> truyền adapter vào viewpager
  • mBinding.slideImageViewPager.setOffscreenPageLimit(MAX_SIZE_IMAGE_LOAD); -> load tối đa MAX_SIZE_IMAGE_LOAD ảnh ban đầu
  • mBinding.indicator.setViewPager(mBinding.slideImageViewPager); -> truyền viewpager vào CircleIndicator để bắt sự kiện scroll viewpager
package tuananh.com.slideimageinrecyclerview.view.adapter;

import android.content.Context;
import android.databinding.DataBindingUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import java.util.List;

import tuananh.com.slideimageinrecyclerview.BR;
import tuananh.com.slideimageinrecyclerview.R;
import tuananh.com.slideimageinrecyclerview.databinding.ItemRecyclerProfileBinding;
import tuananh.com.slideimageinrecyclerview.listener.OnClickShowImageListener;
import tuananh.com.slideimageinrecyclerview.model.Profile;

/**
 * Created by TuanAnh on 4/26/2017.
 */
public class ProfileAdapter extends RecyclerView.Adapter<ProfileAdapter.ProfileViewHolder> {
    private static final int MAX_SIZE_IMAGE_LOAD = 8;
    private Context mContext;
    private LayoutInflater mLayoutInflater;
    private List<Profile> mProfileList;
    private OnClickShowImageListener mOnClickShowImageListener;

    public ProfileAdapter(Context context, List<Profile> profileList,
                          OnClickShowImageListener onClickShowImageListener) {
        mContext = context;
        mProfileList = profileList;
        mOnClickShowImageListener = onClickShowImageListener;
        mLayoutInflater = LayoutInflater.from(context);
    }

    @Override
    public ProfileViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ItemRecyclerProfileBinding binding = DataBindingUtil.inflate(mLayoutInflater,
            R.layout.item_recycler_profile, parent, false);
        return new ProfileViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(ProfileViewHolder holder, int position) {
        Profile profile = mProfileList.get(position);
        holder.bind(profile);
    }

    @Override
    public int getItemCount() {
        return mProfileList == null ? 0 : mProfileList.size();
    }

    public class ProfileViewHolder extends RecyclerView.ViewHolder {
        private ItemRecyclerProfileBinding mBinding;

        public ProfileViewHolder(ItemRecyclerProfileBinding binding) {
            super(binding.getRoot());
            mBinding = binding;
        }

        public void bind(Profile profile) {
            mBinding.setVariable(BR.viewModel, profile);
            SlideImageAdapter slideImageAdapter =
                new SlideImageAdapter(mContext, profile, mOnClickShowImageListener);
            mBinding.sliderImageViewPager.setAdapter(slideImageAdapter);
            mBinding.sliderImageViewPager.setOffscreenPageLimit(MAX_SIZE_IMAGE_LOAD);
            mBinding.indicator.setViewPager(mBinding.sliderImageViewPager);
            mBinding.executePendingBindings();
        }
    }
}

2.2.2. Layout

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="viewModel"
            type="tuananh.com.slideimageinrecyclerview.model.Profile"/>

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margin_padding_10"
            android:layout_marginLeft="@dimen/margin_padding_20"
            android:drawableLeft="@drawable/img_dots"
            android:drawablePadding="@dimen/margin_padding_10"
            android:text="@{viewModel.nameAge}"
            android:textSize="@dimen/text_size_14"
            android:textStyle="bold"/>

        <android.support.v4.view.ViewPager
            android:id="@+id/slide_image_view_pager"
            android:layout_width="match_parent"
            android:layout_height="@dimen/size_200"/>

        <tuananh.com.slideimageinrecyclerview.view.custom.CircleIndicator
            android:id="@+id/indicator"
            android:layout_width="match_parent"
            android:layout_height="@dimen/size_30"
            android:layout_gravity="bottom"
            app:ci_drawable="@drawable/black_radius"
            app:ci_drawable_unselected="@drawable/blur_radius"/>
    </LinearLayout>
</layout>

Image

Slide Image in RecyclerView 6Slide Image in RecyclerView 7Slide Image in RecyclerView 8Slide Image in RecyclerView 9Slide Image in RecyclerView 10

Tham khảo

Code

Bài viết liên quan

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *