I want to show my specific folder vedios in GridView layout.
But I am getting black items in GridView layout
Screenshot showing GridView layout
This is my class for getting data from internal memory.
public class Spacecraft {
String name;
boolean Checked=false;
private Uri uri;;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Uri getUri() {
return uri;
}
public void setUri(Uri uri) {
this.uri = uri;
}
public boolean isChecked(){
return Checked;
}
public void toggleChecked(){
Checked = !Checked;
}
}
This is my Adapter Class.
public class VedioAdapter extends BaseAdapter {
Context c;
ArrayList<Spacecraft> spacecrafts;
public VedioAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
this.c = c;
this.spacecrafts = spacecrafts;
}
#Override
public int getCount() {
return spacecrafts.size();
}
#Override
public Object getItem(int i) {
return spacecrafts.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view==null)
{
//INFLATE CUSTOM LAYOUT
view= LayoutInflater.from(c).inflate(R.layout.whatsapp_vedio,viewGroup,false);
}
final Spacecraft s= (Spacecraft) this.getItem(i);
if(s.isChecked()){
view.setBackgroundColor(Color.parseColor("#06ad94"));
}
else view.setBackgroundColor(Color.TRANSPARENT);
// TextView nameTxt= (TextView) view.findViewById(R.id.textView);
VideoView vedio=(VideoView)view.findViewById(R.id.vedio);
vedio.setVideoURI(s.getUri());
//BIND DATA
// nameTxt.setText(s.getName());
return view;
}
}
This is my VedioLayout activity class.
public class VedioGrid extends AppCompatActivity {
Spacecraft s;
ArrayList<Spacecraft> list = new ArrayList<>();
ArrayList<Spacecraft> list_items = new ArrayList<>();
int count = 0;
public ArrayList<Spacecraft> getPlayList(String rootPath) {
ArrayList<Spacecraft> fileList = new ArrayList<>();
try {
File rootFolder = new File(rootPath);
File[] files = rootFolder.listFiles(); //here you will get NPE if directory doesn't contains any file,handle it like this.
for (File file : files) {
if (file.isDirectory()) {
if (getPlayList(file.getAbsolutePath()) != null) {
fileList.addAll(getPlayList(file.getAbsolutePath()));
} else {
break;
}
} else if (file.getName().endsWith(".mp4")) {
s = new Spacecraft();
s.setName(file.getName());
s.setUri(Uri.fromFile(file));
fileList.add(s);
}
}
return fileList;
} catch (Exception e) {
return null;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.images);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
String path = Environment.getExternalStorageDirectory().getAbsolutePath().toString() + "/and/";
list = getPlayList(path);
GridView gv = (GridView) findViewById(R.id.simpleGridView);
final VedioAdapter adapter = new VedioAdapter(this, list);
gv.setAdapter(adapter);
gv.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
gv.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
Spacecraft s = list.get(position);
s.toggleChecked();
if (s.isChecked()) {
adapter.notifyDataSetChanged();
count = count + 1;
mode.setTitle(count + " Deleted Items");
list_items.add(s);
} else {
if (count != 0) {
adapter.notifyDataSetChanged();
count = count - 1;
mode.setTitle(count + " Deleted Items");
list_items.remove(s);
}
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
final ActionMode mod = mode;
switch (item.getItemId()) {
case R.id.action_open:
new AlertDialog.Builder(VedioGrid.this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Are you sure?")
.setMessage("Do you want to delete this image?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int p) {
int i;
for (i = 0; i < list_items.size(); ++i) {
Spacecraft s1 = list_items.get(i);
File f = new File(s1.getUri().getPath());
Boolean deleted = f.delete();
VedioGrid.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(s1.getUri().getPath()))));
if (deleted == true) {
list.remove(s1);
adapter.notifyDataSetChanged();
}
}
list_items.clear();
Toast.makeText(VedioGrid.this, count + "Deleted", Toast.LENGTH_SHORT).show();
count = 0;
mod.finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
})
.show();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
});
gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Spacecraft s = list.get(position);
Toast.makeText(getApplicationContext(), s.getName(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}
I am not getting the videos in layout and even if try to select multiple items the items nothing happens in the activity.
Am I doing wrong?
I am using
gv.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
gv.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener()
but nothing happens.
Earlier I tried this to fetch the images from internal memory I get the desired result and able to select the items but in this, I am using the same logic to fetch videos and show in GridView layout but not getting the result.
I get black items as shown in the above screenshot and not able to select.
Please help me.
Related
When I opened the searched item, it is opening the first item of ListView not the searched one. Even if search and find the items successfuly.
I configure the adapter with "implements Filterable" and enable Listview with ".setTextFilterEnabled(true)", but doesn´t work.
I saw that I must implement "public Filter getFilter()" but I have no idea how can I do that.
When I type some words in EditText, like "cel" or "12" the filter goes in action, but the result is always the same: The first two items in Listview, no matter what is into the Listview (the content of listview is random).
Below a snippet of my Activity:
public class MusicActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
private boolean checkPermission = false;
ProgressDialog progressDialog;
ListView listView;
List<String> songsNameList;
List<String> songsUrlList;
List<String> songsArtistList;
List<String> songsDurationList;
ListAdapter adapter;
JcPlayerView jcPlayerView;
List<JcAudio> jcAudios;
List<String> thumbnail;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music);
progressDialog = new ProgressDialog(this);
progressDialog.show();
progressDialog.setMessage("Please Wait...");
listView = findViewById(R.id.songsList);
songsNameList = new ArrayList<>();
songsUrlList = new ArrayList<>();
songsArtistList = new ArrayList<>();
songsDurationList = new ArrayList<>();
jcAudios = new ArrayList<>();
thumbnail = new ArrayList<>();
jcPlayerView = findViewById(R.id.jcplayer);
retrieveSongs();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
jcPlayerView.playAudio(jcAudios.get(i));
jcPlayerView.setVisibility(View.VISIBLE);
jcPlayerView.createNotification();
adapter.notifyDataSetChanged();
}
});
}
// RETRIEVING THE SONGS FROM THE SERVER
public void retrieveSongs() {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Songs");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren()) {
Song song = ds.getValue(Song.class);
songsNameList.add(song.getSongName());
songsUrlList.add(song.getSongUrl());
songsArtistList.add(song.getSongArtist());
songsDurationList.add(song.getSongDuration());
thumbnail.add(song.getImageUrl());
jcAudios.add(JcAudio.createFromURL(song.getSongName(), song.getSongUrl()));
}
adapter = new ListAdapter(getApplicationContext(), songsNameList, thumbnail, songsArtistList, songsDurationList);
jcPlayerView.initPlaylist(jcAudios, null);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
progressDialog.dismiss();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(MusicActivity.this, "FAILED!", Toast.LENGTH_SHORT).show();
}
});
}
/*#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.app_menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.searchmenu:
startActivity(new Intent(MusicActivity.this,Search.class));
break;
case R.id.requestmenu:
startActivity(new Intent(MusicActivity.this,UploadSongActivity.class));
break;
case R.id.sharemenu:
break;
}
return true;
}*/
// Filter Class
// METHOD TO HANDEL RUNTIME PERMISSIONS
private boolean validatePermissions(){
Dexter.withContext(getApplicationContext())
.withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
.withListener(new PermissionListener() {
#Override
public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
checkPermission = true;
}
#Override
public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {
checkPermission = false;
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
permissionToken.continuePermissionRequest();
}
}).check();
return checkPermission;
}
#Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(this, "Query Inserted", Toast.LENGTH_SHORT).show();
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
if(TextUtils.isEmpty(newText)){
adapter.filter("");
listView.clearTextFilter();
}else{
String texto = newText;
adapter.filter(newText);
}
return true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.searchmenu, menu);
MenuItem searchItem = menu.findItem(R.id.search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setQueryHint("Search Catholic songs");
searchView.setOnQueryTextListener(this);
searchView.setIconified(false);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.search) {
return true;
}
else if(id == R.id.Rate){
/*if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
} else {
//log.d("TAG", "The intersitial wasn't loaded yet.");
}*/
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getString(R.string.packegname)));
startActivity(intent);
}
else if (id ==R.id.sharemenu){
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT,
"Hey ! check out this music service that gives you access to Hundreds of catholic songs. through Catholic app at: https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID);
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
else if(id == R.id.uploadItem){
if (validatePermissions()){
Intent intent = new Intent(this,UploadSongActivity.class);
startActivity(intent);
}
}
return super.onOptionsItemSelected(item);
}
and below my CustomAdapter:
public class ListAdapter extends BaseAdapter {
List<String> songNames;
List<String> thumbnails;
List<String> songArtist;
List<String> songDuration;
Context context;
private List<String> copyList;
private int searchedItem = -1;
private ArrayList<Song> arraylist;
public ListAdapter(Context context, List<String> songNames, List<String> thumbnails, List<String> songArtist, List<String> songDuration) {
this.context = context;
this.songNames = songNames;
this.thumbnails = thumbnails;
this.songArtist = songArtist;
this.songDuration = songDuration;
copyList = new ArrayList<String>();
copyList.addAll(songNames);
}
#Override
public int getCount() {
return songNames.size();
}
#Override
public Object getItem(int i) {
return songNames.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#SuppressLint({"InflateParams", "ViewHolder"})
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
final ViewHolder viewHolder;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.songs_list_layout, null);
viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) view.getTag();
}
Transformation transformation = new RoundedTransformationBuilder()
.cornerRadiusDp(15)
.build();
Picasso.get().load(thumbnails.get(i)).transform(transformation).into(viewHolder.thumbnail);
viewHolder.songName.setText(songNames.get(i));
viewHolder.artistName.setText(songArtist.get(i));
viewHolder.songDuration.setText(songDuration.get(i));
return view;
}
public void filter(String queryText)
{
songNames.clear();
if(queryText.isEmpty())
{
songNames.addAll(copyList);
}
else
{
for(String name: copyList)
{
if(name.toLowerCase().contains(queryText.toLowerCase()))
{
songNames.add(name);
}
}
}
notifyDataSetChanged();
}
private static class ViewHolder{
TextView songName;
TextView artistName;
TextView songDuration;
ImageView thumbnail;
CardView cardView;
ImageView currentlyPlaying;
ViewHolder(View view){
songName = view.findViewById(R.id.songName);
thumbnail = view.findViewById(R.id.songThumbnail);
artistName = view.findViewById(R.id.artistName);
songDuration = view.findViewById(R.id.songDuration);
cardView = view.findViewById(R.id.cardView);
currentlyPlaying = view.findViewById(R.id.currentlyPlaying);
}
}
What is missing?
I improved your adapter, didn't test it but it should work... I think it's easier to forward the Song list than the lists for each field separately... You have the original list for filtering and filteredList for adapter views...
EDITED: You have to implement Filterable, sorry i didnt see this...
public class ListAdapter extends BaseAdapter implements Filterable {
private final Context context;
private final List<Song> songlist;
private final List<Song> filteredList;
public ListAdapter(Context context, List<Song> songlist) {
this.context = context;
this.songlist = songlist;
filteredList = new ArrayList<>();
filteredList.addAll(songlist);
}
#Override
public int getCount() {
return filteredList.size();
}
#Override
public Object getItem(int i) {
return filteredList.get(i); // return Song item
}
#Override
public long getItemId(int i) {
return i; //TODO change this to return song id
}
#SuppressLint({"InflateParams", "ViewHolder"})
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
final ViewHolder viewHolder;
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.songs_list_layout, null);
viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) view.getTag();
}
Transformation transformation = new RoundedTransformationBuilder()
.cornerRadiusDp(15)
.build();
Song song = filteredList.get(i);
Picasso.get().load(song.getImageUrl()).transform(transformation).into(viewHolder.thumbnail);
viewHolder.songName.setText(song.getSongName());
viewHolder.artistName.setText(song.getSongArtist());
viewHolder.songDuration.setText(song.getSongDuration());
return view;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering (CharSequence constraint) {
FilterResults results = new FilterResults();
if (songlist != null && constraint != null) {
filteredList.clear();
List<Song> newValues = new ArrayList<>();
for (Song song: songlist) {
if(constraint.length() == 0) {
newValues.add(song); //TODO change this if you want empty list
}else{
if(song.getSongName.toLowerCase().contains(constraint.toString().toLowerCase())) {
newValues.add(song);
}
}
}
filteredList.addAll(newValues);
//filteredList = newValues;
results.count = newValues.size();
}
return results;
}
#Override
protected void publishResults (CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
}
private static class ViewHolder{
TextView songName;
TextView artistName;
TextView songDuration;
ImageView thumbnail;
CardView cardView;
ImageView currentlyPlaying;
ViewHolder(View view){
songName = view.findViewById(R.id.songName);
thumbnail = view.findViewById(R.id.songThumbnail);
artistName = view.findViewById(R.id.artistName);
songDuration = view.findViewById(R.id.songDuration);
cardView = view.findViewById(R.id.cardView);
currentlyPlaying = view.findViewById(R.id.currentlyPlaying);
}
}
}
and
public void retrieveSongs() {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Songs");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
List<Song> songsList = new ArrayList<>();
for (DataSnapshot ds : snapshot.getChildren()) {
Song song = ds.getValue(Song.class);
songsList.add(song);
jcAudios.add(JcAudio.createFromURL(song.getSongName(), song.getSongUrl()));
}
adapter = new ListAdapter(getApplicationContext(), songsList);
jcPlayerView.initPlaylist(jcAudios, null);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
progressDialog.dismiss();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(MusicActivity.this, "FAILED!", Toast.LENGTH_SHORT).show();
}
});
}
Also its better to create one instance of adapter and swapData in retrieveSongs...
EDITED: Try something like this
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Song song = (Song)adapter.getItem(i)
jcPlayerView.playAudio(JcAudio.createFromURL(song.getSongName(), song.getSongUrl()));
jcPlayerView.setVisibility(View.VISIBLE);
jcPlayerView.createNotification();
adapter.notifyDataSetChanged();
}
});
in my adapter items can be selectable for show popup such as copy, cut or etc, now how can i get selected part of text on recyclerView item and position? i read more document about found this solution but i dont know how can i do that
this is my adapter which i would like to get selected part of text and postion:
public class ShowBookContentsAdapter extends RecyclerView.Adapter<ShowBookContentsAdapter.ShowBookContentsViewHolder> {
private List<Contents> list;
private Context context;
...
private fontFace setFontFace = fontFace.SHABNAM;
public ShowBookContentsAdapter(List<Contents> items, Context mContext, IonChangeBottomViewVisibility mOnChangeBottomViewVisibility, IonSelectText mIonSelectText) {
list = items;
context = mContext;
ionChangeBottomViewvisibility = mOnChangeBottomViewVisibility;
ionSelectText = mIonSelectText;
}
#Override
public ShowBookContentsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = -1;
switch (viewType) {
case 0:
layout = R.layout.item_book_content_paragraph;
break;
}
view = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
holder = new ShowBookContentsViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(ShowBookContentsViewHolder holder, final int position) {
switch (list.get(position).getContentType()) {
case 0:
makeSelectable(holder.book_content_paragraph);
implementingParagraphView(holder, position);
break;
}
}
private void implementingParagraphView(final ShowBookContentsViewHolder mHolder, final int position) {
holder = mHolder;
String content = list.get(position).getContent();
mHolder.book_content_paragraph.removeAllViews();
try {
Reader reader = new StringReader(content);
KetabkhanView ketabkhan = new KetabkhanView(context);
KetabkhanTagProcessor ketabkhanTagProcessor = new KetabkhanTagProcessor();
ketabkhanTagProcessor.parse(reader, ketabkhan);
mHolder.book_content_paragraph.addView(ketabkhan);
} catch (Exception e) {
e.printStackTrace();
Log.e("E ", e.getMessage());
throw new RuntimeException(e);
}
makeSelectable(mHolder.book_content_paragraph);
if (setFontFace == fontFace.SHABNAM)
Utils.overrideFonts(context, mHolder.book_content_paragraph, PersianFontType.SHABNAM);
else if (setFontFace == fontFace.SAHEL)
Utils.overrideFonts(context, mHolder.book_content_paragraph, PersianFontType.SAHEL);
//for show and hide bottom view
mHolder.book_content_paragraph.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ionChangeBottomViewvisibility != null) {
ionChangeBottomViewvisibility.onChange();
}
}
});
}
...
private void makeSelectable(ViewGroup viewGroup) {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
if (child instanceof ViewGroup) {
makeSelectable((ViewGroup) child);
} else if (child instanceof TextView) {
((TextView) child).setTextIsSelectable(true);
((TextView) child).setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize == 0 ? 14 : textSize);
}
}
}
#Override
public int getItemViewType(int position) {
return list.get(position).getContentType();
}
#Override
public int getItemCount() {
return list.size();
}
public int getItemPosition(int itemId) {
return itemPositions.get(itemId);
}
public void setData(List<Contents> mContents) {
list.clear();
list.addAll(mContents);
}
public class ShowBookContentsViewHolder extends RecyclerView.ViewHolder {
#Nullable
#BindView(R.id.book_content_paragraph)
LinearLayout book_content_paragraph;
...
public ShowBookContentsViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
i make selectable text on items by this method: makeSelectable()
I have implemented the same using custom ActionMode Callback. We can set the custom Action Mode callback to a particular textview of recycler view item by setting textView.customSelectionActionModeCallback in the onBindViewHolder of recyclerView Adapter. In the custom Callback we can use the current position and selected text.
onBindViewHolder will look like this.
public void onBindViewHolder(myViewHolder holder, int position) {
//code
holder.textview. setCustomSelectionActionModeCallback(new CustomSelectionCallback(holder.taskName, position, mContext));
}
In the custom Callback we can send anything along with the position of the item.
Custom Selection Callback can be implemented as follows.
public class CustomSelectionCallback implements ActionMode.Callback {
private TextView mTextView;
private int position;
private Context mContext;
public CustomSelectionCallback(TextView text, int pos, Context context) {
this.mTextView = text;
this.position = pos;
this.mContext = context;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int start = mTextView.getSelectionStart();
int end = mTextView.getSelectionEnd();
Spannable wordtoSpan = (Spannable) mTextView.getText();
wordtoSpan.setSpan(new BackgroundColorSpan(Color.TRANSPARENT), start, end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//copy the text when Copy Action Mode is clicked
if (item.getItemId() == android.R.id.copy) {
copyText(start, end);
mode.finish();
return true;
} else if (item.getItemId() == android.R.id.shareText) {
shareText(start, end);
mode.finish();
return true;
} else if (item.getItemId() == android.R.id.selectAll) {
selectAllText();
return true;
}
return true;
}
/**
* implement select all functionality id ActionMOde Menu
*/
private void selectAllText() {
Selection.setSelection((Spannable) mTextView.getText(), 0, mTextView.length());
}
private void shareText(int start, int end) {
CharSequence selectedTxt = mTextView.getText().subSequence(start, end);
String shareBody = selectedTxt.toString();
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
mContext.startActivity(Intent.createChooser(sharingIntent, "SHARE"));
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
/**
* copy the selected text with start and end param to clipboard
*
* #param start start point of selection of the text view
* #param end end point of selection of the text view
*/
private void copyText(int start, int end) {
ClipboardManager clipboardManager = (ClipboardManager) mContext.
getSystemService(Context.CLIPBOARD_SERVICE);
CharSequence selectedTxt = mTextView.getText().subSequence(start, end);
ClipData clipData = ClipData.newPlainText("selected text label", selectedTxt);
assert clipboardManager != null;
clipboardManager.setPrimaryClip(clipData);
Toast.makeText(mContext, selectedTxt.toString() + " position " + position, Toast.LENGTH_LONG).show();
}
}
In my app, I want to delete the images, which i have done, but every time I delete image, it doesn't refresh the recyclerView. But when I again open the folder then Recyclerview is refreshed..
I want to refresh Recyclerview when image is deleted
Here is my code for Deleting an image
#Override
protected void onExternalStoragePermissionGranted() {
super.onExternalStoragePermissionGranted();
storage = SimpleStorage.getExternalStorage();
checkForGalleryDirectories();
File galleryFiles = new File(path);
pathContainerView.removeAllViews();
pathContainerView.addView(createTitleView("Location: " + galleryFiles.getAbsolutePath()));
File[] files = galleryFiles.listFiles();
List<GalleryItem> galleryItems = new ArrayList<>();
String lastModifiedDate = "UNDEFINED";
SimpleDateFormat formatter = new SimpleDateFormat("E-MMM-yyyy");
if (files != null) {
this.adapter.clearGallery();
for (File file : files) {
if (file.isDirectory()) {
}
String formattedPicDate = formatter.format(lastMod);
if (lastModifiedDate != null && !lastModifiedDate.equals(formattedPicDate)) {
lastModifiedDate = formattedPicDate;
galleryItems.add(new Header(lastModifiedDate));
countgridsize++;
}
galleryItems.add(new Picture(file.getPath(), file.getName()));
}
}
}
this.adapter.setGalleryList(galleryItems);
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_delete:
final List<String> list = GalleryAdapter.list;
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
//Yes button clicked
Toast.makeText(GalleryBrowserActivity.this, "Delete Successfully..", Toast.LENGTH_SHORT).show();
for (String fileNameStr : list) {
String[] parts = fileNameStr.split("/");
String part1 = parts[5]; // 004
String part2 = parts[6]; // 034556
storage.deleteFile(".AliRehman/" + part1, part2);
}
break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(GalleryBrowserActivity.this);
builder.setMessage("Are you sure?")
.setPositiveButton("Yes", dialogClickListener)
.setNegativeButton("No", dialogClickListener).show();
return true;
My adapter Class
public class GalleryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context context;
private final LayoutInflater layoutInflater;
private List<GalleryItem> galleryList = new ArrayList<>();
private OnItemClickListener mItemClickListener;
public static List<String> list;
public GalleryAdapter(Context context, LayoutInflater layoutInflater) {
this.context = context;
this.layoutInflater = layoutInflater;
}
public void setItemClickListener(OnItemClickListener listener) {
mItemClickListener = listener;
}
public void setGalleryList(List<GalleryItem> galleryList) {
this.galleryList = galleryList;
notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
return this.galleryList.get(position).getItemType();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == GalleryItem.HEADER_TYPE) {
return new HeaderHolder(layoutInflater.inflate(R.layout.item_header, parent, false));
} else {
return new PictureHolder(layoutInflater.inflate(R.layout.item_picture, parent, false));
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
GalleryItem item = galleryList.get(position);
if(getItemViewType(position) == GalleryItem.HEADER_TYPE) {
bindHeaderHolder((HeaderHolder) holder, (Header) item);
}
else {
bindPictureHolder((PictureHolder) holder, (Picture) item);
}
}
private void bindPictureHolder(final PictureHolder holder, Picture picture) {
Glide.with(context).load(Uri.fromFile(new File(picture.getPath()))).into(holder.pictureThumbnail);
boolean itemselected=picture.getSelected();
if(itemselected)
{
Log.d("ViewVisiblePicture", String.valueOf(picture.getPath()));
holder.overlayView.setVisibility(View.VISIBLE);
}
else
holder.overlayView.setVisibility(View.GONE);
}
private void bindHeaderHolder(HeaderHolder holder, Header header) {
holder.headerTxt.setText(header.getName());
}
#Override
public int getItemCount() {
return this.galleryList.size();
}
public void clearGallery() {
this.galleryList.clear();
notifyDataSetChanged();
}
public class HeaderHolder extends RecyclerView.ViewHolder {
private TextView headerTxt;
public HeaderHolder(View itemView) {
super(itemView);
this.headerTxt = (TextView) itemView.findViewById(R.id.headerTxt);
}
}
public class PictureHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public ImageView pictureThumbnail;
public FrameLayout overlayView;
public PictureHolder pictureHolder;
private boolean[] thumbnailsselection;
public PictureHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
this.pictureThumbnail = (ImageView) itemView.findViewById(R.id.pictureThumbnail);
this.overlayView = (FrameLayout) itemView.findViewById(R.id.overlayView);
}
#Override
public boolean onLongClick(View view) {
list=new ArrayList<>();
if (mItemClickListener != null) {
mItemClickListener.onItemLongClick(getAdapterPosition());
this.overlayView.setVisibility(View.VISIBLE);
Picture model=(Picture) galleryList.get(getAdapterPosition());
//galleryList.get(getAdapterPosition());
model.setSelected(true);
list.add(model.getPath());
Log.d("Path1", model.getPath());
final int len = GalleryBrowserActivity.countgridsize;
int count = 0;
/* String selectImages = "";
for (int i = 0; i < len; i++) {
*//*if (pictureHolder..get(i).selection) {
count++;
selectImages = selectImages
+ pictureHolder.images.get(i).id + ",";
}*//*
this.overlayView.setVisibility(View.VISIBLE);
}
Log.d("Length", len+"");
if (count == 0) {
Toast.makeText(context,
"Please select at least one image",
Toast.LENGTH_LONG).show();
}*/
return true;
}
Log.d("hi","hello Image");
notifyDataSetChanged();
return false;
}
#Override
public void onClick(View v)
{
int position = getAdapterPosition();
Picture picture = (Picture) galleryList.get(position);
if(GalleryBrowserActivity.mActionMode!=null)
{
Log.d("Visiblilty","visible");
Picture model=(Picture) galleryList.get(getAdapterPosition());
if(model.getSelected()){
this.overlayView.setVisibility(View.GONE);
model.setSelected(false);
list.remove(model.getPath());
}else {
mItemClickListener.onItemClick(position, v, picture.getPath());
Toast.makeText(context, "visible" + picture.getPath(), Toast.LENGTH_LONG).show();
this.overlayView.setVisibility(View.VISIBLE);
model.setSelected(true);
list.add(model.getPath());
Log.d("Path2", model.getPath());
}
notifyDataSetChanged();
}
if (GalleryBrowserActivity.mActionMode==null) {
Log.d("Visible","invisible");
Toast.makeText(context,"invisible",Toast.LENGTH_LONG).show();
mItemClickListener.onItemClick(position, v, picture.getPath());
}
}
}
public interface OnItemClickListener
{
void onItemClick(int position, View v, String picturePath);
void onItemLongClick(int position);
}
}
I would suggest you to make below changes:
In GalleryAdapter :
From:
public static List<String> list;
To:
public static List< GalleryItem > list;
And add a function in your GalleryAdapter to remove items from your galleryList:
public void removeItem(GalleryItem item){
this.galleryList.remove(item);
notifyDataSetChanged();
}
And In PictureHolder:
#Override
public boolean onLongClick(View view) {
list=new ArrayList<>();
if (mItemClickListener != null) {
mItemClickListener.onItemLongClick(getAdapterPosition());
this.overlayView.setVisibility(View.VISIBLE);
GalleryItem model=(GalleryItem) galleryList.get(getAdapterPosition());
//galleryList.get(getAdapterPosition());
((Picture)model).setSelected(true);
list.add(model);
Log.d("Path1", ((Picture)model).getPath());
final int len = GalleryBrowserActivity.countgridsize;
int count = 0;
return true;
}
Log.d("hi","hello Image");
notifyDataSetChanged();
return false;
}
#Override
public void onClick(View v)
{
int position = getAdapterPosition();
GalleryItem picture = (GalleryItem) galleryList.get(position);
if(GalleryBrowserActivity.mActionMode!=null)
{
Log.d("Visiblilty","visible");
GalleryItem model=(GalleryItem) galleryList.get(getAdapterPosition());
if(model.getSelected()){
this.overlayView.setVisibility(View.GONE);
((Picture)model).setSelected(false);
list.remove(model);
}else {
mItemClickListener.onItemClick(position, v, picture.getPath());
Toast.makeText(context, "visible" + picture.getPath(), Toast.LENGTH_LONG).show();
this.overlayView.setVisibility(View.VISIBLE);
((Picture)model).setSelected(true);
list.add(model);
Log.d("Path2", model.getPath());
}
notifyDataSetChanged();
}
if (GalleryBrowserActivity.mActionMode==null) {
Log.d("Visible","invisible");
Toast.makeText(context,"invisible",Toast.LENGTH_LONG).show();
mItemClickListener.onItemClick(position, v, picture.getPath());
}
}
In the above code I am trying to update the list with selected GallryItem objects.
And While deleting item after the DialogInterface.BUTTON_POSITIVE is clicked, update the code like below:
case DialogInterface.BUTTON_POSITIVE:
//Yes button clicked
Toast.makeText(GalleryBrowserActivity.this, "Delete Successfully..", Toast.LENGTH_SHORT).show();
for (GalleryItem item : list) {
this.adapter.removeItem(item);
String fileNameStr = ((Picture)item).getPath();
String[] parts = fileNameStr.split("/");
String part1 = parts[5]; // 004
String part2 = parts[6]; // 034556
storage.deleteFile(".AliRehman/" + part1, part2);
}
break;
The above code will also update the galleryList inside adapter and notify the dataset change. Please let me know if you face any issue while implementing it.
you have to notify your adapter after you delete your image. like below.
arrayAdapter.notifyDataSetChanged();
in your example you have to write above line after you click Yes in your AlertDialog.
All you need to do is call notifyDataSetChanged() which will notify the RecyclerView to re-bin the views again, thereby deleting any item as necessary.
Just add a method in your adapter class,
mAdapter.notifyDataSetChanged();
If you know the position of the particular item which is getting deleted, then it is RECOMMENDED to use,
mAdapter.notifyItemChanged(position);
This will give you a nice animation effect while deleting the item.
I have a fragment (ItemFragment) with a bunch of EditText, a spinner and datepicker. The user input will be saved in SQL database. The user input then displayed in a list fragment (ListFragment) using RecyclerView. When a user click on the item in the list, it will go to ItemFragment and restore the user input. I added onSaveInstanceState in ItemFragment. I'm pretty new to Android so please bear with me. So how do I restore ItemFragment state during RecylerView's onTouchEvent?
ItemFragment.java (not sure if this is the correct way to do this?)
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putString("title", title);
outState.putString("quantity", quantity);
outState.putString("unit", unit);
outState.putString("date", date);
outState.putString("note", Note);
}
ListFragment.java
mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
View child = recyclerView.findChildViewUnder(motionEvent.getX(), motionEvent.getY());
if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
int position = recyclerView.getChildLayoutPosition(child);
Item selectedItem = mItems.get(position);
//How do I restore ItemFragment here???
return true;
}
return false;
}
Edited added Item.java and full code of ItemFragment.java
Item.java
public class Item {
private Long id;
private String title;
private String quantity;
private String unit;
private String date;
private String Note;
public String getNote() {
return Note;
}
public void setNote(String Note) {
this.Note = Note;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getQuantity() {
return quantity;
}
public void setQuantity(String quantity) {
this.quantity = quantity;
}
public static Item getItemfromCursor(Cursor cursor){
Item item = new Item();
item.setId(cursor.getLong(cursor.getColumnIndex(Constants.COLUMN_ID)));
item.setTitle(cursor.getString(cursor.getColumnIndex(Constants.COLUMN_TITLE)));
item.setQuantity(cursor.getString(cursor.getColumnIndex(Constants.COLUMN_QUANTITY)));
item.setUnit(cursor.getString(cursor.getColumnIndex(Constants.COLUMN_UNIT)));
item.setNote(cursor.getString(cursor.getColumnIndex(Constants.COLUMN_NOTE)));
item.setDate(cursor.getString(cursor.getColumnIndex(Constants.COLUMN_DATE)));
return item;
}
}
ItemFragment.java
public class ItemFragment extends DialogFragment {
private View mRootView;
private Item currentItem = null;
private Toolbar mToolbar;
private String date;
private String Note;
private String title;
private String quantity;
private TextView dateText;
private TextView unitError;
private EditText itemEditText;
private EditText quantityEditText;
private EditText noteEditText;
private Spinner remSpinner;
private Spinner spinner;
private String unit;
private String reminder;
private int spinnerCount=0;
private int spinnerInitializedCount=0;
private int remSpinnerCount=0;
private int remSpinnerInitializedCount=0;
public ItemFragment() {
}
//create an instance of the fragment
public static ItemFragment newInstance(long id) {
ItemFragment fragment = new ItemFragment();
if (id > 0) {
Bundle bundle = new Bundle();
bundle.putLong("id", id);
fragment.setArguments(bundle);
}
return fragment;
}
//get id of an item
public void getCurrentItem() {
Bundle args = getArguments();
if (args != null && args.containsKey("id")) {
long id = args.getLong("id", 0);
if (id > 0) {
currentItem = ItemManager.newInstance(getActivity()).getItem(id);
}
}
}
//notify Activity that the fragment wants to place an item in the menu
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
getCurrentItem();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.add_item, container, false);
itemEditText=(EditText)mRootView.findViewById((R.id.add_item));
quantityEditText=(EditText)mRootView.findViewById(R.id.amount);
unitError = (TextView)mRootView.findViewById(R.id.unit_error);
noteEditText = (EditText)mRootView.findViewById(R.id.add_notes);
dateText = (TextView)mRootView.findViewById(R.id.date_selected);
//unit spinner code here
//reminder spinner here
spinner.setOnItemSelectedListener(spinnerListener);
remSpinner.setOnItemSelectedListener(spinnerListener);
spinnerCount=1;
remSpinnerCount=1;
return mRootView;
}
//spinner listener
AdapterView.OnItemSelectedListener spinnerListener = new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getId()) {
case R.id.units:
//set spinner text appearance
((TextView)parent.getChildAt(0)).setTextSize(13);
((TextView)parent.getChildAt(0)).setTextColor(Color.DKGRAY);
if(spinnerInitializedCount<spinnerCount){
spinnerInitializedCount++;
} else {
//get selected unit
unit = parent.getItemAtPosition(position).toString();
}
break;
case R.id.reminder_list:
//set spinner text appearance
((TextView)parent.getChildAt(0)).setTextSize(13);
((TextView)parent.getChildAt(0)).setTextColor(Color.DKGRAY);
//get selected reminder
reminder = parent.getItemAtPosition(position).toString();
break;
}
}}
public void onNothingSelected(AdapterView<?> parent) {
}
};
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.menu_add_item, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()){
case R.id.delete:
if(currentItem != null){
promptForDelete();
}
else{
makeToast("Cannot delete item that has not been saved");
}
break;
case R.id.save:
if(saveItem()){
makeToast(currentItem != null ? "Item updated" : "Item saved");
}
break;
}
return super.onOptionsItemSelected(item);
}
private void makeToast(String message){
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
}
private boolean saveItem(){
Note = noteEditText.getText().toString();
date = dateText.getText().toString();
title = itemEditText.getText().toString();
if(TextUtils.isEmpty(title)){
itemEditText.setError("Item is required");
return false;
}
quantity = quantityEditText.getText().toString();
if(TextUtils.isEmpty(quantity)){
quantityEditText.setError("Quantity is required");
return false;
}
if(unit.equals("None")){
unitError = (TextView)spinner.getSelectedView();
unitError.setError("");
unitError.setTextColor(Color.RED);
unitError.setTextSize(R.dimen.text_size_normal);
unitError.setText("Select a unit!");
return false;
}
if(currentItem != null){
currentItem.setTitle(title);
currentItem.setQuantity(quantity);
currentItem.setUnit(unit);
currentItem.setDate(date);
currentItem.setNote(Note);
ItemManager.newInstance(getActivity()).update(currentItem);
}
else {
Item item = new Item();
item.setTitle(title);
item.setQuantity(quantity);
item.setUnit(unit);
item.setDate(date);
item.setNote(Note);
ItemManager.newInstance(getActivity()).create(item);
}
return true;
}
private void populateFields(){
itemEditText.setText(currentItem.getTitle());
quantityEditText.setText(currentItem.getQuantity());
noteEditText.setText(currentItem.getNote());
dateText.setText(currentItem.getDate());
}
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putString("title", title);
outState.putString("quantity", quantity);
outState.putString("selunit", unit);
outState.putString("seldate", date);
outState.putString("note", Note);
}
public void promptForDelete(){
final String itemToBeDeleted = currentItem.getTitle();
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
alertDialog.setTitle("Delete" + itemToBeDeleted + "?");
alertDialog.setMessage("Are you sure you want to delete " + itemToBeDeleted + "?");
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ItemManager.newInstance(getActivity()).delete(currentItem);
makeToast(itemToBeDeleted + "deleted");
startActivity(new Intent(getActivity(), MainActivity.class));
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}
EDITED - added ItemListAdapter.java & ItemManager.java
ItemListAdapter.java
public class ItemListAdapter extends RecyclerView.Adapter<ItemListAdapter.ViewHolder> {
private List<Item> mItems;
private Context mContext;
public ItemListAdapter(List<Item> items, Context context){
mItems = items;
mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rowView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item_list, parent, false);
ViewHolder viewHolder = new ViewHolder(rowView);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemx.setText(mItems.get(position).getTitle());
holder.quantity.setText(String.valueOf(mItems.get(position).getQuantity()));
holder.unit.setText(mItems.get(position).getUnit());
holder.note.setText(mItems.get(position).getNote());
holder.expDate.setText(mItems.get(position).getDate());
}
#Override
public int getItemCount() {
return mItems.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public final TextView itemx;
public final TextView quantity;
public final TextView unit;
public final TextView note;
public final TextView expDate;
public ViewHolder(View itemView) {
super(itemView);
itemx = (TextView)itemView.findViewById(R.id.tv_item);
quantity = (TextView)itemView.findViewById(R.id.tv_quantity);
unit = (TextView)itemView.findViewById(R.id.tv_unit);
note = (TextView)itemView.findViewById(R.id.tv_note);
expDate = (TextView)itemView.findViewById(R.id.tv_exp_date);
}
}
public void promptForDelete(final int position){
String fieldToBeDeleted = mItems.get(position).getTitle();
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("Delete " + fieldToBeDeleted + " ?");
alertDialog.setMessage("Are you sure you want to delete the item " + fieldToBeDeleted + "?");
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
mItems.remove(position);
notifyItemRemoved(position);
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}
ItemManager.java
public class ItemManager{
private Context mContext;
private static ItemManager itemManagerInstance = null;
public static ItemManager newInstance(Context context){
if (itemManagerInstance == null){
itemManagerInstance = new ItemManager(context.getApplicationContext());
}
return itemManagerInstance;
}
private ItemManager(Context context){
this.mContext = context.getApplicationContext();
}
public long create(Item item){
ContentValues values = new ContentValues();
values.put(Constants.COLUMN_TITLE, item.getTitle());
values.put(Constants.COLUMN_QUANTITY, item.getQuantity());
values.put(Constants.COLUMN_UNIT, item.getUnit());
values.put(Constants.COLUMN_EXPIRY_DATE, item.getDate());
values.put(Constants.COLUMN_NOTE, item.getNote());
Uri result = mContext.getContentResolver().insert(XContentProvider.ITEM_URI, values);
long id = Long.parseLong(result.getLastPathSegment());
return id;
}
public void update(Item item){
ContentValues values = new ContentValues();
values.put(Constants.COLUMN_TITLE, item.getTitle());
values.put(Constants.COLUMN_QUANTITY, item.getQuantity());
values.put(Constants.COLUMN_UNIT, item.getUnit());
values.put(Constants.COLUMN_EXPIRY_DATE, item.getDate());
values.put(Constants.COLUMN_NOTE, item.getNote());
mContext.getContentResolver().update(XContentProvider.ITEM_URI, values, Constants.COLUMN_ID + " = " + item.getId(), null);
}
public void delete(Item item){
mContext.getContentResolver().delete(XContentProvider.ITEM_URI, Constants.COLUMN_ID + " = " + item.getId(), null);
}
public List<Item> getAllItems(){
List<Item> items = new ArrayList<Item>();
Cursor cursor = mContext.getContentResolver().query(XContentProvider.ITEM_URI, Constants.COLUMNS, null, null, null);
if (cursor != null){
cursor.moveToFirst();
while (!cursor.isAfterLast()){
items.add(Item.getItemfromCursor(cursor));
cursor.moveToNext();
}
cursor.close();
}
return items;
}
public Item getItem(Long id){
Item item;
Cursor cursor = mContext.getContentResolver().query(XContentProvider.ITEM_URI, Constants.COLUMNS, Constants.COLUMN_ID + " = " + id, null, null);
if (cursor != null){
cursor.moveToFirst();
item = Item.getItemfromCursor(cursor);
return item;
}
return null;
}
}
You probably need to use SharedPreferences or SQL database to save data .onSaveInstanceState is used for save state when fragment is possible to be destroyed.
Just pass id of item to ItemFragment and display data in it.
openFragment(new ItemFragment(item.getId()), "Add Item")
package com.airi.vcare;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
public class ItemFragment extends DialogFragment {
private View mRootView;
private Item currentItem = null;
private Toolbar mToolbar;
private String date;
private String Note;
private String title;
private String quantity;
private TextView dateText;
private TextView unitError;
private EditText itemEditText;
private EditText quantityEditText;
private EditText noteEditText;
private Spinner remSpinner;
private Spinner spinner;
private String unit;
private String reminder;
private int spinnerCount=0;
private int spinnerInitializedCount=0;
private int remSpinnerCount=0;
private int remSpinnerInitializedCount=0;
public ItemFragment() {
}
//create an instance of the fragment
public static ItemFragment newInstance(long id) {
ItemFragment fragment = new ItemFragment();
if (id > 0) {
Bundle bundle = new Bundle();
bundle.putLong("id", id);
fragment.setArguments(bundle);
}
return fragment;
}
//get id of an item
public void getCurrentItem() {
Bundle args = getArguments();
if (args != null && args.containsKey("id")) {
long id = args.getLong("id", 0);
if (id > 0) {
currentItem = ItemManager.newInstance(getActivity()).getItem(id);
}
}
}
//notify Activity that the fragment wants to place an item in the menu
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
getCurrentItem();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.add_item, container, false);
itemEditText=(EditText)mRootView.findViewById((R.id.add_item));
quantityEditText=(EditText)mRootView.findViewById(R.id.amount);
unitError = (TextView)mRootView.findViewById(R.id.unit_error);
noteEditText = (EditText)mRootView.findViewById(R.id.add_notes);
dateText = (TextView)mRootView.findViewById(R.id.date_selected);
//unit spinner code here
//reminder spinner here
spinner.setOnItemSelectedListener(spinnerListener);
remSpinner.setOnItemSelectedListener(spinnerListener);
spinnerCount=1;
remSpinnerCount=1;
//just display fields .
populateFields();
return mRootView;
}
//spinner listener
AdapterView.OnItemSelectedListener spinnerListener = new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getId()) {
case R.id.units:
//set spinner text appearance
((TextView)parent.getChildAt(0)).setTextSize(13);
((TextView)parent.getChildAt(0)).setTextColor(Color.DKGRAY);
if(spinnerInitializedCount<spinnerCount){
spinnerInitializedCount++;
} else {
//get selected unit
unit = parent.getItemAtPosition(position).toString();
}
break;
case R.id.reminder_list:
//set spinner text appearance
((TextView)parent.getChildAt(0)).setTextSize(13);
((TextView)parent.getChildAt(0)).setTextColor(Color.DKGRAY);
//get selected reminder
reminder = parent.getItemAtPosition(position).toString();
break;
}
}}
public void onNothingSelected(AdapterView<?> parent) {
}
};
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.menu_add_item, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()){
case R.id.delete:
if(currentItem != null){
promptForDelete();
}
else{
makeToast("Cannot delete item that has not been saved");
}
break;
case R.id.save:
if(saveItem()){
makeToast(currentItem != null ? "Item updated" : "Item saved");
}
break;
}
return super.onOptionsItemSelected(item);
}
private void makeToast(String message){
Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show();
}
private boolean saveItem(){
Note = noteEditText.getText().toString();
date = dateText.getText().toString();
title = itemEditText.getText().toString();
if(TextUtils.isEmpty(title)){
itemEditText.setError("Item is required");
return false;
}
quantity = quantityEditText.getText().toString();
if(TextUtils.isEmpty(quantity)){
quantityEditText.setError("Quantity is required");
return false;
}
if(unit.equals("None")){
unitError = (TextView)spinner.getSelectedView();
unitError.setError("");
unitError.setTextColor(Color.RED);
unitError.setTextSize(R.dimen.text_size_normal);
unitError.setText("Select a unit!");
return false;
}
if(currentItem != null){
currentItem.setTitle(title);
currentItem.setQuantity(quantity);
currentItem.setUnit(unit);
currentItem.setDate(date);
currentItem.setNote(Note);
ItemManager.newInstance(getActivity()).update(currentItem);
}
else {
Item item = new Item();
item.setTitle(title);
item.setQuantity(quantity);
item.setUnit(unit);
item.setDate(date);
item.setNote(Note);
ItemManager.newInstance(getActivity()).create(item);
}
return true;
}
private void populateFields(){
itemEditText.setText(currentItem.getTitle());
quantityEditText.setText(currentItem.getQuantity());
noteEditText.setText(currentItem.getNote());
dateText.setText(currentItem.getDate());
}
#Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putString("title", title);
outState.putString("quantity", quantity);
outState.putString("selunit", unit);
outState.putString("seldate", date);
outState.putString("note", Note);
}
public void promptForDelete(){
final String itemToBeDeleted = currentItem.getTitle();
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
alertDialog.setTitle("Delete" + itemToBeDeleted + "?");
alertDialog.setMessage("Are you sure you want to delete " + itemToBeDeleted + "?");
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ItemManager.newInstance(getActivity()).delete(currentItem);
makeToast(itemToBeDeleted + "deleted");
startActivity(new Intent(getActivity(), MainActivity.class));
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}
public class ItemListAdapter extends RecyclerView.Adapter<ItemListAdapter.ViewHolder> {
private List<Item> mItems;
private Context mContext;
public ItemListAdapter(List<Item> items, Context context){
mItems = items;
mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rowView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item_list, parent, false);
ViewHolder viewHolder = new ViewHolder(rowView);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemx.setText(mItems.get(position).getTitle());
holder.quantity.setText(String.valueOf(mItems.get(position).getQuantity()));
holder.unit.setText(mItems.get(position).getUnit());
holder.note.setText(mItems.get(position).getNote());
holder.expDate.setText(mItems.get(position).getDate());
holder.item.getParent().setOnClick(new OnClickListener(){
onclick(View view){
//todo here
openFragment(new ItemFragment(item.getId()), "Add Item")
}
})
}
#Override
public int getItemCount() {
return mItems.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public final TextView itemx;
public final TextView quantity;
public final TextView unit;
public final TextView note;
public final TextView expDate;
public ViewHolder(View itemView) {
super(itemView);
itemx = (TextView)itemView.findViewById(R.id.tv_item);
quantity = (TextView)itemView.findViewById(R.id.tv_quantity);
unit = (TextView)itemView.findViewById(R.id.tv_unit);
note = (TextView)itemView.findViewById(R.id.tv_note);
expDate = (TextView)itemView.findViewById(R.id.tv_exp_date);
}
}
public void promptForDelete(final int position){
String fieldToBeDeleted = mItems.get(position).getTitle();
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("Delete " + fieldToBeDeleted + " ?");
alertDialog.setMessage("Are you sure you want to delete the item " + fieldToBeDeleted + "?");
alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
mItems.remove(position);
notifyItemRemoved(position);
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}
I am selecting multiple items in my recylcerview and when i delete these multiple items using Action mode bar then default delete animation is not showing but when i am deleting item single then animation plays?
This is my MainActivity.
public class MainActivity extends AppCompatActivity implements android.view.ActionMode.Callback {
public static boolean list_layout = true;
SwipeRefreshLayout swipeRefreshLayout;
RecyclerView recyclerView;
ActionMode actionMode;
MyAdapter adapter;
private List<Person> persons;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.rv);
recyclerView.setHasFixedSize(false);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addOnItemTouchListener(new RecyclerViewTouchListener(this, recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
Toast.makeText(MainActivity.this, "onClick " + position, Toast.LENGTH_SHORT).show();
if (actionMode != null) {
myToggleSelection(position);
}
if (adapter.getSelectedItemCount() == 0 && actionMode != null) {
actionMode.finish();
}
}
#Override
public void onLongClick(View view, int position) {
Toast.makeText(MainActivity.this, "onLongClick " + position, Toast.LENGTH_SHORT).show();
if (actionMode != null) {
return;
}
actionMode = startActionMode(MainActivity.this);
myToggleSelection(position);
}
}));
initializeData();
adapter = new MyAdapter(this, persons);
recyclerView.setAdapter(adapter);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refreshSwipe);
swipeRefreshLayout.setColorSchemeColors(Color.BLUE, Color.GREEN, Color.RED, Color.DKGRAY);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(false);
}
});
}
private void myToggleSelection(int idx) {
adapter.toggleSelection(idx);
String title = getString(R.string.selected_count, adapter.getSelectedItemCount());
actionMode.setTitle(adapter.getSelectedItemCount() + " Selected");
}
private void initializeData() {
persons = new ArrayList<>();
for (int i = 0; i < 5; i++) {
persons.add(new Person("Emma Wilson", "23 years old", R.mipmap.ic_launcher));
persons.add(new Person("Lavery Maiss", "25 years old", R.mipmap.ic_launcher));
persons.add(new Person("Lillie Watts", "35 years old", R.mipmap.ic_launcher));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
if (list_layout) {
list_layout = false;
recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
MyAdapter adapter = new MyAdapter(this, persons);
recyclerView.setAdapter(adapter);
item.setIcon(R.drawable.abc_ic_menu_copy_mtrl_am_alpha);
} else {
list_layout = true;
recyclerView.setLayoutManager(new LinearLayoutManager(this));
MyAdapter adapter = new MyAdapter(this, persons);
recyclerView.setAdapter(adapter);
item.setIcon(R.drawable.abc_ic_menu_selectall_mtrl_alpha);
}
return true;
}
return super.onOptionsItemSelected(item);
}
// Action Mode Methods
#Override
public boolean onCreateActionMode(android.view.ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_cab_recyclerviewdemoactivity, menu);
return true;
}
#Override
public boolean onPrepareActionMode(android.view.ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(android.view.ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_delete:
List<Integer> selectedItemPositions = adapter.getSelectedItems();
for (int i = selectedItemPositions.size() - 1; i >= 0; i--) {
adapter.remove(selectedItemPositions.get(i));
}
actionMode.finish();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(android.view.ActionMode mode) {
this.actionMode = null;
adapter.clearSelections();
}
// Interface
interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
}
This my Adapter class.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
List<Person> persons;
LayoutInflater inflater;
Context context;
private int previousPosition = 0;
private boolean deleting = false;
private boolean isGridLayout = false;
private boolean isOddCard = true;
private SparseBooleanArray selectedItems = new SparseBooleanArray();
private SparseBooleanArray mSelectedPositions = new SparseBooleanArray();
private boolean mIsSelectable = false;
private boolean selecting = false;
public MyAdapter(Context context, List<Person> persons) {
this.persons = persons;
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int resource = R.layout.cardview_list_item;
if (!MainActivity.list_layout) {
resource = R.layout.cardview_grid_item;
isGridLayout = true;
} else {
isGridLayout = false;
}
View view = inflater.inflate(resource, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Person person = persons.get(position);
holder.personName.setText(person.name);
holder.personAge.setText(person.age);
holder.personPhoto.setImageResource(person.photoId);
holder.itemView.setActivated(selectedItems.get(position, false));
holder.overflowMenu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showPopMenu((ImageButton) v, holder);
}
});
}
private void showPopMenu(ImageButton button, final ViewHolder holder) {
PopupMenu popup = new PopupMenu(context, button);
//Inflating the Popup using xml file
popup.getMenuInflater()
.inflate(R.menu.menu_card, popup.getMenu());
//registering popup with OnMenuItemClickListener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(context, "You Clicked : " + item.getTitle(), Toast.LENGTH_SHORT).show();
deleting = true;
int position = holder.getPosition();
remove(position);
return true;
}
});
popup.show();
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public int getItemCount() {
return persons.size();
}
public void toggleSelection(int pos) {
if (selectedItems.get(pos, false)) {
selectedItems.delete(pos);
} else {
selectedItems.put(pos, true);
}
selecting = true;
notifyItemChanged(pos);
}
public void clearSelections() {
selectedItems.clear();
notifyDataSetChanged();
selecting = false;
}
public int getSelectedItemCount() {
return selectedItems.size();
}
public List<Integer> getSelectedItems() {
List<Integer> items =
new ArrayList<Integer>(selectedItems.size());
for (int i = 0; i < selectedItems.size(); i++) {
items.add(selectedItems.keyAt(i));
}
return items;
}
public void remove(int position) {
persons.remove(position);
deleting = true;
notifyItemRemoved(position);
}
public class ViewHolder extends RecyclerView.ViewHolder {
CardView cv;
ImageButton overflowMenu;
TextView personName;
TextView personAge;
ImageView personPhoto;
View itemView;
public ViewHolder(View itemView) {
super(itemView);
this.itemView = itemView;
cv = (CardView) itemView.findViewById(R.id.cardView);
overflowMenu = (ImageButton) itemView.findViewById(R.id.imageButton);
personName = (TextView) itemView.findViewById(R.id.person_name);
personAge = (TextView) itemView.findViewById(R.id.person_age);
personPhoto = (ImageView) itemView.findViewById(R.id.person_photo);
}
}
}
actionMode.finish() will stop the remove animation of your recycler view, because adapter.clearSelections() called in onDestroyActionMode()
use notifyItemRangeChanged(0, selectedItems.size()) instead of notifyDataSetChanged() in adapter.clearSelections() method can make the animation work