目前,我正在使用相机意图捕获图像并在RecyclerView
中更新它:
private void cameraIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Log.e(TAG, ex.getLocalizedMessage());
}
if (photoFile != null) {
Uri uri = FileProvider.getUriForFile(getActivity().getApplicationContext(),
"packagename.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
在此之前发生的事情是它会触发我在setOnItemClickListener interface
中创建的RecyclerView.Adapter
的意图,该onCreate
在setVisibleUserHint
中调用以填充来自网络服务器的数据(或当if (isCamera) {
cameraArray = object.getJSONArray(PROFILE_DETAILS_CAMERA_ARRAY_KEY);
sortAdapter(true, object, cameraArray);
} else {
galleryArray = object.getJSONArray(PROFILE_DETAILS_GALLERY_ARRAY_KEY);
sortAdapter(false, object, galleryArray);
}
再次重新进入片段时触发)。
//初始化相机数据
cameraAdapter = new RecyclerViewAdapterGallery(getActivity(), array, true);
cameraAdapter.setOnItemClickListener(new RecyclerViewAdapterGallery.onItemClickListener() {
@Override
public void setOnItemClickListener(View view, final int position, String image, final boolean isCamera, boolean isLongClick) {
clickResponse(view, position, image, isCamera, isLongClick, cameraAdapter, array, object);
}
});
recyclerView.setAdapter(cameraAdapter);
cameraAdapter.notifyDataSetChanged();
//设置适配器
onActivityResult
帖子在@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_TAKE_PHOTO:
if (resultCode != Activity.RESULT_CANCELED) {
if (resultCode == Activity.RESULT_OK) {
try {
handleBigCameraPhoto(finalPosition);
} catch (IOException e) {
Log.e(TAG, e.getLocalizedMessage());
}
}
}
break;
...
}
}
:
private void handleBigCameraPhoto(int position) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
getActivity().sendBroadcast(mediaScanIntent);
saveFile(f, false, position);
}
handleBigCameraPhoto:
outState
这很好用,它可以很好地保存文件到Web服务器但是我想在成功时更新适配器,当然我无法使用inState
或{{来恢复适配器对象1}}捆绑。
cameraArray.put(position, parseFile.getUrl());
userObject.put(PROFILE_DETAILS_CAMERA_ARRAY_KEY, cameraArray);
userObject.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
if (e == null) {
if (cameraAdapter != null) {
cameraAdapter.updatePosition(cameraArray, position);
}
} else {
Log.e(TAG, "failed " + e.getLocalizedMessage());
}
}
});
到目前为止,我不确定为什么cameraAdapter
没有更新,因为它没有返回null并且正在调用updatePosition()。
public void updatePosition(JSONArray array, int position) {
Log.e(TAG, "updatePositionCalled");
this.imageList = array;
notifyItemChanged(position);
}
如果有人能帮助我解开这个谜团,那就太好了!此外,如果您需要更多代码或验证,请与我们联系。
注意:我目前拥有JSONArray
个对象,位于适配器中的位置和存储在saveInstanceState
包中的Web服务器对象,并且已正确恢复(因为当我从ViewPager
片段中出来并返回,因此调用setUserVisibleHint
它可以正确地从Web服务器恢复适配器。
更新:我在适配器中创建了一个getImageList()
方法,并在假定的'更新'之后调用它,它更新列表值但不更新列表?!所以我真的认为问题出在notifyItemChanged(position)
public JSONArray getImageList() {
return imageList;
}
//新来电
if (e == null) {
cameraAdapter.updatePosition(cameraArray, position);
Log.e(TAG, cameraAdapter.getImageList().toString());
} else {
Log.e(TAG, "failed " + e.getLocalizedMessage());
}
它确实打印出列表中已传递给适配器的相应值,但似乎不更新UI。
更新II :
我有两个(现已删除的)答案通知我notifyDataSetChanged()
,这完全没有任何区别,并且会适得其反,因为它会在片段中重新绑定整个适配器,从而使其变慢。我已经用notifyItemChanged()
重新定位专用位置(据称)。
注意事项II :我正在提供赏金,不是为了懒惰和未经研究的答案,但对于解决方案至少有一个解释,我想知道为什么会出错,所以我不再遇到同样的问题(不是快速修复)。我已经非常了解RecyclerView
,RecyclerView.Adapter
和RecyclerView.ViewHolder
的不同功能和组件,我只是遇到了Activity
所在的特殊情况返回结果,但不按预期更新UI。
答案 0 :(得分:4)
嘿,我认为问题是使用以下方法的行this.imageList = array
,
public void updatePosition(JSONArray array, int position) {
Log.e(TAG, "updatePositionCalled");
this.imageList = array;
notifyItemChanged(position);
}
原因:
this.imageList = array
行创建新参考。它不会更新在Recyclerview中传递的旧引用。因此,notifyItemChanged(position);
正在刷新视图,但是使用了尚未更新的数组的旧引用。
<强>解决方案:强>
您需要按以下方式更新方法:
public void updatePosition(String url, int position) {
Log.e(TAG, "updatePositionCalled");
this.imageList.put(position, url);
notifyItemChanged(position);
}
和
userObject.put(PROFILE_DETAILS_CAMERA_ARRAY_KEY, cameraArray);
userObject.saveInBackground(new SaveCallback() {
@Override
public void done(ParseException e) {
if (e == null) {
if (cameraAdapter != null) {
cameraAdapter.updatePosition(parseFile.getUrl(), position);
}
} else {
Log.e(TAG, "failed " + e.getLocalizedMessage());
}
}
});
<强>更新强>
此外,将notifyItemChanged(position)
替换为notifyItemInserted(position)
,因为数组中插入了新项目。