Android Custom Carousel Effect
- 2021-12-13 17:03:13
- OfStack
In this paper, we share the specific code of Android custom carousel effect for your reference. The specific contents are as follows
Overview
1. Write a layout with ViewPager, TextView and LinearLayout.
ViewPager: Used to carry pictures TextView: Used to display text descriptions LinearLayout: Used to show indicators2. Customize ConstraintLayout, and handle page switching logic in this control.
Analysis
1. Get custom attributes and set some attributes
public BannerY(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
initXmlParams(context, attrs, defStyleAttr);
fixParams();
initListener();
initLists();
initImageLoader();
}
/**
* Initialization ImageLoader
*/
private void initImageLoader() {
ImageLoader.getInstance().init(ImageLoaderConfiguration.createDefault(mContext));
}
/**
* Fill the layout into the BannerY, Get VP,TextView,LinearLayout Control
*
* @param context
*/
private void initView(Context context) {
mContext = context;
LayoutInflater.from(context).inflate(R.layout.layout_banner, this);
mVp = (ViewPager) findViewById(R.id.vp);
mTvDesc = (TextView) findViewById(R.id.tv_desc);
mLLPoint = (LinearLayout) findViewById(R.id.ll_point);
}
/**
* Get custom properties
*
* @param context
* @param attrs
* @param defStyleAttr
*/
private void initXmlParams(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BannerY, defStyleAttr, 0);
mPointSize = typedArray.getDimensionPixelSize(R.styleable.BannerY_point_size, 8);
mPointBG = typedArray.getResourceId(R.styleable.BannerY_point_bg, R.drawable.point_selector);
mInterval = typedArray.getInteger(R.styleable.BannerY_banner_interval, 2000);
mTvBottomMargin = typedArray.getDimensionPixelSize(R.styleable.BannerY_desc_bottom_margin, 8);
mPointBottomMargin = typedArray.getDimensionPixelSize(R.styleable.BannerY_point_bottom_margin, 8);
mDescColor = typedArray.getColor(R.styleable.BannerY_desc_color, Color.BLACK);
mDescSize = typedArray.getDimensionPixelSize(R.styleable.BannerY_desc_size, 14);
mScaleType = typedArray.getInt(R.styleable.BannerY_banner_scaletype, -1);
typedArray.recycle();
}
/**
* Adjust the pointer and text description position through custom properties
*/
private void fixParams() {
// Describe the control
LayoutParams mTvDescLayoutParams = (LayoutParams) mTvDesc.getLayoutParams();
mTvDescLayoutParams.bottomMargin = (int) mTvBottomMargin;
mTvDesc.setLayoutParams(mTvDescLayoutParams);
mTvDesc.setTextColor(mDescColor);
mTvDesc.getPaint().setTextSize(mDescSize);
// Indicator
LayoutParams mLLPointLayoutParams = (LayoutParams) mLLPoint.getLayoutParams();
mLLPointLayoutParams.bottomMargin = (int) mPointBottomMargin;
mLLPoint.setLayoutParams(mLLPointLayoutParams);
}
/**
* Create a data source collection and create a Handler Object
*/
@SuppressLint("HandlerLeak")
private void initLists() {
mImageViewList = new ArrayList<>();
mDescList = new ArrayList<>();
mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
// Get ViewPager Index value of the current display picture
int currentItem = mVp.getCurrentItem();
// Switch to below 1 Pictures
mVp.setCurrentItem(currentItem + 1);
// Interval 1 Send at a fixed time 1 Messages , The interval duration is controlled by custom attribute values .
mHandler.sendEmptyMessageDelayed(1, mInterval);
}
};
}
/**
* For ViewPager Setting Slide Listening
*/
private void initListener() {
mVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
// ViewPager A total of Integer.MAX_VALUE Views
// position Mould taking , Convert to mImageViewList Corresponding index .
int realPosition = position % mImageViewList.size();
if (mDescList.size() == mImageViewList.size()) {
// The text description set is equal in length to the picture set , Then it is a text description TextView Show the corresponding text content .
String desc = mDescList.get(realPosition);
mTvDesc.setText(desc);
} else {
if (BuildConfig.DEBUG) {
Log.d(TAG, " Text collection and picture collection are not equal in length ");
}
}
// Upper 1 The indicator corresponding to the pages is set to unchecked
mLLPoint.getChildAt(prePosition).setEnabled(false);
// From the indicator-mounted LinearLayout Obtain the indicator corresponding to the current view in the , Then set the indicator to be currently selected , So as to change the color of the indicator .
mLLPoint.getChildAt(realPosition).setEnabled(true);
prePosition = realPosition;
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_DRAGGING) {// Sliding
// Manual touch ViewPager, So that it is in a sliding state ,Handler Stop sending messages .
isDragging = true;
mHandler.removeCallbacksAndMessages(null);
}
if (state == ViewPager.SCROLL_STATE_IDLE && isDragging) {// Idle state
// ViewPager After the manual sliding stops, , Re-open Handler Send a message .
mHandler.removeCallbacksAndMessages(null);
mHandler.sendEmptyMessageDelayed(1, mInterval);
}
}
});
}
2. Set the picture source collection
/**
* Set up the picture source
* @param imagesRes
* @param <T>
*/
public <T> void setImagesRes(ArrayList<T> imagesRes) {
if (judgeLenght(imagesRes)) {
mImageViewList.clear();
// Initialize the picture list
initImageList(imagesRes);
// Create Adapter
mBannerAdapter = new BannerAdapter(mImageViewList);
mVp.setAdapter(mBannerAdapter);
// Settings ViewPager The current view is in the middle position , Because ViewPager The number of views is Integer.MAX_VALUE( In ViewPagerAdapter Set in the ).
int position = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % mImageViewList.size();
// Sets the current ViewPager Which view to show
mVp.setCurrentItem(position);
// Open a message loop
mHandler.sendEmptyMessageDelayed(1, mInterval);
if (mDescList.size() == mImageViewList.size()) {
// Set up text description display
mTvDesc.setText(mDescList.get(prePosition));
}
}
}
/**
* Initialize the picture list
*/
private void initImageList(ArrayList imagesRes) {
Class<?> imageResClass = imagesRes.get(0).getClass();
for (int i = 0; i < imagesRes.size(); i++) {
// Create ImageView
ImageView imageView = createImageView(imagesRes, i, imageResClass);
// For ImageView Set click events
setImageViewListener(imageView);
// Will ImageView Add to the collection
mImageViewList.add(imageView);
// Add an indicator
addPoint(i);
}
}
/**
* Create from parameters ImageView Object
*
* @param imagesRes
* @param i
* @param imageResClass
* @return
*/
private ImageView createImageView(ArrayList imagesRes, int i, Class<?> imageResClass) {
ImageView imageView = new ImageView(mContext);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
imageView.setLayoutParams(layoutParams);
ImageView.ScaleType scaleType = sScaleTypeArray[mScaleType];
imageView.setScaleType(scaleType);
if (imageResClass.equals(String.class)) {
// If the picture data source collection is url, Website picture
String url = (String) imagesRes.get(i);
// Use ImageLoader Show the picture to the ImageView Medium
ImageLoader.getInstance().displayImage(url, imageView);
} else if (imageResClass.equals(Integer.class)) {
// If the picture data source collection is a picture resource ID
Integer resId = (Integer) imagesRes.get(i);
imageView.setImageResource(resId);
}
return imageView;
}
/**
* For ImageView Object sets click events and touch events
*
* @param imageView
*/
@SuppressLint("ClickableViewAccessibility")
private void setImageViewListener(ImageView imageView) {
imageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// When the finger is in ImageView Press down , Then stop handler Send a message to switch pictures
mHandler.removeCallbacksAndMessages(null);
break;
case MotionEvent.ACTION_UP:
// When your fingers are raised , Send the Switch Picture message normally .
mHandler.removeCallbacksAndMessages(null);
mHandler.sendEmptyMessageDelayed(1, mInterval);
break;
}
return false;
}
});
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mIClickBanner != null) {
// When clicked ImageView Hour , Pass getTage() Gets the current view index value corresponding to the picture .
// The value is specified in the ViewPagerAdapter In instantiateItem() Set in the .
int positon = (int) v.getTag();
int i = positon % mImageViewList.size();
mIClickBanner.click(i);
} else {
if (BuildConfig.DEBUG) {
Log.e(TAG, " Picture callback method is nonexistent ");
}
}
}
});
}
3. Adapter of BannerY
public class BannerAdapter<T> extends PagerAdapter {
private final static String TAG = BannerAdapter.class.getName();
ArrayList<ImageView> mImageViewList;
/**
* @param mImageViewList ImageView Control list , In the list IamgeView Have set up picture resources and click events, etc. .
*/
public BannerAdapter(ArrayList<ImageView> mImageViewList) {
this.mImageViewList = mImageViewList;
}
@Override
public int getCount() {
// Settings ViewPager Number of views of ,Integer.MAX_VALUE Yes 1 A very large number , No matter how long the polling is, it is difficult to reach the end .
return Integer.MAX_VALUE;
}
@SuppressLint("ClickableViewAccessibility")
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, final int position) {
// position This number is very large , After taking the mold, it can correspond mImageViewList The index value in the collection is changed .
final int realPosition = position % mImageViewList.size();
ImageView imageView = mImageViewList.get(realPosition);
// Match the index value with the ImageView Binding , When clicked, the index value can be taken out .
imageView.setTag(position);
ViewParent viewParent = imageView.getParent();
if (viewParent != null) {
// This is to prevent ViewPager Add pictures repeatedly .
((ViewGroup) viewParent).removeView(imageView);
}
// Add a picture to the ViewPager Medium
container.addView(imageView);
return imageView;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
}
}