Reputation: 987
In my app when the user clicked on "Add Images" button it allows the user to select images from gallery and load it into the Recycler View. But when user come back to a previous activity by pressing back button and again he pressed "Add Images" button the previously selected images are lost from Recyclerview. I have tried onSavedInstanceState() but it not works in my case. I checked various StackOverflow solutions but nothing is working for me.
Here is my main activity called RecorderActivity
public class RecorderActivity extends AppCompatActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.add_images) {
Intent intent = new Intent(context,GridViewActivity.class);
intent.putExtra("call","1");
startActivity(intent);
}
else if(item.getItemId()==R.id.add_pdf_ppt) {
Toast.makeText(context, "Under Development", Toast.LENGTH_SHORT).show();
}
else if(item.getItemId()==R.id.rearrange_items) {
Intent i=new Intent(RecorderActivity.this,GridViewActivity.class);
i.putExtra("call","2");
startActivity(i);
}
return super.onOptionsItemSelected(item);
}
}
Here when "Add Images" options button from the toolbar is clicked it opens GridViewActivity where the user can add images from the gallery but when user come back to previous activity i.e. RecorderActivity and clicked again "Add Images" button, the previously selected images are lost from recyclerView.
Here is my GridViewActivity code
This is updated code where I saved ArrayList to shared preferences by using Gson and in onCreate() method I have retrieved ArrayList from sharedPreferences and set it to the recycler view but recyclerview shows the cards only not images inside the card. This is the problem! In sharedPreferences I'm uses one count variable to indicates total images in sharedPreferences.
public class GridViewActivity extends AppCompatActivity {
Context context=GridViewActivity.this;
RecyclerView recyclerView;
int PICK_IMAGE_MULTIPLE=1;
static ArrayList<Images> arrayList;
static ImagesAdapter imagesAdapter;
AutoFitGridLayoutManager autoFitGridLayoutManager;
SharedPref sharedPref;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view);
recyclerView=findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
autoFitGridLayoutManager=new AutoFitGridLayoutManager(context,250);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(autoFitGridLayoutManager);
arrayList=new ArrayList<>();
sharedPref=new SharedPref(context);
if (sharedPref.getCount()==0) {
Toast.makeText(context, "No images...", Toast.LENGTH_SHORT).show();
}
else {
Gson gson=new Gson();
String response=sharedPref.getImages();
arrayList=gson.fromJson(response,new TypeToken<ArrayList<Images>>(){}.getType());
Log.d("ROHIT", String.valueOf(arrayList.size()));
imagesAdapter=new ImagesAdapter(context,arrayList);
setRecyclerView();
}
}
public void setRecyclerView() {
ItemTouchHelper.Callback callback=new ItemMoveCallback(imagesAdapter);
ItemTouchHelper touchHelper=new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(recyclerView);
recyclerView.setAdapter(imagesAdapter);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.add_imges_cam) {
//open camera
}
else if(item.getItemId()==R.id.add_imges_gallery) {
//open gallery to select images
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), PICK_IMAGE_MULTIPLE);
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
int count=0;
if(requestCode==PICK_IMAGE_MULTIPLE && resultCode==RESULT_OK) {
String[] filePath = {MediaStore.Images.Media.DATA};
if (data.getData() != null) {
//if single image is selected
Uri imageUri = data.getData();
Cursor cursor = getContentResolver().query(imageUri, filePath, null, null, null);
cursor.moveToFirst();
arrayList.add(new Images(imageUri.toString()));
cursor.close();
} else {
if (data.getClipData() != null) {
ClipData mClipData = data.getClipData();
for (int i = 0; i < mClipData.getItemCount(); i++) {
ClipData.Item item = mClipData.getItemAt(i);
Uri uri = item.getUri();
// Get the cursor
Cursor cursor = getContentResolver().query(uri, filePath, null, null, null);
// Move to first row
cursor.moveToFirst();
arrayList.add(new Images(uri.toString()));
count++;
cursor.close();
}
}
}
imagesAdapter=new ImagesAdapter(context,arrayList);
sharedPref.save(arrayList);
Log.d("ROHIT","data saved arraylist"+arrayList.size());
sharedPref.updateCount(count);
Log.d("ROHIT","data saved");
setRecyclerView();
}
}
}
This is SharedPref.java
public class SharedPref {
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
Context context;
public SharedPref(Context context) {
this.context=context;
sharedPreferences=context.getSharedPreferences("Grid_images",Context.MODE_PRIVATE);
editor=sharedPreferences.edit();
}
public void save(ArrayList<Images> arrayList) {
Gson gson=new Gson();
Object src;
String json=gson.toJson(arrayList);
editor.putString("grid_images",json);
editor.apply();
editor.commit();
}
public void updateCount(int i) {
editor.putInt("images_count",i);
editor.apply();
editor.commit();
}
public int getCount() {
return sharedPreferences.getInt("images_count",0);
}
public String getImages() {
return sharedPreferences.getString("grid_images",null);
}
This is Images.java class
public class Images implements Parcelable {
private String image;
public Images(String image) {
this.image=image;
}
protected Images(Parcel in) {
image = in.readString();
}
public static final Creator<Images> CREATOR = new Creator<Images>() {
@Override
public Images createFromParcel(Parcel in) {
return new Images(in);
}
@Override
public Images[] newArray(int size) {
return new Images[size];
}
};
public String getImage() {
return image;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(String.valueOf(image));
}
}
This is ImageAdapter class code
public class ImagesAdapter extends RecyclerView.Adapter<ImagesAdapter.MyViewHolder> implements ItemMoveCallback.ItemTouchHelperContract {
ArrayList<Images> images;
Context context;
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
View rowView;
ImageButton bt_remove;
public MyViewHolder(View itemView) {
super(itemView);
rowView=itemView;
imageView=itemView.findViewById(R.id.imageview);
bt_remove=itemView.findViewById(R.id.bt_delete);
}
}
public ImagesAdapter(Context context,ArrayList<Images> images) {
this.context=context;
this.images=images;
}
public ImagesAdapter(Context context) {
this.context=context;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.images_grid,parent,false);
MyViewHolder myViewHolder=new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, final int position) {
Images current_image=images.get(position);
holder.imageView.setImageURI(Uri.parse(current_image.getImage()));
holder.bt_remove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
images.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,images.size());
}
});
}
@Override
public int getItemCount() {
return images.size();
}
@Override
public void onRowMoved(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(images, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(images, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onRowSelected(MyViewHolder myViewHolder) {
myViewHolder.rowView.setBackgroundColor(context.getResources().getColor(R.color.recycler_drag));
}
@Override
public void onRowClear(MyViewHolder myViewHolder) {
myViewHolder.rowView.setBackgroundColor(Color.WHITE);
}
}
Here is the output:
After selecting 4 images from gallery it is displayed in recyclerview in GridViewActivity
But after pressing back button and go again to GridViewActivity the recyclerview display like this
Please Do not mark it as a Duplicate Question. I search about this but no solution is worked for me. Please tell me what should I have to do in order to fix this problem!
Upvotes: 0
Views: 3109
Reputation: 2644
Replace your Activity with this and try:
public class GridViewActivity extends AppCompatActivity {
Context context=GridViewActivity.this;
RecyclerView recyclerView;
int PICK_IMAGE_MULTIPLE=1;
static ArrayList<Images> arrayList;
static ImagesAdapter imagesAdapter;
AutoFitGridLayoutManager autoFitGridLayoutManager;
SharedPref sharedPref;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view);
recyclerView=findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
autoFitGridLayoutManager=new AutoFitGridLayoutManager(context,250);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setLayoutManager(autoFitGridLayoutManager);
arrayList=new ArrayList<>(); // move this line above adapter initialization
imagesAdapter=new ImagesAdapter(context,arrayList);
setRecyclerView(); // forgot to invoke this method here.
sharedPref=new SharedPref(context);
if (sharedPref.getCount()==0) {
Toast.makeText(context, "No images...", Toast.LENGTH_SHORT).show();
}
else {
Gson gson=new Gson();
String response=sharedPref.getImages();
arrayList=gson.fromJson(response,new TypeToken<ArrayList<Images>>(){}.getType());
Log.d("ROHIT", String.valueOf(arrayList.size()));
imagesAdapter.notifyDataSetChanged(); // change is here
}
}
public void setRecyclerView() {
ItemTouchHelper.Callback callback=new ItemMoveCallback(imagesAdapter);
ItemTouchHelper touchHelper=new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(recyclerView);
recyclerView.setAdapter(imagesAdapter);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.add_imges_cam) {
//open camera
}
else if(item.getItemId()==R.id.add_imges_gallery) {
//open gallery to select images
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), PICK_IMAGE_MULTIPLE);
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
int count=0;
if(requestCode==PICK_IMAGE_MULTIPLE && resultCode==RESULT_OK) {
String[] filePath = {MediaStore.Images.Media.DATA};
if (data.getData() != null) {
//if single image is selected
Uri imageUri = data.getData();
Cursor cursor = getContentResolver().query(imageUri, filePath, null, null, null);
cursor.moveToFirst();
arrayList.add(new Images(imageUri.toString()));
cursor.close();
} else {
if (data.getClipData() != null) {
ClipData mClipData = data.getClipData();
for (int i = 0; i < mClipData.getItemCount(); i++) {
ClipData.Item item = mClipData.getItemAt(i);
Uri uri = item.getUri();
// Get the cursor
Cursor cursor = getContentResolver().query(uri, filePath, null, null, null);
// Move to first row
cursor.moveToFirst();
arrayList.add(new Images(uri.toString()));
count++;
cursor.close();
}
}
}
sharedPref.save(arrayList);
Log.d("ROHIT","data saved arraylist"+arrayList.size());
sharedPref.updateCount(count);
Log.d("ROHIT","data saved");
imagesAdapter.notifyDataSetChanged();
}
}
}
Upvotes: 0
Reputation: 2564
This is happening because you are creating a new ArrayList everytime you come back from Gallery.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
arrayList=new ArrayList<>();
...
// and then you are re-initializing your recycler view
imagesAdapter=new ImagesAdapter(context,arrayList);
setRecyclerView();
So when the user does not pick any image from the gallery then inside onActivityResult()
you do not get any image uri, but before that you create a new ArrayList and re-initialize your recyclerview.
That is why your recycler view shows no items.
Keep that ArrayList as a class member variable and keep adding/removing data based on onActivityResult().
Upvotes: 1