[英]Can't set image in RecyclerView using URI
我正在開發一個應用程序,它從 SQLite 數據庫中提取信息並將其顯示在 RecyclerView 中。 我無法使用 URI 在 RecyclerView 中設置圖像。
Uri mImageUri=data.getData();
imgUri = data.getData();
// Get path (Path will be stored in database)
String imgToString = imgUri.toString();
// Get URI back from path
imgUri = Uri.parse(imgToString);
// Set ImageView
plainImage.setImageURI(imgUri);
// Set Glide image
Glide.with(this)
.asBitmap()
.load(imgUri)
.into(image);
這是從圖庫中選擇圖片后我的 OnActivityResult() 的片段。 使用此代碼在基本活動中設置圖像是可行的。 我從 URI 中獲取 toString() 並將其保存在我的數據庫中。 (在最終版本的應用程序中獲取 URI 之前,我會將選定的圖片移動到應用程序文件夾)
但是,當我從數據庫中檢索 URI 字符串,將它們解析回 URI,並嘗試在 RecyclerView 中設置圖像時,此方法不再有效。
這是來自 RecyclerAdapter 的 OnBindViewHolder()
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: called.");
// Load only first image for now
if(mImages.get(position).size() > 0) {
tempUri = Uri.parse(mImages.get(position).get(0));
// Make glide work with image
Glide.with(mContext)
.asBitmap()
.load(tempUri)
.into(holder.image);
// With regular ImageView
holder.imageViewTest.setImageURI(tempUri);
}
holder.weight.setText(mWeights.get(position).toString());
holder.location.setText(mLocations.get(position));
holder.confidence.setText(mConfidences.get(position).toString());
// Open item view
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, ItemView.class);
// Attach additional data to intent
intent.putExtra("image_url", mImages.get(position));
intent.putExtra("location", mLocations.get(position));
intent.putExtra("confidence", mConfidences.get(position));
intent.putExtra("weight", mWeights.get(position));
mContext.startActivity(intent);
}
});
}
檢查變量時,URI 似乎很好。 什么可能導致這種情況,我怎樣才能在 RecyclerView 中設置圖像?
謝謝
編輯
這是適配器代碼
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private static final String TAG = "RecyclerViewAdapter";
private ArrayList<ArrayList<String>> mImages;
private ArrayList<Float> mWeights;
private ArrayList<Float> mConfidences;
private ArrayList<String> mLocations;
private ArrayList<Integer> mSharkEntryIds;
private Context mContext;
private Uri tempUri;
public RecyclerViewAdapter(Context context, ArrayList<Integer> ids, ArrayList<ArrayList<String>> images, ArrayList<Float> weights
, ArrayList<Float> confidences, ArrayList<String> locations) {
this.mContext = context;
this.mSharkEntryIds = ids;
this.mImages = images;
this.mWeights = weights;
this.mLocations = locations;
this.mConfidences = confidences;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_list_item, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
Log.d(TAG, "onBindViewHolder: called.");
// Load only first image for now
if(mImages.get(position).size() > 0) {
tempUri = Uri.parse(mImages.get(position).get(0));
// Make glide work with image
Glide.with(mContext)
.asBitmap()
.load(tempUri)
.into(holder.image);
}
holder.weight.setText(mWeights.get(position).toString() + " kg");
holder.location.setText(mLocations.get(position));
holder.confidence.setText(mConfidences.get(position).toString() + " %");
// Open item view
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mContext, ItemView.class);
// Attach additional data to intent
intent.putExtra("id", mSharkEntryIds.get(position));
intent.putExtra("image_url", mImages.get(position));
intent.putExtra("location", mLocations.get(position));
intent.putExtra("confidence", mConfidences.get(position));
intent.putExtra("weight", mWeights.get(position));
mContext.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return mImages.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
CircleImageView image;
TextView weight;
TextView confidence;
TextView location;
RelativeLayout parentLayout;
public ViewHolder(@NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.thumbnail);
weight = itemView.findViewById(R.id.biomassText);
confidence = itemView.findViewById(R.id.confidenceText);
location = itemView.findViewById(R.id.locationText);
parentLayout = itemView.findViewById(R.id.parent_layout);
}
}
}
這是我初始化 RecyclerView 的代碼
// Vars
private ArrayList<Integer> mSharkEntryIds = new ArrayList<>();
private ArrayList<String> mLocations = new ArrayList<>();
//private ArrayList<String> mImageUrls = new ArrayList<>();
private ArrayList<ArrayList<String>> mImagePaths = new ArrayList<>();
private ArrayList<Float> mConfidences = new ArrayList<>();
private ArrayList<Float> mWeights = new ArrayList<>();
private DatabaseHelper mDatabaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view);
mDatabaseHelper = new DatabaseHelper(this);
Log.d(TAG, "onCreate: started");
//initImageBitmaps();
// Populate list view
Cursor data = mDatabaseHelper.getSharkEntriesFromDatabase();
while(data.moveToNext()){
mSharkEntryIds.add(data.getInt(0));
mWeights.add(data.getFloat(1));
mLocations.add(data.getString(2));
mConfidences.add(data.getFloat(3));
}
Log.d(TAG, "onCreate: test");
// Get associated image paths
ArrayList<String> photosForEntry;
for(Integer id : mSharkEntryIds){
data = mDatabaseHelper.getPhotosWithSharkID(id);
photosForEntry = new ArrayList<>();
while(data.moveToNext()){
photosForEntry.add(data.getString(0));
}
mImagePaths.add(photosForEntry);
}
initRecyclerView();
}
private void initRecyclerView(){
Log.d(TAG, "initRecyclerView: init recyclerview");
RecyclerView recyclerView = findViewById(R.id.recycler_view);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, mSharkEntryIds, mImagePaths, mWeights, mConfidences, mLocations);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
我認為您做錯了,我會假設您在mImages
中獲得了字符串形式的路徑
你看到你的onBindViewHolder
的這一部分:
...................
// Load only first image for now
if(mImages.get(position).size() > 0) {
tempUri = Uri.parse(mImages.get(position).get(0));
// Make glide work with image
Glide.with(mContext)
.asBitmap()
.load(tempUri)
.into(holder.image);
// With regular ImageView
holder.imageViewTest.setImageURI(tempUri);
}
..................
將其更改為:
........
// Load only first image for now
if(position == 0) {
tempUri = Uri.parse(mImages.get(position));
// Make glide work with image
Glide.with(mContext)
.asBitmap()
.load(tempUri)
.into(holder.image);
// With regular ImageView
holder.imageViewTest.setImageURI(tempUri);
}
..............
更新:
您的代碼看起來不錯,並且您說 Uri 存在於列表中,所以我的猜測可能是在設置適配器之前設置布局管理器:
我的意思是在你的initRecyclerView()
中:
..........
//add this first
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//add this next
recyclerView.setAdapter(adapter);
......
我已經解決了這個問題:
日志包含以下消息:
java.lang.SecurityException(Permission Denial: opening provider com.android.providers.downloads.DownloadStorageProvider from ProcessRecord{985e802 27308:com.oshea.sharkbiomass/u0a82} (pid=27308, uid=10082) requires that you obtain access using ACTION_OPEN_DOCUMENT或相關 API)
問題出在我的 select 照片按鈕的點擊監聽器中。
// Select photo button listener
btnSelectPhotos.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, 1);
}
});
我將其更改為:
// Select photo button listener
btnSelectPhotos.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
startActivityForResult(intent, 1);
}
});
(將 ACTION_GET_CONTENT 更改為 ACTION_OPEN_DOCUMENT)並且它起作用了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.