简体   繁体   English

在Camera Intent之后更新RecyclerView.Adapter

[英]Update RecyclerView.Adapter after Camera Intent

So currently, I'm capturing an image and updating it in a RecyclerView using the Camera Intent: 所以目前,我正在使用Camera Intent捕获图像并在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);
            }
        }
    }

What happens prior to this is it'll trigger the intent from an setOnItemClickListener interface I have created within my RecyclerView.Adapter which is called in onCreate to populate the data from the web-server (or when triggered by setVisibleUserHint as they re-enter the fragment again). 在此之前发生的事情是它将触发我在我的RecyclerView.Adapter中创建的setOnItemClickListener interface的意图,该setOnItemClickListener interfaceonCreate调用以填充来自Web服务器的数据(或者当它们重新进入时由setVisibleUserHint触发)再次碎片)。

//init camera data //初始摄像机数据

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);
}

//settings adapters //设置适配器

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();

What happens post is within the onActivityResult : 帖子在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;
...
}

}

handleBigCameraPhoto: handleBigCameraPhoto:

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);
}

This works perfectly, it saves the file fine to the web-server but I want to update the adapter when that is successful, and of course I'm unable to restore the adapter object using outState or inState bundle. 这很好用,它可以很好地保存文件到Web服务器,但我想在成功时更新适配器,当然我无法使用outStateinState包恢复适配器对象。

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());
                }
           }
});

By this point I'm not sure why the cameraAdapter isn't updating as it's not returning null and is calling updatePosition(). 到目前为止,我不确定为什么cameraAdapter没有更新,因为它没有返回null并且正在调用updatePosition()。

public void updatePosition(JSONArray array, int position) {
        Log.e(TAG, "updatePositionCalled");
        this.imageList = array;
        notifyItemChanged(position);
}

If anyone can help me solve this mystery, that would be great! 如果有人能帮助我解开这个谜团,那就太好了! Also, if you need any more code or verification at all, let me know. 此外,如果您需要更多代码或验证,请告知我们。

Note : I currently have the JSONArray of objects, position in the adapter and web-server object stored in the saveInstanceState bundle and is restored correctly (because when I come out of the ViewPager fragment and come back in, thus calling setUserVisibleHint it restores the adapter from the web-server correctly). 注意 :我目前有对象的JSONArray ,位于适配器中的位置和存储在saveInstanceState包中的web-server对象并且正确恢复(因为当我从ViewPager片段中退出并返回时,因此调用setUserVisibleHint它会恢复适配器从Web服务器正确)。

Update : I've created a getImageList() method inside the adapter and calling that after the supposed 'update', it's updating the list values but not the list?! 更新 :我在适配器内部创建了一个getImageList()方法,并在假定的'更新'之后调用它,它更新了列表值而不是列表?! So i really do think the problem is with notifyItemChanged(position) 所以我真的认为问题出在notifyItemChanged(position)

 public JSONArray getImageList() {
        return imageList;
 }

// new call //新来电

if (e == null) {
    cameraAdapter.updatePosition(cameraArray, position);
    Log.e(TAG, cameraAdapter.getImageList().toString());
} else {
    Log.e(TAG, "failed " + e.getLocalizedMessage());
}

It literally prints out the corresponding values in the list, that has been passed to the adapter, but doesn't seem to update the UI. 它实际上打印出列表中已传递给适配器的相应值,但似乎不更新UI。

Update II : 更新II

I've had two (now deleted) answers advising me to notifyDataSetChanged() , Which makes no difference at all and is counter-productive as it'll rebind the whole adapter within the fragment, thus making it slow. 我有两个(现在删除的)答案通知我notifyDataSetChanged() ,这完全没有任何区别,并且适得其反,因为它将重新绑定片段中的整个适配器,从而使它变慢。 I'm already rebinding the dedicated position (supposedly) with notifyItemChanged() . 我已经使用notifyItemChanged()重新定位了专用位置(据说notifyItemChanged()

Note II : I'm offering a bounty, not for lazy and unresearched answers but for a solution with the very least an explanation, I'd like to know why it's going wrong, so I don't run into the same problem again (not a quick fix ). 注意二 :我提供赏金, 不是懒惰和未经研究的答案,但对于解决方案至少有一个解释,我想知道为什么它会出错,所以我不再遇到同样的问题(不是快速修复 )。 I'm already well aware of the different functionalities and components of a RecyclerView , RecyclerView.Adapter and RecyclerView.ViewHolder , I'm just having trouble in this particular scenario where the Activity is returning a result, but not updating the UI as it should. 我已经很清楚RecyclerViewRecyclerView.AdapterRecyclerView.ViewHolder的不同功能和组件,我在这个特定场景中遇到麻烦,其中Activity返回结果,但没有更新UI,因为它应该。

Hey i think the issue is with the line this.imageList = array of below method, 嘿,我认为问题在于this.imageList = array下面方法的this.imageList = array

public void updatePosition(JSONArray array, int position) {
        Log.e(TAG, "updatePositionCalled");
        this.imageList = array;
        notifyItemChanged(position);
}

Reason : 原因:

The this.imageList = array line is creating a new reference . this.imageList = array行正在创建一个新引用 It is not updating the old reference which was passed in the Recyclerview. 它不会更新在Recyclerview中传递的旧引用。 Hence, notifyItemChanged(position); 因此, notifyItemChanged(position); is refreshing the view but with the old reference of the array which has not been updated. 刷新视图,但使用尚未更新的数组的旧引用。

Solution: 解:

You need to update the method as following: 您需要更新方法如下:

public void updatePosition(String url, int position) {
        Log.e(TAG, "updatePositionCalled");
        this.imageList.put(position, url);
        notifyItemChanged(position);
}

And

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());
                }
           }
});

Update: 更新:

Also, replace notifyItemChanged(position) with notifyItemInserted(position) as new item is being inserted here in the Array. 此外,替换notifyItemChanged(position)notifyItemInserted(position)作为新的项目被这里插入在阵列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM