@rookiedev是正确的, Glide中没有load(Bitmap)它,这是有原因的:获取一个
Bitmap通常花费时间,有时会阻塞I / O。因此,调用imageWithTextUI线程不是一个好习惯。更新:话虽这么
说,我提出了这个功能一而回; 尽管更容易进行黑客攻击,但您可以在下面找到我强烈建议的“滑行方式” 。
Glide的设计具有灵活性,这个问题很好地证明了这一特性。以下实现似乎很长,但是所有部分
都有其存在的原因。考虑到性能的提高,使您的生成器适合Glide世界的代码量并不多。我试图将其格式化
为简短的格式,折叠了不相关的部分,并使用静态导入来使其更短(请参阅结尾部分的导入)。
该代码还包括以编程方式生成的UI,因此您只需将以下所有代码复制粘贴到GlideGeneratedImageListFragment.java并运行它即可;唯一的外部依赖关系是support lib’s RecyclerView。
class GeneratingAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { // See https://docs.google.com/drawings/d/1KyOJkNd5Dlm8_awZpftzW7KtqgNR6GURvuF6RfB210g/edit?usp=sharing // ModelType/A, DataType/T, ResourceType/Z, TranspreType/R private final GenericRequestBuilder<GenerateParams, GenerateParams, Bitmap, GlideDrawable> generator; public GeneratingAdapter(final Context context) { generator = Glide // this part should be cleaner in Glide 4.0, but that's not released yet .with(context) .using(new GenerateParamsPassthroughModelLoader(), GenerateParams.class) // custom class .from(GenerateParams.class) .as(Bitmap.class) .transpre(new BitmapToGlideDrawableTransprer(context), GlideDrawable.class) // builtin .deprer(new GenerateParamsBitmapResourceDeprer(context)) // custom class .enprer(new BitmapEnprer(Bitmap.CompressFormat.PNG, 0)) // builtin .cacheDeprer(new FileToStreamDeprer<Bitmap>(new StreamBitmapDeprer(context))) // builtin //.placeholder(new ColorDrawable(Color.YELLOW)) // you can pre-set placeholder and error .error(new ColorDrawable(Color.RED)) // so it's easier when binding //.diskCacheStrategy(DiskCacheStrategy.NONE) // only for debugging to always regenerate //.skipMemoryCache(true) // only for debugging to always regenerate ; } @Override public int getItemCount() { return 1000; } private final float[] colorCache = new float[] {0, 1.0f, 0.5f}; private final float[] bgCache = new float[] {0, 0.5f, 1.0f}; @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { colorCache[0] = bgCache[0] = (position * 15) % 360; // just to have a fancy example :) GenerateParams params = new GenerateParams( // omit position to see Glide caching in action (every 24th item / 12th row is the same) "android text", Color.HSVToColor(colorCache), Color.HSVToColor(bgCache) ); generator.load(params).into((ImageView)holder.itemView); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { int height = parent.getContext().getResources().getDisplayMetrics().heightPixels / 3; ImageView view = new ImageView(parent.getContext()); view.setLayoutParams(new RecyclerView.LayoutParams(MATCH_PARENT, height)); view.setScaleType(ImageView.ScaleType.FIT_CENTER); return new RecyclerView.ViewHolder(view) {}; // anon class for brevity }}public class GlideGeneratedImageListFragment extends Fragment { @Override public @Nullable View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { RecyclerView view = new RecyclerView(container.getContext()); view.setLayoutParams(new MarginLayoutParams(MATCH_PARENT, MATCH_PARENT)); view.setLayoutManager(new GridLayoutManager(container.getContext(), 2 )); view.setAdapter(new GeneratingAdapter(view.getContext())); return view; }}class GenerateParams { final String text; final int color; final int background; public GenerateParams(String text, int color, int bg) { this.text = text; this.color = color; this.background = bg; } public String getId() { // TODO make sure it's unique for every possible instance of GenerateParams // because it will affect how the resulting bitmap is cached // the below is correct correct for the current fields, if those change this has to change return String.format(Locale.ROOT, "%s-%08x-%08x", text, color, background); }}class GenerateParamsPassthroughModelLoader implements ModelLoader<GenerateParams, GenerateParams> { @Override public DataFetcher<GenerateParams> getResourceFetcher(final GenerateParams model, int width, int height) { return new DataFetcher<GenerateParams>() { @Override public GenerateParams loadData(Priority priority) throws Exception { return model; } @Override public void cleanup() { } @Override public String getId() { return model.getId(); } @Override public void cancel() { } }; }}class GenerateParamsBitmapResourceDeprer implements ResourceDeprer<GenerateParams, Bitmap> { private final Context context; public GenerateParamsBitmapResourceDeprer(Context context) { this.context = context; } @Override public Resource<Bitmap> depre(GenerateParams source, int width, int height) throws IOException { BitmapPool pool = Glide.get(context).getBitmapPool(); Bitmap bitmap = pool.getDirty(width, height, Bitmap.Config.ARGB_8888); if (bitmap == null) { bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); } Generators.imageWithTextNoLayout(context, bitmap, source); return BitmapResource.obtain(bitmap, pool); } @Override public String getId() { // be careful if you change the Generator implementation you have to change this // otherwise the users may see a cached image; or clear cache on app update return "com.example.MyImageGenerator"; }}class Generators { public static Bitmap imageWithText(Context context, Bitmap bitmap, GenerateParams params) { TextView view = new TextView(context); view.setText(params.text); view.setTextColor(params.color); view.setBackgroundColor(params.background); view.setTypeface(null, Typeface.BOLD); view.setGravity(Gravity.CENTER); view.setTextSize(20 ); Canvas canvas = new Canvas(bitmap); view.measure(makeMeasureSpec(canvas.getWidth(), EXACTLY), makeMeasureSpec(canvas.getHeight(), EXACTLY)); view.layout(0, 0, canvas.getWidth(), canvas.getHeight()); view.draw(canvas); return bitmap; } public static Bitmap imageWithTextNoLayout(Context context, Bitmap bitmap, GenerateParams params) { Paint paint = new Paint(); paint.setColor(params.color); paint.setTextAlign(Paint.Align.CENTER); // text's anchor for the x given in drawText paint.setTextSize(applyDimension(COMPLEX_UNIT_SP, 20, context.getResources().getDisplayMetrics())); paint.setTypeface(Typeface.DEFAULT_BOLD); Canvas canvas = new Canvas(bitmap); canvas.drawColor(params.background); canvas.drawText(params.text, canvas.getWidth() / 2, canvas.getHeight() / 2, paint); return bitmap; }}// Here are the imports in case you need it;// didn't want to put it in the beginning to keep the relevant pre first.import java.io.IOException;import java.util.Locale;import android.content.Context;import android.graphics.*;import android.graphics.drawable.ColorDrawable;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.support.v7.widget.*;import android.view.*;import android.view.ViewGroup.MarginLayoutParams;import android.widget.*;import static android.util.TypedValue.*;import static android.view.View.MeasureSpec.*;import static android.view.ViewGroup.LayoutParams.*;import com.bumptech.glide.*;import com.bumptech.glide.load.ResourceDeprer;import com.bumptech.glide.load.data.DataFetcher;import com.bumptech.glide.load.engine.Resource;import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;import com.bumptech.glide.load.model.ModelLoader;import com.bumptech.glide.load.resource.bitmap.*;import com.bumptech.glide.load.resource.drawable.GlideDrawable;import com.bumptech.glide.load.resource.file.FileToStreamDeprer;import com.bumptech.glide.load.resource.transpre.BitmapToGlideDrawableTransprer;外观如下所示(实际滚动要平滑得多,GIF的FPS 确实很低):
请注意,它是如何加载前几项,然后逐渐加载其余项的。它需要一点点的内存缓存和池升温,但你可以使用一个,如果你想更平滑的显示预加载。预热后,滚动效果很好。操作栏上的删除按钮会调用Glide.clearDiskCache(),Glide.clearMemory()因此它将再次开始重新生成项目。



