我正在构建一个应用程序,该应用程序允许用户上传自己的图像以在该应用程序中使用。我正在使用Firebase Cloudstore数据库存储每个图像上的信息,并使用Firebase Storage存储实际图像。
因此,图像存储在Firebase存储中的名为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是否确实连接到存储来查找图像,但是肯定没有显示它。
谁能看到我要去哪里错了?
答案 0 :(得分:0)
Cloud Storage中的每个图像都有一个gs(Google存储)URL,并且当然不能公开访问,这意味着您必须首先获得下载链接。
使用Firebase Storage SDK进行此操作。