RecyclerView

玩转RecyclerView | 实现子视图叠加 | 3D画廊效果 | 高级动效 | Android 3D坐标系介绍 之前写的一篇文章展示了RecyclerView实现的画廊效果,适用于专辑/图片/列表浏览效果。本篇文章阐述如何基于RecyclerView实现如下图所示的3D画廊效果。以下效果的重点在于实现子视图的图层叠加,滑动过程中的3D旋转效果较为简单。(1)无3D旋转效果图片(1)带3D旋转效果图片。 阅读详情

载请标明出处:http://blog.youkuaiyun.com/lmj623565791/article/details/38173061 ,本文出自:【张鸿洋的博客】

上一篇博客我使用自定义HorizontalScrollView写了一个具有HorizontalScrollView效果和ViewPager特性的横向图片轮播,详见:Android 自定义 HorizontalScrollView 打造再多图片(控件)也不怕 OOM 的横向滑动效果。其实制作横向滚动的不得不说另一个控件,就是Google官方最近新增加的RecyclerView,据说是ListView的升级版本,本篇博客,首先介绍RecyclerView的用法,然后经行一定的分析;最后自定义一下RecyclerView实现我们需要的相册效果。

1、RecyclerView的基本用法

首先主Activity的布局文件:

[html]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <android.support.v7.widget.RecyclerView  
  7.         android:id="@+id/id_recyclerview_horizontal"  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="120dp"  
  10.         android:layout_centerVertical="true"  
  11.         android:background="#FF0000"  
  12.         android:scrollbars="none" />  
  13.   
  14. </RelativeLayout>  

Item的布局文件:

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="120dp"  
  4.     android:layout_height="120dp"  
  5.     android:background="@drawable/item_bg02" >  
  6.   
  7.     <ImageView  
  8.         android:id="@+id/id_index_gallery_item_image"  
  9.         android:layout_width="80dp"  
  10.         android:layout_height="80dp"  
  11.         android:layout_alignParentTop="true"  
  12.         android:layout_centerHorizontal="true"  
  13.         android:layout_margin="5dp"  
  14.         android:scaleType="centerCrop" />  
  15.   
  16.     <TextView  
  17.         android:id="@+id/id_index_gallery_item_text"  
  18.         android:layout_width="wrap_content"  
  19.         android:layout_height="wrap_content"  
  20.         android:layout_below="@id/id_index_gallery_item_image"  
  21.         android:layout_centerHorizontal="true"  
  22.         android:layout_marginBottom="5dp"  
  23.         android:layout_marginTop="5dp"  
  24.         android:textColor="#ff0000"  
  25.         android:text="some info"  
  26.         android:textSize="12dp" />  
  27.   
  28. </RelativeLayout>  

数据适配器:

[java]  view plain  copy
  1. package com.example.zhy_horizontalscrollview03;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.content.Context;  
  6. import android.support.v7.widget.RecyclerView;  
  7. import android.view.LayoutInflater;  
  8. import android.view.View;  
  9. import android.view.ViewGroup;  
  10. import android.widget.ImageView;  
  11. import android.widget.TextView;  
  12.   
  13. public class GalleryAdapter extends  
  14.         RecyclerView.Adapter<GalleryAdapter.ViewHolder>  
  15. {  
  16.   
  17.     private LayoutInflater mInflater;  
  18.     private List<Integer> mDatas;  
  19.   
  20.     public GalleryAdapter(Context context, List<Integer> datats)  
  21.     {  
  22.         mInflater = LayoutInflater.from(context);  
  23.         mDatas = datats;  
  24.     }  
  25.   
  26.     public static class ViewHolder extends RecyclerView.ViewHolder  
  27.     {  
  28.         public ViewHolder(View arg0)  
  29.         {  
  30.             super(arg0);  
  31.         }  
  32.   
  33.         ImageView mImg;  
  34.         TextView mTxt;  
  35.     }  
  36.   
  37.     @Override  
  38.     public int getItemCount()  
  39.     {  
  40.         return mDatas.size();  
  41.     }  
  42.   
  43.     /** 
  44.      * 创建ViewHolder 
  45.      */  
  46.     @Override  
  47.     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)  
  48.     {  
  49.         View view = mInflater.inflate(R.layout.activity_index_gallery_item,  
  50.                 viewGroup, false);  
  51.         ViewHolder viewHolder = new ViewHolder(view);  
  52.   
  53.         viewHolder.mImg = (ImageView) view  
  54.                 .findViewById(R.id.id_index_gallery_item_image);  
  55.         return viewHolder;  
  56.     }  
  57.   
  58.     /** 
  59.      * 设置值 
  60.      */  
  61.     @Override  
  62.     public void onBindViewHolder(final ViewHolder viewHolder, final int i)  
  63.     {  
  64.         viewHolder.mImg.setImageResource(mDatas.get(i));  
  65.     }  
  66.   
  67. }  

可以看到数据适配器与BaseAdapter比较发生了相当大的变化,主要有3个方法:

getItemCount 这个不用说,获取总的条目数

onCreateViewHolder 创建ViewHolder

onBindViewHolder 将数据绑定至ViewHolder

可见,RecyclerView对ViewHolder也进行了一定的封装,但是如果你仔细观察,你会发出一个疑问,ListView里面有个getView返回View为Item的布局,那么这个Item的样子在哪控制?

其实是这样的,我们创建的ViewHolder必须继承RecyclerView.ViewHolder,这个RecyclerView.ViewHolder的构造时必须传入一个View,这个View相当于我们ListView getView中的convertView (即:我们需要inflate的item布局需要传入)。

还有一点,ListView中convertView是复用的,在RecyclerView中,是把ViewHolder作为缓存的单位了,然后convertView作为ViewHolder的成员变量保持在ViewHolder中,也就是说,假设没有屏幕显示10个条目,则会创建10个ViewHolder缓存起来,每次复用的是ViewHolder,所以他把getView这个方法变为了onCreateViewHolder。有兴趣的自己打印下Log,测试下。

最后在Activity中使用:

[java]  view plain  copy
  1. package com.example.zhy_horizontalscrollview03;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Arrays;  
  5. import java.util.List;  
  6.   
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.support.v7.widget.LinearLayoutManager;  
  10. import android.support.v7.widget.RecyclerView;  
  11. import android.view.Window;  
  12.   
  13. public class MainActivity extends Activity  
  14. {  
  15.   
  16.     private RecyclerView mRecyclerView;  
  17.     private GalleryAdapter mAdapter;  
  18.     private List<Integer> mDatas;  
  19.       
  20.       
  21.     @Override  
  22.     protected void onCreate(Bundle savedInstanceState)  
  23.     {  
  24.         super.onCreate(savedInstanceState);  
  25.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  26.         setContentView(R.layout.activity_main);  
  27.           
  28.         initDatas();  
  29.         //得到控件  
  30.         mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview_horizontal);  
  31.         //设置布局管理器  
  32.         LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);  
  33.         linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);  
  34.         mRecyclerView.setLayoutManager(linearLayoutManager);  
  35.         //设置适配器  
  36.         mAdapter = new GalleryAdapter(this, mDatas);  
  37.         mRecyclerView.setAdapter(mAdapter);  
  38.   
  39.           
  40.     }  
  41.   
  42.   
  43.     private void initDatas()  
  44.     {  
  45.         mDatas = new ArrayList<Integer>(Arrays.asList(R.drawable.a,  
  46.                 R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e,  
  47.                 R.drawable.f, R.drawable.g, R.drawable.h, R.drawable.l));  
  48.     }  
  49.   
  50. }  

使用起来也很方便,唯一的区别就是要设置LayoutManager,目前只有一个实现类,就是LinearLayoutManager,可以设置为水平或者垂直。

最后效果图:


效果很不错,这就是RecyclerView的基本用法了,但是你会发现一个坑爹的地方,竟然没有提供setOnItemClickListener这个回调,要不要这么坑爹。。。

2、为RecyclerView添加OnItemClickListener回调

虽然它没有提供,但是添加个OnItemClickListener对我们来说还不是小菜一碟~

我决定在Adapter中添加这个回调接口:

[java]  view plain  copy
  1. package com.example.zhy_horizontalscrollview03;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.content.Context;  
  6. import android.support.v7.widget.RecyclerView;  
  7. import android.view.LayoutInflater;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.view.ViewGroup;  
  11. import android.widget.ImageView;  
  12. import android.widget.TextView;  
  13.   
  14. public class GalleryAdapter extends  
  15.         RecyclerView.Adapter<GalleryAdapter.ViewHolder>  
  16. {  
  17.   
  18.     /** 
  19.      * ItemClick的回调接口 
  20.      * @author zhy 
  21.      * 
  22.      */  
  23.     public interface OnItemClickLitener  
  24.     {  
  25.         void onItemClick(View view, int position);  
  26.     }  
  27.   
  28.     private OnItemClickLitener mOnItemClickLitener;  
  29.   
  30.     public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)  
  31.     {  
  32.         this.mOnItemClickLitener = mOnItemClickLitener;  
  33.     }  
  34.   
  35.     private LayoutInflater mInflater;  
  36.     private List<Integer> mDatas;  
  37.   
  38.     public GalleryAdapter(Context context, List<Integer> datats)  
  39.     {  
  40.         mInflater = LayoutInflater.from(context);  
  41.         mDatas = datats;  
  42.     }  
  43.   
  44.     public static class ViewHolder extends RecyclerView.ViewHolder  
  45.     {  
  46.         public ViewHolder(View arg0)  
  47.         {  
  48.             super(arg0);  
  49.         }  
  50.   
  51.         ImageView mImg;  
  52.         TextView mTxt;  
  53.     }  
  54.   
  55.     @Override  
  56.     public int getItemCount()  
  57.     {  
  58.         return mDatas.size();  
  59.     }  
  60.   
  61.     @Override  
  62.     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i)  
  63.     {  
  64.         View view = mInflater.inflate(R.layout.activity_index_gallery_item,  
  65.                 viewGroup, false);  
  66.         ViewHolder viewHolder = new ViewHolder(view);  
  67.   
  68.         viewHolder.mImg = (ImageView) view  
  69.                 .findViewById(R.id.id_index_gallery_item_image);  
  70.         return viewHolder;  
  71.     }  
  72.   
  73.     @Override  
  74.     public void onBindViewHolder(final ViewHolder viewHolder, final int i)  
  75.     {  
  76.         viewHolder.mImg.setImageResource(mDatas.get(i));  
  77.   
  78.         //如果设置了回调,则设置点击事件  
  79.         if (mOnItemClickLitener != null)  
  80.         {  
  81.             viewHolder.itemView.setOnClickListener(new OnClickListener()  
  82.             {  
  83.                 @Override  
  84.                 public void onClick(View v)  
  85.                 {  
  86.                     mOnItemClickLitener.onItemClick(viewHolder.itemView, i);  
  87.                 }  
  88.             });  
  89.   
  90.         }  
  91.   
  92.     }  
  93.   
  94. }  

很简单,创建一个接口,提供一个设置入口,然后在onBindViewHolder中判断即可。

最后在主Activity中设置监听:

[java]  view plain  copy
  1. mAdapter = new GalleryAdapter(this, mDatas);  
  2. mAdapter.setOnItemClickLitener(new OnItemClickLitener()  
  3. {  
  4.     @Override  
  5.     public void onItemClick(View view, int position)  
  6.     {  
  7.         Toast.makeText(MainActivity.this, position+"", Toast.LENGTH_SHORT)  
  8.                 .show();  
  9.     }  
  10. });  
  11. mRecyclerView.setAdapter(mAdapter);  

好了,这样就行了,看效果图:


效果还是不错的,接下来我想改成相册效果,即上面显示一张大图,下面的RecyclerView做为图片切换的指示器。

3、自定义RecyclerView实现滚动时内容联动

首先修改下布局:

布局文件:

[java]  view plain  copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <FrameLayout  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="0dp"  
  10.         android:layout_weight="1" >  
  11.   
  12.         <ImageView  
  13.             android:id="@+id/id_content"  
  14.             android:layout_width="fill_parent"  
  15.             android:layout_height="fill_parent"  
  16.             android:layout_gravity="center"  
  17.             android:layout_margin="10dp"  
  18.             android:scaleType="centerCrop"  
  19.             android:src="@drawable/ic_launcher" />  
  20.     </FrameLayout>  
  21.   
  22.     <com.example.zhy_horizontalscrollview03.MyRecyclerView  
  23.         android:id="@+id/id_recyclerview_horizontal"  
  24.         android:layout_width="match_parent"  
  25.         android:layout_height="120dp"  
  26.         android:layout_gravity="bottom"  
  27.         android:background="#FF0000"  
  28.         android:scrollbars="none" />  
  29.   
  30. </LinearLayout>  

添加一个显示大图的区域,把RecyclerView改为自己定义的。

然后看我们自定义RecyclerView的代码:

[java]  view plain  copy
  1. package com.example.zhy_horizontalscrollview03;  
  2.   
  3. import android.content.Context;  
  4. import android.support.v7.widget.RecyclerView;  
  5. import android.util.AttributeSet;  
  6. import android.view.MotionEvent;  
  7. import android.view.View;  
  8.   
  9. public class CopyOfMyRecyclerView extends RecyclerView  
  10. {  
  11.   
  12.     public CopyOfMyRecyclerView(Context context, AttributeSet attrs)  
  13.     {  
  14.         super(context, attrs);  
  15.     }  
  16.   
  17.     private View mCurrentView;  
  18.   
  19.     /** 
  20.      * 滚动时回调的接口 
  21.      */  
  22.     private OnItemScrollChangeListener mItemScrollChangeListener;  
  23.   
  24.     public void setOnItemScrollChangeListener(  
  25.             OnItemScrollChangeListener mItemScrollChangeListener)  
  26.     {  
  27.         this.mItemScrollChangeListener = mItemScrollChangeListener;  
  28.     }  
  29.   
  30.     public interface OnItemScrollChangeListener  
  31.     {  
  32.         void onChange(View view, int position);  
  33.     }  
  34.   
  35.     @Override  
  36.     protected void onLayout(boolean changed, int l, int t, int r, int b)  
  37.     {  
  38.         super.onLayout(changed, l, t, r, b);  
  39.   
  40.         mCurrentView = getChildAt(0);  
  41.   
  42.         if (mItemScrollChangeListener != null)  
  43.         {  
  44.             mItemScrollChangeListener.onChange(mCurrentView,  
  45.                     getChildPosition(mCurrentView));  
  46.         }  
  47.     }  
  48.   
  49.     @Override  
  50.     public boolean onTouchEvent(MotionEvent e)  
  51.     {  
  52.   
  53.         if (e.getAction() == MotionEvent.ACTION_MOVE)  
  54.         {  
  55.             mCurrentView = getChildAt(0);  
  56.             // Log.e("TAG", getChildPosition(getChildAt(0)) + "");  
  57.             if (mItemScrollChangeListener != null)  
  58.             {  
  59.                 mItemScrollChangeListener.onChange(mCurrentView,  
  60.                         getChildPosition(mCurrentView));  
  61.   
  62.             }  
  63.   
  64.         }  
  65.   
  66.         return super.onTouchEvent(e);  
  67.     }  
  68.   
  69. }  

定义了一个滚动时回调的接口,然后在onTouchEvent中,监听ACTION_MOVE,用户手指滑动时,不断把当前第一个View回调回去~

关于我咋知道getChildAt(0)和getChildPosition()可用,起初我以为有getFirstVisibleItem这个方法,后来发现么有;但是发现了getRecycledViewPool()看名字我觉得是Viewholder那个缓存队列,我想那么直接取这个队列的第一个不就是我要的View么,后来没有成功。我就观察它内部的View,最后发现,第一个显示的始终是它第一个child,至于getChildPosition这个看方法就看出来了。

现在的效果:



和我之前那个例子的效果是一模一样的,不过,我还想做一些改变,我觉得Gallery或者说相册的指示器,下面可能1000来张图片,我不仅喜欢手指在屏幕上滑动时,图片会自动切换。我还希望,如果我给指示器一个加速度,即使手指离开,下面还在滑动,上面也会联动 。而且我还想做些优化,直接在ACTION_MOVE中回调,触发的频率太高了,理论上一张图片只会触发一次~~

4、优化与打造真正的Gallery效果

既然希望手指离开还能联动,那么不仅需要ACTION_MOVE需要监听,还得监听一个加速度,速度到达一定值,然后继续移动~~再理一理,需要这么麻烦么,不是能滚动么,那么应该有OnScrollListener啊,小看一把,果然有,哈哈哈~天助我也,下面看修改后的代码:

[java]  view plain  copy
  1. package com.example.zhy_horizontalscrollview03;  
  2.   
  3. import android.content.Context;  
  4. import android.support.v7.widget.RecyclerView;  
  5. import android.support.v7.widget.RecyclerView.OnScrollListener;  
  6. import android.util.AttributeSet;  
  7. import android.view.View;  
  8.   
  9. public class MyRecyclerView extends RecyclerView implements OnScrollListener  
  10. {  
  11.   
  12.     /** 
  13.      * 记录当前第一个View 
  14.      */  
  15.     private View mCurrentView;  
  16.   
  17.     private OnItemScrollChangeListener mItemScrollChangeListener;  
  18.   
  19.     public void setOnItemScrollChangeListener(  
  20.             OnItemScrollChangeListener mItemScrollChangeListener)  
  21.     {  
  22.         this.mItemScrollChangeListener = mItemScrollChangeListener;  
  23.     }  
  24.   
  25.     public interface OnItemScrollChangeListener  
  26.     {  
  27.         void onChange(View view, int position);  
  28.     }  
  29.   
  30.     public MyRecyclerView(Context context, AttributeSet attrs)  
  31.     {  
  32.         super(context, attrs);  
  33.         // TODO Auto-generated constructor stub  
  34.         this.setOnScrollListener(this);  
  35.     }  
  36.   
  37.     @Override  
  38.     protected void onLayout(boolean changed, int l, int t, int r, int b)  
  39.     {  
  40.         super.onLayout(changed, l, t, r, b);  
  41.   
  42.         mCurrentView = getChildAt(0);  
  43.   
  44.         if (mItemScrollChangeListener != null)  
  45.         {  
  46.             mItemScrollChangeListener.onChange(mCurrentView,  
  47.                     getChildPosition(mCurrentView));  
  48.         }  
  49.     }  
  50.   
  51.   
  52.     @Override  
  53.     public void onScrollStateChanged(int arg0)  
  54.     {  
  55.     }  
  56.   
  57.     /** 
  58.      *  
  59.      * 滚动时,判断当前第一个View是否发生变化,发生才回调 
  60.      */  
  61.     @Override  
  62.     public void onScrolled(int arg0, int arg1)  
  63.     {  
  64.         View newView = getChildAt(0);  
  65.   
  66.         if (mItemScrollChangeListener != null)  
  67.         {  
  68.             if (newView != null && newView != mCurrentView)  
  69.             {  
  70.                 mCurrentView = newView ;  
  71.                 mItemScrollChangeListener.onChange(mCurrentView,  
  72.                         getChildPosition(mCurrentView));  
  73.   
  74.             }  
  75.         }  
  76.   
  77.     }  
  78.   
  79. }  

我放弃了重写onTouchEvent方法,而是让这个类实现RecyclerView.OnScrollListener接口,然后设置监听,在onScrolled里面进行判断。

至于优化:我使用了一个成员变化存储当前第一个View,只有第一个View发生变化时才回调~~太完美了~

看MainActivity:

[java]  view plain  copy
  1. package com.example.zhy_horizontalscrollview03;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Arrays;  
  5. import java.util.List;  
  6.   
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.support.v7.widget.LinearLayoutManager;  
  10. import android.support.v7.widget.RecyclerView;  
  11. import android.view.View;  
  12. import android.view.Window;  
  13. import android.widget.ImageView;  
  14. import android.widget.Toast;  
  15.   
  16. import com.example.zhy_horizontalscrollview03.GalleryAdapter.OnItemClickLitener;  
  17. import com.example.zhy_horizontalscrollview03.MyRecyclerView.OnItemScrollChangeListener;  
  18.   
  19. public class MainActivity extends Activity  
  20. {  
  21.   
  22.     private MyRecyclerView mRecyclerView;  
  23.     private GalleryAdapter mAdapter;  
  24.     private List<Integer> mDatas;  
  25.     private ImageView mImg ;   
  26.       
  27.       
  28.     @Override  
  29.     protected void onCreate(Bundle savedInstanceState)  
  30.     {  
  31.         super.onCreate(savedInstanceState);  
  32.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  33.         setContentView(R.layout.activity_main);  
  34.           
  35.         mImg = (ImageView) findViewById(R.id.id_content);  
  36.   
  37.         mDatas = new ArrayList<Integer>(Arrays.asList(R.drawable.a,  
  38.                 R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e,  
  39.                 R.drawable.f, R.drawable.g, R.drawable.h, R.drawable.l));  
  40.   
  41.         mRecyclerView = (MyRecyclerView) findViewById(R.id.id_recyclerview_horizontal);  
  42.         LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);  
  43.         linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);  
  44.   
  45.         mRecyclerView.setLayoutManager(linearLayoutManager);  
  46.         mAdapter = new GalleryAdapter(this, mDatas);  
  47.         mRecyclerView.setAdapter(mAdapter);  
  48.   
  49.         mRecyclerView.setOnItemScrollChangeListener(new OnItemScrollChangeListener()  
  50.         {  
  51.             @Override  
  52.             public void onChange(View view, int position)  
  53.             {  
  54.                 mImg.setImageResource(mDatas.get(position));  
  55.             };  
  56.         });  
  57.           
  58.         mAdapter.setOnItemClickLitener(new OnItemClickLitener()  
  59.         {  
  60.             @Override  
  61.             public void onItemClick(View view, int position)  
  62.             {  
  63. //              Toast.makeText(getApplicationContext(), position + "", Toast.LENGTH_SHORT)  
  64. //                      .show();  
  65.                 mImg.setImageResource(mDatas.get(position));  
  66.             }  
  67.         });  
  68.   
  69.     }  
  70.   
  71. }  

代码没什么变化~多了个设置回调~

效果图:


可以看到不仅支持手机在上面移动时的变化,如果我给了一个加速度,下面持续滚动,上面也会持续变化~~大赞~每张图片回调一次,效率也相当不错。


好了,看完这边博客,相信大家对于RecyclerView有了一定的认识,甚至对于如何改造一个控件也多了一份了解~~


如果觉得不错,就留个言或者点个赞,表示对我的支持 


源码点击下载

RecyclerView实现画廊效果|列表选中位置居中|列表位置固定|第一个项目居中|列表平滑滚动 基于RecyclerView实现图片画廊效果, 关键词:图片居中显示,RecyclerView平缓滚动,第一个视图居中,最后一个视图居中 阅读详情

相关推荐

RecyclerView系列:RecyclerView嵌套RecyclerView(BaseRecyclerViewAdapterHelper实现)

看效果图: 先导入依赖包: 导入BaseRecyclerViewAdapterHelper和RecyclerView 把RecyclerView整到布局activity_main.xml中去。 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.and

知道这个有什么用? 4337

理解RecyclerView(五)—RecyclerView的绘制流程

前言:做人如果没有梦想,那和咸鱼有什么区别。        ——《少林足球》 一、概述   上一篇文章对RecyclerView中实现了如何高度自定义点击事件、万能ViewHolder、万能适配器的封装和使用。最开始就提到,RecyclerView支持各种各样的布局效果,其核心关键在于RecyclerView.LayoutManager中,使用时我们是需要setLayoutManager()设置布局管理器的。RecyclerView已经将一部分功能抽离出来,在布局管理器中另外处理,也方便开发者自行拓展。

https://juejin.cn/user/1654096907477549/posts 2456

RecycleView自定义LayoutManager实现Gallery效果,看完这篇

1、可以看到条目的起始位置是从屏幕的一半的地方再减去item宽度的一半的位置开始,而且每个item都是叠在上一个item宽度一般的位置 mStartX = getWidth()/2 - getItemShowWidth(); for (int i = 0; i < getItemCount(); i++) {    &nbs

flunsna的博客 767

解决ViewPager嵌套RecyclerView,RecyclerView嵌套RecyclerView瀑布流事件冲突问题

1.瀑布流效果 2.嵌套滚动效果实现 3.嵌套滚动浮动菜单栏 3.1嵌套事件链接机制 3.2实现上拉刷新,上拉加载更多

Tiger的专栏 2053

Android RecyclerView

1.RecyclerView RecyclerView是Android 5.0推出的,是support-v7包中的新组件,它被用来代替ListView和GridView,并且能够实现瀑布流的布局,更加高级并且更加灵活,提供更为高效的回收复用机制,同时实现管理与视图的解耦合。RecyclerView提供了一种插拔式的体验,高度的解耦,异常的灵活,只需设置其提供的不同的LayoutManager,ItemAnimator和ItemDecoration,就能实现不同的效果。 RecyclerView的优点: ①支

zenmela2011的专栏 1万+

为RecyclerView打造通用Adapter 让RecyclerView更加好用

转载请标明出处: http://blog.youkuaiyun.com/lmj623565791/article/details/47251585; 本文出自:【张鸿洋的博客】 一、概述记得好久以前针对ListView类控件写过一篇打造万能的ListView GridView 适配器,如今RecyclerView异军突起,其Adapter的用法也与ListView类似,那么我们也可以一步一步的为其打

Hongyang 16万+

使用自定义 LayoutManager 实现 Android 中 Gallery 或者 ViewPager 控件的效果

使用自定义 LayoutManager 实现 Android 中 Gallery 或者 ViewPager 控件的效果,支持垂直和水平两个方向,支持 RecycleView 的试图回收机制

RecyclerView详解

RecyclerView 简称 RV, 是作为 ListView 和 GridView 的加强版出现的,目的是在有限的屏幕之上展示大量的内容,因此 RecyclerView 的复用机制的实现是它的一个核心部分。 RV 常规使用方式如下: 解释说明。 setLayoutManager:必选项,设置 RV 的布局管理器,决定 RV 的显示风格。常用的有线性布局管理器(LinearLayoutManager)、网格布局管理器(GridLayoutManager)、瀑布流布局管理器(StaggeredGr

Android 4万+

Android-使用recyclerView实现画廊滑动效果

使用recyclerView实现画廊滑动效果! 相对于viewpager,使用recyclerView的滑动性更流畅!两种方法任君选择。

用RecyclerView制作Gallery画廊效果

使用AndroidL(5.0)最新提供的widget-RecyclerView制作的Gallery画廊效果demo,未添加Fragment左右策划效果。

RecyclerView如何嵌套RecyclerView

Linearlayoutmanager RecyclerView嵌套GridLayoutManager RecyclerView 布局方式:以一个GridLayoutManager的recyclerview作为Linearlayoutmanager RecyclerView的itemview MainRecyclerAdapter.java public class MainRecyclerAdapter extends RecyclerView.Adapter<MainRecyclerAdap

Jonly_W的博客 2845

Android App开发中使用RecyclerView实现Gallery画廊的实例

什么是RecyclerView         RecyclerView是Android 5.0 materials design中的组件之一,相应的还有CardView、Palette等。看名字我们就能看出一点端倪,没错,它主要的特点就是复用。我们知道,Listview中的Adapter中可以实现ViewHolder的复用。RecyclerView提供了一个耦合度更低的方式来复用ViewHolder,并且可以轻松的实现ListView、GridView以及瀑布流的效果。 RecyclerView使用的基本思路         首先我们要gradle的依赖库中添加  compile ‘com.

RecyclerView的canScrollVertically

前几日在某机型上线上出现了一个与RecyclerView上划下滑相关的BUG。 源码解读 看了会儿RecyclerView的canScrollVertically(int direction)函数: /** * Check if this view can be scrolled vertically in a certain direction. * * ...

袋鼠 3346

LabVIEW内存优化实战:用DVR和队列高效处理大型数组,告别数据副本

本文深入探讨LabVIEW内存优化技术,重点介绍数据值引用(DVR)和单元素队列(SEQs)在高效处理大型数组中的应用。通过对比传统方法与现代引用技术的性能差异,提供减少内存副本、提升程序效率的实战方案,帮助开发者在测试测量、图像处理等数据密集型场景中实现显著性能提升。

weixin_30835649的博客 1061

AIGC游戏本地化:用AI实现多语言自动翻译

游戏本地化是游戏全球化战略的关键环节,传统人工翻译方式成本高、周期长。本文旨在探讨如何利用AIGC技术实现高效、准确、低成本的游戏多语言自动翻译解决方案。我们将覆盖从文本翻译到语音合成的完整本地化流程,重点关注AI技术在游戏特定语境下的应用优化。文章首先介绍游戏本地化的核心挑战和AI解决方案,然后深入讲解关键技术原理,接着通过实战项目演示具体实现,最后讨论应用场景和未来趋势。AIGC:人工智能生成内容,指利用AI技术自动生成文本、图像、音频等内容本地化(Localization)

AI 领航者的博客 1336

RecyclerView嵌套RecyclerView的滑动问题如何解

一、概述 虽然今天我们要说的是Rv嵌套Rv的问题,但多数情况下我们都不会使用Rv嵌套Rv,去实现复杂的列表,而使用多个itemType实现,再难点的配合GridLayoutManager.SpanSizeLookup一起解决。 因为Rv嵌套Rv会有问题,如果嵌套的Rv高度没有设置明确的值,会一次创建所有的item,造成卡顿问题。类似我们在NestedScrollView里面嵌套Rv,Rv的高度写的是wrap_content/match_parent,一样的情况。 既然高度不确定,那我们给嵌套的Rv指定高度,

ganduwei的博客 4389

大唐杯5G考前冲刺篇(回顾全文重点必看)

大唐杯习题复习指南

nimo观察者 1万+

Carousel Recyclerview:打造惊艳轮播效果的终极RecyclerView解决方案

Carousel Recyclerview是一款专为Android开发者设计的强大库,它通过自定义布局管理器的方式,让你能够轻松创建出令人惊艳的轮播效果。无论是实现图片展示、产品推荐还是内容轮播,这款终极RecyclerView解决方案都能满足你的需求,帮助你快速构建出专业级的轮播界面。 ## 为什么选择Carousel Recyclerview? 在移动应用开发中,轮播效果是提升用户体验的重

gitblog_00347的博客 1033

华为OD机试真题 新系统 - WIFI设备网络规划 (Java/Py/C/C++/Js/Go)

本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。

算法大师! 2014

【Android Performance】Android CPU调度模式详解:从performance到schedutil的Governor调优指南

本文系统讲解Android/Linux系统中的CPU频率调节策略(Governor),涵盖六大调度模式的底层工作原理:performance(性能优先)、powersave(省电优先)、conservative(保守调频)、ondemand(按需调频)、userspace(手动控制)以及schedutil(调度器驱动)。文中深入拆解每种Governor的调频决策逻辑、上升/下降曲线的差异、适用场景与选型建议,并配以实操命令演示如何查看可用Governor列表、动态切换调度模式以及多Cluster架构下的统一

weixin_44081096的博客 430

Android中RecyclerView嵌套RecyclerView

前言这两天在做一个新的APP,在考虑用户体验上要一个两级的列表嵌套,于就想看看RecyclerView是否能做出这样的效果,自己写了一个DEMO来做一下测试,最后的效果还是比较满意的。下...

Vaccae的博客 1696

硬核实战!Python爬虫从0到1完整版:爬取知乎热榜+回答内容(数据去重+Excel一键导出+避坑指南,零基础友好)

✔️ 适用人群:Python爬虫零基础、想练手实战爬虫、需要爬取知乎内容做数据分析、办公/学习素材整理的同学爬取知乎热榜全量数据(排名+标题+热榜链接+热度值) →自动跟进爬取每个热榜问题的回答内容(回答者昵称+赞同数+评论数+回答正文+发布时间) →数据清洗+智能去重→一键导出格式化Excel文件,所有功能一站式完成入门级难度,无复杂反爬破解、无分布式/代理池,纯requests请求+静态解析,新手能看懂、能运行、能修改;爬取速度快,热榜+回答全程仅需几十秒。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1460
上一篇: SwipeRefresh 各种实现上拉,下拉刷新
下一篇: android加强
code_dream_wq
博客等级 码龄10年 51粉丝 199原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值