本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
Android 使用RecyclerView实现轮播图
奔跑的男人 · 2175浏览 · 发布于2019-05-09 +关注

一、需求

之前一篇博客使用ViewPager实现轮播图《Android ViewPager实现循环轮播图》,但是ViewPager有个天生的缺陷是View无法重用,此外ViewPager的滑动过程会频繁requestLayout,尽管可以通过addViewInLayout和removeViewInLayout配合PagerAdapter 的startUpdate和finishUpdate可以减少重绘,但在ListView和RecyclerView中仍然达不到最好的效果。因此,使用一种新的方式十分必要。

 

二、代码实现

RecyclerPagerView 

public
 
class
 
RecyclerPagerView
 
extends
 
RecyclerView
 
implements
 
Handler
.
Callback
 
{


    
private
 
static
 
final
 
long
 TASK_TIMEOUT = 
3000
;

    
public
 OnPageChangeListener onPageChangeListener;


    
private
 
final
 Handler mRecyclerHandler;

    
private
 
final
 
int
 MSG_PLAY_NEXT  = 
112233
;

    
private
 
volatile
 
boolean
 isPlaying = 
false
;

    
private
 
boolean
 lastIsPlayState = 
false
;

    
private
 
int
 realPosition = -
1
;


    
public
 
RecyclerPagerView
(Context context)
 
{

        
this
(context,
null
);

    }


    
public
 
RecyclerPagerView
(Context context, @Nullable AttributeSet attrs)
 
{

        
this
(context, attrs,
0
);

    }


    
public
 
RecyclerPagerView
(Context context, @Nullable AttributeSet attrs, 
int
 defStyle)
 
{

        
super
(context, attrs, defStyle);

        mRecyclerHandler = 
new
 Handler(Looper.getMainLooper(),
this
);

    }


    
public
 
void
 
setOnPageChangeListener
(OnPageChangeListener onPageChangeListener)
 
{

        
this
.onPageChangeListener = onPageChangeListener;

        
if
(
this
.onPageChangeListener!=
null
){

            addOnScrollListener(
this
.onPageChangeListener);

            
int
 currentItem = getCurrentItem();

            
this
.onPageChangeListener.onPageSelection(currentItem);

        }

    }


    
public
 
int
 
getCurrentItem
()
{

        LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();

        
return
 linearLayoutManager.findFirstVisibleItemPosition();

    }


    
public
 
void
 
setCurrentItem
(
int
 position,
boolean
 isAnimate)
{

        Adapter adapter = getAdapter();

        
if
(adapter==
null
 || adapter.getItemCount()<=position){

            
return
;

        }

        
if
(!isAnimate)

        {

            scrollToPosition(position);

        }
else
 {

            smoothScrollToPosition(position);

        }

    }

    
public
 
void
 
setCurrentItem
(
int
 position )
{

       setCurrentItem(position,
true
);

    }



    
@Override

    
public
 
boolean
 
fling
(
int
 velocityX, 
int
 velocityY)
 
{


        LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();


        
int
 screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;


        
// views on the screen

        
int
 lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();

        View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);

        
int
 firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();

        View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);


        
// distance we need to scroll

        
int
 leftMargin = (screenWidth - lastView.getWidth()) / 
2
;

        
int
 rightMargin = (screenWidth - firstView.getWidth()) / 
2
 + firstView.getWidth();

        
int
 leftEdge = lastView.getLeft();

        
int
 rightEdge = firstView.getRight();

        
int
 scrollDistanceLeft = leftEdge - leftMargin;

        
int
 scrollDistanceRight = rightMargin - rightEdge;


        
int
 targetPosition;


        
if
 (Math.abs(velocityX) < 
1500
) {

            
// The fling is slow -> stay at the current page if we are less than half through,

            
// or go to the next page if more than half through


            
if
 (leftEdge > screenWidth / 
2
) {

                
// go to next page

                smoothScrollBy(-scrollDistanceRight, 
0
);

                targetPosition = firstVisibleItemPosition;


            } 
else
 
if
 (rightEdge < screenWidth / 
2
) {

                
// go to next page

                smoothScrollBy(scrollDistanceLeft, 
0
);

                targetPosition = firstVisibleItemPosition+
1
;

            } 
else
 {

                
// stay at current page

                
if
 (velocityX > 
0
) {

                    smoothScrollBy(-scrollDistanceRight, 
0
);

                } 
else
 {

                    smoothScrollBy(scrollDistanceLeft, 
0
);

                }

                targetPosition = firstVisibleItemPosition;

            }

        } 
else
 {

            
// The fling is fast -> go to next page


            
if
 (velocityX > 
0
) {

                smoothScrollBy(scrollDistanceLeft, 
0
);

                targetPosition = firstVisibleItemPosition+
1
;

            } 
else
 {

                smoothScrollBy(-scrollDistanceRight, 
0
);

                targetPosition = firstVisibleItemPosition;

            }


        }


        Log.e(
"RecyclerPagerView"
,
"nextPage="
+targetPosition);

        
if
(
this
.onPageChangeListener!=
null
){

            realPosition = targetPosition;

            
this
.onPageChangeListener.onPageSelection(targetPosition);

        }

        
return
 
true
;

    }




    
@Override

    
public
 
void
 
onScrollStateChanged
(
final
  
int
 state)
 
{

        
super
.onScrollStateChanged(state);


        
if
 (state == SCROLL_STATE_IDLE) {


            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();


            
int
 screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;


            
int
 lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();

            View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);

            
int
 firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();

            View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);


            
// distance we need to scroll

            
int
 leftMargin = (screenWidth - lastView.getWidth()) / 
2
;

            
int
 rightMargin = (screenWidth - firstView.getWidth()) / 
2
 + firstView.getWidth();

            
int
 leftEdge = lastView.getLeft();

            
int
 rightEdge = firstView.getRight();

            
int
 scrollDistanceLeft = leftEdge - leftMargin;

            
int
 scrollDistanceRight = rightMargin - rightEdge;

            
int
  targetPosition = -
1
;

            
if
 (leftEdge > screenWidth / 
2
) {

                smoothScrollBy(-scrollDistanceRight, 
0
);

                targetPosition = firstVisibleItemPosition+
1
;

            } 
else
 
if
 (rightEdge < screenWidth / 
2
) {

                smoothScrollBy(scrollDistanceLeft, 
0
);

                targetPosition = lastVisibleItemPosition;

            }
else
{

                targetPosition = firstVisibleItemPosition;

            }

            
if
(
this
.onPageChangeListener!=
null
){

                realPosition = targetPosition;

                
this
.onPageChangeListener.onPageSelection(targetPosition);

            }

        }


    }


    
@Override

    
public
 
boolean
 
handleMessage
(Message msg)
 
{

        
int
 what = msg.what;

        
switch
 (what){

            
case
 MSG_PLAY_NEXT:

                showNextPage();

                
break
;

        }


        
return
 
false
;

    }


    
private
 
void
 
showNextPage
()
 
{

        
if
(!isPlaying){

            
return
;

        }

        
if
(!canRecyclePlaying()){

            isPlaying = 
false
;

            
return
;

        }

        Adapter adapter = getAdapter();

        
int
 currentItem = getCurrentItem();

        
if
(adapter!=
null
 && adapter.getItemCount()>
0
) {

            
if
 (currentItem == NO_POSITION  ) {

                setCurrentItem(
0
);

            }
else
 {

                setCurrentItem(currentItem+
1
);

            }

        }


        mRecyclerHandler.sendEmptyMessageDelayed(MSG_PLAY_NEXT,TASK_TIMEOUT);

    }


    
public
 
void
 
startPlay
()
{

        
if
(isPlaying){

            stopPlay();

        }

        
if
 (!canRecyclePlaying()){

            isPlaying = 
false
;

            
return
;

        }


        isPlaying = 
true
;

        mRecyclerHandler.sendEmptyMessageDelayed(MSG_PLAY_NEXT,TASK_TIMEOUT);

    }


    
@Override

    
public
 
void
 
setAdapter
(Adapter adapter)
 
{

        
super
.setAdapter(adapter);


        
if
(canRecyclePlaying()){

            
if
(realPosition==-
1
){

                realPosition = 
1000
;

            }

            setCurrentItem(realPosition,
false
);

        }

    }


    
private
 
boolean
 
canRecyclePlaying
()
 
{

        Adapter adapter = getAdapter();

        
if
(adapter==
null
 || adapter.getItemCount()<
1
) 
return
 
false
;

        
return
 
true
;

    }


    
private
 
void
 
stopPlay
()
 
{

        isPlaying = 
false
;

        mRecyclerHandler.removeMessages(MSG_PLAY_NEXT);

    }


    
@Override

    
protected
 
void
 
onAttachedToWindow
()
 
{

        
super
.onAttachedToWindow();

        
if
(lastIsPlayState){

            startPlay();

        }


    }


    
@Override

    
protected
 
void
 
onDetachedFromWindow
()
 
{

        
super
.onDetachedFromWindow();

        lastIsPlayState = isPlaying;

        stopPlay();

    }


    
public
 
static
    
abstract
 
class
 
OnPageChangeListener
 
extends
 
RecyclerView
.
OnScrollListener
{

            
public
 
abstract
  
void
 
onPageSelection
(
int
 position)
;

    }


}

 

Adapter+Holder 适配器

该类的作用主要用于约束和快速接入

public class QuickViewHolder extends RecyclerView.ViewHolder{    private SparseArray mViews;    private View mConvertView;    private QuickViewHolder(View v){        super(v);
        mConvertView = v;
        mViews = new SparseArray<>();
    }    public static QuickViewHolder get(ViewGroup parent, int layoutId){
        View convertView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);        return new QuickViewHolder(convertView);
    }    public  T getView(int id){
        View v = mViews.get(id);        if(v == null){
            v = mConvertView.findViewById(id);
            mViews.put(id, v);
        }        return (T)v;
    }


}

 

BannerAdapter实现,该类继承QuickAdapter

public class BannerAdapter extends QuickAdapter {    public BannerAdapter(List datas) {        super(datas);
    }    @Override
    public int getLayoutId(int viewType) {        return R.layout.item_banner_image;
    }    @Override
    public void convert(QuickViewHolder holder, String url, int position) {        final Resources resources = holder.itemView.getResources();        final int drawableId = resources.getIdentifier(url, "drawable", holder.itemView.getContext().getPackageName());        if(drawableId!=0) {
            ImageView bannerImage = holder.getView(R.id.banner_image_item);
            bannerImage.setImageResource(drawableId);
        }

    }
}

 

三、使用

        final RecyclerPagerView rpv  = findViewById(R.id.recycler_pager);
        tipTextView                  = findViewById(R.id.tip_text);
        LinearLayoutManager lm = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
        rpv.setLayoutManager(lm);

        List imagelist = new ArrayList<>();
        imagelist.add("banner_t1");
        imagelist.add("banner_t2");
        imagelist.add("banner_t3");
        imagelist.add("banner_t4");

        rpv.setAdapter(new BannerAdapter(imagelist));
        rpv.setOnPageChangeListener(new PagerChangeListener(tipTextView,imagelist.size()));
        rpv.startPlay();

监听器

    public static class  PagerChangeListener extends RecyclerPagerView.OnPageChangeListener {        private TextView tipTextView;        private int size;        public PagerChangeListener(TextView tipTextView,int size) {            this.tipTextView = tipTextView;            this.size = size;
        }        @Override
        public void onPageSelection(int position) {
            tipTextView.setText((position%size+1)+"/"+size);
        }
    }

 


 

加载中

0评论

评论
分类专栏
小鸟云服务器
扫码进入手机网页