RecycleView使用以及Glide缓存问题

xiaoxiao2021-02-27  373

RecycleView+Glide详解。

 

 

Glide框架详解:https://blog.csdn.net/weixin_37730482/article/category/6875816

 

 

代码以及说明

 

 

AndroidStudio配置

implementation 'com.android.support:recyclerview-v7:27.1.1'

 

 

Activity 代码

public class GlideRecycleViewActivity extends AppCompatActivity implements View.OnClickListener{ private Button modebutton; private Button addbutton; private Button delbutton; private RecyclerView recyclerview; private GlideRecycleViewAdapter adapter; private List<Student> list; private int type = 0; private int addposition = 0; private int delposition = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_gliderecycleview); initData(); } /** * 赋值 */ private void initData() { modebutton = findViewById(R.id.activity_gliderecycleview_modebutton); addbutton = findViewById(R.id.activity_gliderecycleview_addbutton); delbutton = findViewById(R.id.activity_gliderecycleview_delbutton); modebutton.setOnClickListener(this); addbutton.setOnClickListener(this); delbutton.setOnClickListener(this); recyclerview = findViewById(R.id.activity_gliderecycleview_recycleview); list = new ArrayList<>(); Student student1 = new Student(); student1.setName("詹姆斯"); student1.setAva("http://XXX.jpg"); student1.setAge(student1.getName() + ":很懒什么也没留下!"); Student student2 = new Student(); student2.setName("韦德"); student2.setAva("https://XXX.png"); student2.setAge(student2.getName() + ":很懒什么也没留下!"); Student student3 = new Student(); student3.setName("山东鲁能"); student3.setAva("http://XXX.png"); student3.setAge(student3.getName() + ":很懒什么也没留下!"); Student student4 = new Student(); student4.setName("保罗"); student4.setAva(""); student4.setAge(student4.getName() + ":很懒什么也没留下!"); Student student5 = new Student(); student5.setName("安东尼"); student5.setAva(""); student5.setAge(student5.getName() + ":很懒什么也没留下!"); Student student6 = new Student(); student6.setName("蒿俊闵"); student6.setAva("http://XXX.gif"); student6.setAge(student6.getName() + ":很懒什么也没留下!"); Student student7 = new Student(); student7.setName("李霄鹏"); student7.setAva(""); student7.setAge(student7.getName() + ":没有上传头像!"); for (int i = 0; i < 30; i++) { list.add(student1); list.add(student2); list.add(student3); list.add(student4); list.add(student5); list.add(student6); list.add(student7); } //2.设置LinearLayoutManager ListView recyclerview.setLayoutManager(new LinearLayoutManager(this)); //3.设置ItemAnimator recyclerview.setItemAnimator(new DefaultItemAnimator()); //4.设置固定大小 recyclerview.setHasFixedSize(true); adapter = new GlideRecycleViewAdapter(this, this, list); recyclerview.setAdapter(adapter); /** * RecycleView滚动监听是开始加载Glide还是暂停加载Glide * */ recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); switch (newState) { case SCROLL_STATE_SETTLING://滚动 Glide.with(GlideRecycleViewActivity.this).pauseRequests();//停止Glide加载图片 break; case SCROLL_STATE_DRAGGING://拖动 Glide.with(GlideRecycleViewActivity.this).pauseRequests();//停止Glide加载图片 break; case SCROLL_STATE_IDLE://空闲 Glide.with(GlideRecycleViewActivity.this).resumeRequests();//开始Glide加载图片 break; default://其他 Glide.with(GlideRecycleViewActivity.this).pauseRequests();//停止Glide加载图片 break; } adapter.notifyDataSetChanged(); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); } }); /** * Item点击以及长按监听 * */ if (null != adapter) { adapter.setRecycleViewItemClickAndLongClick(new RecycleViewAdapterInterface() { @Override public void OnItemCilck(View view, int position) { if (null != list) { String name = list.get(position).getName(); Toast.makeText(GlideRecycleViewActivity.this, "点击:" + name, Toast.LENGTH_SHORT).show(); } } @Override public void OnItemLongCilck(View view, int position) { if (null != list) { String name = list.get(position).getName(); Toast.makeText(GlideRecycleViewActivity.this, "长按:" + name, Toast.LENGTH_SHORT).show(); } } }); } } /** * 各种点击事件的View */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.activity_gliderecycleview_modebutton://变换模式 type++; if (type == 0) {//列表 modebutton.setText("列表"); recyclerview.setLayoutManager(new LinearLayoutManager(GlideRecycleViewActivity.this)); } else if (type == 1) {//网格 modebutton.setText("网格"); recyclerview.setLayoutManager(new GridLayoutManager(GlideRecycleViewActivity.this, 4)); } else if (type == 2) {//横向列表 modebutton.setText("横向列表"); recyclerview.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.HORIZONTAL)); } else { type = 0; modebutton.setText("列表"); recyclerview.setLayoutManager(new LinearLayoutManager(GlideRecycleViewActivity.this)); } break; case R.id.activity_gliderecycleview_addbutton://添加数据 if (null != adapter) { addposition++; Student student = new Student(); student.setName("詹姆斯" + addposition); student.setAva("http://XXX.png"); student.setAge(student.getName() + ":很懒什么也没留下!"); adapter.addData(student, addposition); } break; case R.id.activity_gliderecycleview_delbutton://删除数据 if (null != adapter) { delposition++; adapter.removeData(delposition); } break; default: break; } } /** * onKeyDown方法 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { finish(); return false; } return super.onKeyDown(keyCode, event); } }

 

 

Activity 布局xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/activity_gliderecycleview_linearlayout" android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" android:weightSum="3"> <Button android:id="@+id/activity_gliderecycleview_modebutton" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="列表" /> <Button android:id="@+id/activity_gliderecycleview_addbutton" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:layout_weight="1" android:text="插入数据" /> <Button android:id="@+id/activity_gliderecycleview_delbutton" android:layout_width="0dp" android:layout_height="match_parent" android:layout_marginLeft="10dp" android:layout_weight="1" android:text="删除数据" /> </LinearLayout> <View android:id="@+id/activity_gliderecycleview_view" android:layout_width="match_parent" android:layout_height="1dp" android:layout_below="@+id/activity_gliderecycleview_linearlayout" android:background="#CCCCCC" /> <android.support.v7.widget.RecyclerView android:id="@+id/activity_gliderecycleview_recycleview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/activity_gliderecycleview_view"> </android.support.v7.widget.RecyclerView> </RelativeLayout>

 

 

 

Adapter 代码

public class GlideRecycleViewAdapter extends RecyclerView.Adapter<GlideRecycleViewAdapter.ViewHolder> { private Activity activity; private Context context; private List<Student> list; private LayoutInflater mInflater; private RecycleViewAdapterInterface recycleViewAdapterInterface=null; public void setRecycleViewItemClickAndLongClick(RecycleViewAdapterInterface recycleViewAdapterInterface){ this.recycleViewAdapterInterface=recycleViewAdapterInterface; } public GlideRecycleViewAdapter(Activity activity,Context context,List<Student> list){ this.activity=activity; this.context=context; this.list=list; mInflater = LayoutInflater.from(context); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view=mInflater.inflate(R.layout.gliderecycleview_item, parent, false); ViewHolder holder = new ViewHolder(view); return holder; } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.textView1.setText(list.get(position).getName() + "【" + (position + 1) + "】"); holder.textView2.setText(list.get(position).getAge()); String ava = list.get(position).getAva(); RequestOptions options = new RequestOptions() .diskCacheStrategy(DiskCacheStrategy.DATA) .placeholder(R.mipmap.patient_ava) .error(R.mipmap.patient_ava); if(!BooleanUtils.isEmpty(ava)){//头像不为空 //文字显示颜色 holder.textView1.setTextColor(context.getResources().getColor(R.color.colorPrimary)); holder.textView2.setTextColor(context.getResources().getColor(R.color.colorPrimary)); //获取 ava 对应的缓存文件 File file=new GlideImageUtils(context).getCacheFile(ava); if(null!=file){//缓存文件不为空 直接加载file对应的图片 Glide.with(activity) .load(file) .apply(options) .into(holder.circleImageView); }else{//缓存文件为空 加载url对应的图片 Glide.with(activity) .load(ava) .apply(options) .into(holder.circleImageView); } }else{//头像为空 //文字显示颜色 holder.textView1.setTextColor(context.getResources().getColor(R.color.colorAccent)); holder.textView2.setTextColor(context.getResources().getColor(R.color.colorAccent)); Glide.with(activity) .load("http:www") .apply(options) .into(holder.circleImageView); } /** * 捕获RecycleView的Item点击以及长按事件 * */ final int clickposition=position; //Item点击 holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(null!=recycleViewAdapterInterface){ recycleViewAdapterInterface.OnItemCilck(v,clickposition); } } }); //Item长按 holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if(null!=recycleViewAdapterInterface){ recycleViewAdapterInterface.OnItemLongCilck(v,clickposition); } return true; } }); } @Override public int getItemCount() { return list.size(); } /** * ViewHolder类 * */ class ViewHolder extends RecyclerView.ViewHolder{ private ImageView circleImageView; private TextView textView1; private TextView textView2; public ViewHolder(View itemView) { super(itemView); circleImageView = itemView.findViewById(R.id.gliderecycleview_circleimageview); textView1 = itemView.findViewById(R.id.gliderecycleview_item_textview1); textView2 = itemView.findViewById(R.id.gliderecycleview_item_textview2); } } /** * 添加数据 * */ public void addData(Student student,int position) { list.add(position, student); notifyItemInserted(position); notifyItemRangeChanged(position,list.size()); } /** * 删除数据 * */ public void removeData(int position) { list.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position,list.size()); } }

 

 

 

Item布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="80dp"> <ImageView android:id="@+id/gliderecycleview_circleimageview" android:layout_width="60dp" android:layout_height="60dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="15dp" android:scaleType="fitXY" android:src="@mipmap/patient_ava" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="60dp" android:layout_centerVertical="true" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:layout_toRightOf="@+id/gliderecycleview_circleimageview"> <TextView android:id="@+id/gliderecycleview_item_textview1" android:layout_width="match_parent" android:layout_height="30dp" android:ellipsize="end" android:gravity="center|left" android:singleLine="true" android:text="张三" android:textColor="@color/colorPrimary" android:textSize="14sp" /> <TextView android:id="@+id/gliderecycleview_item_textview2" android:layout_width="match_parent" android:layout_height="30dp" android:layout_below="@+id/gliderecycleview_item_textview1" android:ellipsize="end" android:gravity="center|left" android:singleLine="true" android:text="这个人很懒什么也没留下" android:textColor="@color/colorPrimary" android:textSize="14sp" /> </RelativeLayout> <View android:layout_width="match_parent" android:layout_height="0.5dp" android:layout_alignParentBottom="true" android:background="#CCCCCC"/> </RelativeLayout>

 

 

接口

public interface RecycleViewAdapterInterface { void OnItemCilck(View view, int position); void OnItemLongCilck(View view,int position); }

 

 

缓存类 OriginalKey

import com.bumptech.glide.load.Key; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; public class OriginalKey implements Key { private final String id; private final Key signature; public OriginalKey(String id, Key signature) { this.id = id; this.signature = signature; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } OriginalKey that = (OriginalKey) o; if (!id.equals(that.id)) { return false; } if (!signature.equals(that.signature)) { return false; } return true; } @Override public int hashCode() { int result = id.hashCode(); result = 31 * result + signature.hashCode(); return result; } @Override public void updateDiskCacheKey(MessageDigest messageDigest) { try { messageDigest.update(id.getBytes(STRING_CHARSET_NAME)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } signature.updateDiskCacheKey(messageDigest); } }

 

 

 

缓存类 SafeKeyGenerator

import com.bumptech.glide.load.Key; import com.bumptech.glide.util.LruCache; import com.bumptech.glide.util.Util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class SafeKeyGenerator { private final LruCache<Key, String> loadIdToSafeHash = new LruCache<Key, String>(1000); public String getSafeKey(Key key) { String safeKey; synchronized (loadIdToSafeHash) { safeKey = loadIdToSafeHash.get(key); } if (safeKey == null) { try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); key.updateDiskCacheKey(messageDigest); safeKey = Util.sha256BytesToHex(messageDigest.digest()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } synchronized (loadIdToSafeHash) { loadIdToSafeHash.put(key, safeKey); } } return safeKey; } }

 

 

缓存类 GlideImageUtils

import android.content.Context; import com.bumptech.glide.disklrucache.DiskLruCache; import com.bumptech.glide.load.engine.cache.DiskCache; import com.bumptech.glide.signature.EmptySignature; import java.io.File; import java.io.IOException; public class GlideImageUtils { private Context context; public GlideImageUtils(Context context){ this.context=context; } public File getCacheFile(String id) { OriginalKey originalKey = new OriginalKey(id, EmptySignature.obtain()); SafeKeyGenerator safeKeyGenerator = new SafeKeyGenerator(); String safeKey = safeKeyGenerator.getSafeKey(originalKey); try { DiskLruCache diskLruCache = DiskLruCache.open(new File(context.getCacheDir(), DiskCache.Factory.DEFAULT_DISK_CACHE_DIR), 1, 1, DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE); DiskLruCache.Value value = diskLruCache.get(safeKey); if (value != null) { return value.getFile(0); } } catch (IOException e) { e.printStackTrace(); } return null; } }

 

 

注意:

 

1.RecycleView所在包android.support.v7.widget.RecyclerView。

 

2.和ListView直接继承BaseAdapter不同。RecycleView的适配器

 继承RecyclerView.Adapter<GlideRecycleViewAdapter.ViewHolder>。然后至少需要重写三个方法。

onCreateViewHolder方法:引入Item布局。 onBindViewHolder方法:获取数值。 getItemCount方法:获取列表Item条数。

 

3.与ListView不同,RecycleView没有直接提供Item点击以及Item长按事件。需要自己写。

3.1.自定义接口

public interface RecycleViewAdapterInterface { void OnItemCilck(View view, int position); void OnItemLongCilck(View view,int position); }

 

3.2.Adapter中初始化以及暴露外部调用方法

private RecycleViewAdapterInterface recycleViewAdapterInterface=null; public void setRecycleViewItemClickAndLongClick(RecycleViewAdapterInterface recycleViewAdapterInterface){ this.recycleViewAdapterInterface=recycleViewAdapterInterface; }

 

onBindViewHolder方法中

/** * 捕获RecycleView的Item点击以及长按事件 * */ final int clickposition=position; //Item点击 holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(null!=recycleViewAdapterInterface){ recycleViewAdapterInterface.OnItemCilck(v,clickposition); } } }); //Item长按 holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if(null!=recycleViewAdapterInterface){ recycleViewAdapterInterface.OnItemLongCilck(v,clickposition); } return true; } });

holder.itemView:

 

 

 

3.2.2.外部调用(全局)

/** * Item点击以及长按监听 * */ if (null != adapter) { adapter.setRecycleViewItemClickAndLongClick(new RecycleViewAdapterInterface() { @Override public void OnItemCilck(View view, int position) { if (null != list) { String name = list.get(position).getName(); Toast.makeText(GlideRecycleViewActivity.this, "点击:" + name, Toast.LENGTH_SHORT).show(); } } @Override public void OnItemLongCilck(View view, int position) { if (null != list) { String name = list.get(position).getName(); Toast.makeText(GlideRecycleViewActivity.this, "长按:" + name, Toast.LENGTH_SHORT).show(); } } }); }

 

 

4.删除和添加数据

RecycleView删除添加数据非常方便。

 

Adapter中

/** * 添加数据 * */ public void addData(Student student,int position) { list.add(position, student); notifyItemInserted(position); notifyItemRangeChanged(position,list.size()); } /** * 删除数据 * */ public void removeData(int position) { list.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position,list.size()); }

 

Activity 中

case R.id.activity_gliderecycleview_addbutton://添加数据 if (null != adapter) { addposition++; Student student = new Student(); student.setName("詹姆斯" + addposition); student.setAva("http://cdspres.oss-cn-beijing.aliyuncs.com/avatar/80366a04e7874e4fa04a6ef8e68ab3751525391386176.png"); student.setAge(student.getName() + ":很懒什么也没留下!"); adapter.addData(student, addposition); } break; case R.id.activity_gliderecycleview_delbutton://删除数据 if (null != adapter) { delposition++; adapter.removeData(delposition); } break;

 

 

5.RecycleView的滚动事件最好是这样添加。

recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener())

因为

recyclerview.setOnScrollListener(new RecyclerView.OnScrollListener())

可能会出现空指针,且已过期。另外RecycleView滚动事件 状态

SCROLL_STATE_SETTLING:滚动

SCROLL_STATE_DRAGGING:拖动

SCROLL_STATE_IDLE:空闲

 

 

 

6.目前SDK中提供了三种自带的LayoutManager

LinearLayoutManager:ListView列表

GridLayoutManager:GridView列表

StaggeredGridLayoutManager:纵向列表

recyclerview.setLayoutManager(new LinearLayoutManager(this)); recyclerview.setLayoutManager(new GridLayoutManager(GlideRecycleViewActivity.this, 4));//4:GridView一行显示几个Item recyclerview.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.HORIZONTAL));2:纵向列表一页显示几行item

 

 

7.可设置RecycleView的Animator(动画效果,这里以默认为例)

recyclerview.setItemAnimator(new DefaultItemAnimator());

 

 

转载请注明原文地址: https://www.6miu.com/read-5904.html

最新回复(0)