android - 如何使用存储在 Firebase 存储中的图像?
问题描述
我正在构建一个应用程序,它允许用户上传他们自己的图像,以便在应用程序中使用。我使用 Firebase Cloudstore 数据库存储每个图像的信息,并使用 Firebase Storage 存储实际图像。
因此,图像存储在 Firebase Storage 中一个名为 images 的文件夹中;其中,它们被赋予一个随机生成的名称,该名称存储在数据库中的相应记录中。假设特定图像的名称是“abcd.png”,那么数据库记录将如下所示:
symbols
> key1 > name: "Test symbol"
uid: "User's randomly generated ID"
description: "A description, as set by the user"
url: "images/abcd.png"
现在,我想将所有用户上传的图像显示为小缩略图。我正在连接到数据库,查找属于当前用户的所有符号,然后使用 ArrayAdapter 来显示它们。不幸的是,我目前得到一排空白框。我不确定我做错了什么。
符号显示在名为 CurrentSymbolsFragment 的片段中。布局(fragment_current_symbols.xml)是:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="@+id/gridview_symbolList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchMode="columnWidth"
</GridView>
</android.support.constraint.ConstraintLayout>
类文件是:
public class FragmentCurrentSymbols extends Fragment {
private ArrayList<ChartSymbol> mSymbols;
private Context mContext;
private GridView mGridCurrentSymbols;
static public FragmentCurrentSymbols newInstance(Context context,
ArrayList<ChartSymbol> symbols) {
if(context == null) return null;
if(symbols == null) return null;
if(symbols.size() == 0) return null;
FragmentCurrentSymbols f = new FragmentCurrentSymbols();
f.setRequiredData(context, symbols);
return f;
}
public void setRequiredData(Context context, ArrayList<ChartSymbol> symbols) {
if(context == null) return;
if(symbols == null) return;
if(symbols.size() == 0) return;
this.mContext = context;
this.mSymbols = symbols;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// Inflate layout
View rootView = inflater.inflate(R.layout.fragment_current_symbols, container, false);
mGridCurrentSymbols = rootView.findViewById(R.id.gridview_symbolList)
initialiseWithSymbols();
return rootView;
}
// Set symbols to be shown and initialise the view
public void setSymbols(ArrayList<ChartSymbol> symbols) {
mSymbols = symbols;
initialiseWithSymbols();
}
/**
* initialiseWithSymbols
* Initialise the symbol list from the symbols
* This takes the symbols and shows them, in order, in the grid
**/
public void initialiseWithSymbols() {
if (mSymbols == null) return;
// Now set up ChartSymbolAdapter to display symbols in grid
ChartSymbolAdapter mSymbolAdapter = new ChartSymbolAdapter(mContext,
R.layout.adapter_symbol_manage_layout,
mSymbols);
mGridCurrentSymbols.setAdapter(mSymbolAdapter);
mGridCurrentSymbols.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
ChartSymbolAdapter
课程是:
public class ChartSymbolAdapter extends ArrayAdapter<ChartSymbol> {
private Context mContext;
private ArrayList<ChartSymbol> mSymbolArray;
private int layoutId;
private ChartSymbol selectedSymbol;
public ChartSymbolAdapter(Context context, int layout_id, ArrayList<ChartSymbol> symbolArray) {
super(context, layout_id, symbolArray);
this.mContext=context;
this.mSymbolArray=symbolArray;
this.layoutId = layout_id;
}
private static class ViewHolder {
private SymbolCell symbolCell;
private TextView symbolName, symbolKey;
}
@NonNull
@Override
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
ViewHolder mViewHolder;
StorageReference mStorageRef = FirebaseStorage.getInstance().getReference();
if(convertView == null) {
mViewHolder = new ViewHolder();
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
assert layoutInflater != null;
convertView = layoutInflater.inflate(layoutId, parent, false);
mViewHolder.symbolCell = convertView.findViewById(R.id.symbol_cell);
mViewHolder.symbolName = convertView.findViewById(R.id.symbol_name);
mViewHolder.symbolKey = convertView.findViewById(R.id.symbol_key);
convertView.setTag(mViewHolder);
// Now add the symbol
ChartSymbol cellSymbol = mSymbolArray.get(position);
// Find the url
String drawableUrl = cellSymbol.getUrl();
// If there's a Url, use it
if(drawableUrl != null) {
Glide.with(getContext())
.load(drawableUrl)
.into(mViewHolder.symbolCell);
}
}
return convertView;
}
}
类SymbolCell
扩展ImageView
:
public class SymbolCell extends android.support.v7.widget.AppCompatImageView {
ChartSymbol symbol;
Paint paint;
public SymbolCell(Context thisContext, AttributeSet attrs) {
super(thisContext, attrs);
paint = new Paint();
}
/**
* onDraw
* Draw a square to contain the given symbol.
* @param canvas Canvas to draw on
*/
protected void onDraw(Canvas canvas) {
// Draw a box around cell
// Set paint
int stroke_width = 2;
paint.setStrokeWidth(stroke_width);
float height = getHeight();
float width = getWidth();
// Draw a black border for item
paint.setColor(0xff000000);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(0, 0, width - 2*stroke_width, height - 2*stroke_width, paint);
}
}
当我尝试这个时,我得到了一系列空白框。存储的符号与我存储的符号一样多,所以这是正确的,但它们没有显示实际图像。我已经确定我使用的图像的颜色一直到边缘,所以这不是问题。
这是我第一次在项目中使用 Glide,所以我在那里做错了吗?
使用调试器,我可以看到从 Firestore 中正确检索了符号,并且 URL 是正确的。我不确定如何检查 Glide 是否真的连接到存储来查找图像,但它肯定没有显示它。
谁能看到我哪里出错了?
解决方案
Cloud Storage 中的每张图片都有一个 gs(Google Storage)网址,当然不能公开访问,这意味着您必须先获取下载链接。
使用 Firebase 存储 SDK 执行此操作。
推荐阅读
- flutter - 重启 CircularCountdownTimer 颤振 onComplete
- wordpress - 页面子项不会出现在 wp_nav_menu 中
- python - python boto无法获取docker容器的环境变量
- python - 在 GPU(而不是 CPU)上运行对象检测算法的问题
- javascript - 通过数组映射后根据索引对对象数组进行排序
- javascript - 浏览器扩展兼容性 - 检查浏览器是 chrome 还是 firefox
- r - 尽管在 r 中使用 as.POSIXct 时间跨过午夜,但日期并没有改变
- c# - C# File System Watcher windows 服务发生内存泄漏,无法追踪导致内存泄漏的原因
- python - 内置身份验证视图的 Django Admin 不会消失
- javascript - 在javascript嵌套循环中获取未知整数