I have a Listview in my row, I have check box to select a item to delete.
I want to have a button to select all my items and delete them at same time.
When I click my button to select all the items, only the last item gets selected.
Here is my code:
all.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
for(int i=0;i<listview.getChildCount();i++){
Log.i("mhs",listview.getChildCount()+"");
checkBox.setChecked(true);
}
}
});
Here is my Adaptor :
public class CustomArrayAdapter extends ArrayAdapter<String> {
private LayoutInflater inflater;
// This would hold the database objects i.e. Blacklist
private List<Blacklist> records;
#SuppressWarnings("unchecked")
public CustomArrayAdapter(Context context, int resource, #SuppressWarnings("rawtypes") List objects) {
super(context, resource, objects);
this.records = objects;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
//Reuse the view to make the scroll effect smooth
if (convertView == null)
convertView = inflater.inflate(R.layout.list_item, parent, false);
// Fetch phone number from the database object
final Blacklist phoneNumber = records.get(position);
// Set to screen component to display results
((TextView) convertView.findViewById(R.id.serial_tv)).setText("" + (position + 1));
((TextView) convertView.findViewById(R.id.phone_number_tv)).setText(phoneNumber.phoneNumber);
checkBox = (CheckBox) convertView.findViewById(R.id.check);
final LinearLayout me = (LinearLayout) convertView.findViewById(R.id.me);
if (position + 1 >= 1) {
me.setVisibility(View.VISIBLE);
}
checkBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (((CheckBox) v).isChecked()) {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
// Set the appropriate message into it.
alertDialogBuilder.setMessage(getResources().getString(R.string.block));
// Add a positive button and it's action. In our case action would be deletion of the data
alertDialogBuilder.setPositiveButton(getResources().getString(R.string.yes),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
try {
blackListDao.delete(blockList.get(position));
// Removing the same from the List to remove from display as well
blockList.remove(position);
listview.invalidateViews();
// Reset the value of selectedRecordPosition
selectedRecordPosition = -1;
populateNoRecordMsg();
} catch (Exception e) {
e.printStackTrace();
}
}
});
// Add a negative button and it's action. In our case, just hide the dialog box
alertDialogBuilder.setNegativeButton(getResources().getString(R.string.no),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
checkBox.setChecked(false);
}
});
// Now, create the Dialog and show it.
final AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
});
all.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
for(int i=0;i<listview.getChildCount();i++){
Log.i("mhs",listview.getChildCount()+"");
checkBox.setChecked(true);
listview.removeView(i);
}
}
});
return convertView;
}
}
How to select all the items together?
The issue with a listview is that the views are recycled! That means that calling
checkBox.setChecked(true);
Will simply just edit the current active item. If you want to remove all the items the best way to do so is to clear the list you are using, and the notifyingDataSetChanged().
In the for loop add this:
currentCheckBox = listView.getChildAt(i);
//now you should have the correct checkBox
Edit: if your needs is simply deleting the data and clearing, I'd make a method just for that. Call it, delete the items from db, then .clear() the adapter. (can't remember if notifyDatasetChanged() is called autmatically here, do it if not)
Related
I'm fetching the data from SQLite database and adding it to my custom listview which is used in multiple activities.
In the first screen that user sees it has full title and its full description displayed, but what I want is to limit the number of characters displayed in the title [ or just one line ] and description [ or maximum two lines ].
I know if I just had used that custom listview only once I could have done something like just display the substring of the title or description. But the problem is I'm using that listview in multiple places and I don't want to see that behaviour in other activities. Instead, for this activity what I want is to get the full title and description when clicked on that particular list item and I have already done this.
Here is my customListView Adapter is :
public class MyCustomNotesAdapter extends BaseAdapter {
Context context;
ArrayList<Note> noteList;
public MyCustomNotesAdapter(Context context, ArrayList<Note> noteList) {
this.context = context;
this.noteList = noteList;
}
#Override
public int getCount() {
return this.noteList.size();
}
#Override
public Object getItem(int position) {
return noteList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View view, ViewGroup viewGroup) {
//inflate our custom listview
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.custom_notes_listview, null);
TextView title_text = view.findViewById(R.id.note_title);
TextView desc_text = view.findViewById(R.id.note_desc);
//Button update_btn = view.findViewById(R.id.update_note_button);
Note note = noteList.get(position);
title_text.setText(note.getTitle()); //note.getTitle().substring(beginIndex, endIndex) doesn't work for my case.
desc_text.setText(note.getDescription());
return view;
}
}
And the activity where Im using this is :
.................. other codes ......
//display notes of the logged in user
listView = findViewById(R.id.listView);
myNotesDatabaseHelper = new MyNotesDatabaseHelper(AllNotesScreenActivity.this);
final List<Note> allNotes =
myNotesDatabaseHelper.getAllNotes(myNotesDatabaseHelper.getIdFromUsername(username));
if (allNotes.size() <= 0)
Toast.makeText(this, "You have no notes , please create note.", Toast.LENGTH_SHORT).show();
//array adapter
myCustomNotesAdapter = new MyCustomNotesAdapter(AllNotesScreenActivity.this, (ArrayList<Note>) allNotes);
listView.setAdapter(myCustomNotesAdapter);
//handle delete on long click listener
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
//logic to delete item
final Note clickedNote = (Note) adapterView.getItemAtPosition(i);
//alert dialog for deleting your note on tapping
AlertDialog.Builder deleteNoteAlertDialog = new AlertDialog.Builder(
AllNotesScreenActivity.this);
//initializng alert dialog
alertDialog = new Alert("Delete Note !", "Do you want to delete this note permanently ? [ can't be undo ]");
// Setting Dialog Title
deleteNoteAlertDialog.setTitle(alertDialog.getAlertTitle());
// Setting Dialog Message
deleteNoteAlertDialog.setMessage(alertDialog.getAlertMessage());
// Setting Icon to Dialog
deleteNoteAlertDialog.setIcon(R.drawable.delete);
// Setting Positive "Yes" Btn
deleteNoteAlertDialog.setPositiveButton("YES",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
boolean success = myNotesDatabaseHelper.deleteOneNote(clickedNote);
if (!success) {
Toast.makeText(AllNotesScreenActivity.this, "Couldn't be deleted your note. ", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(AllNotesScreenActivity.this, "Note Deleted Successfully ", Toast.LENGTH_LONG).show();
Intent intent = new Intent(getApplicationContext(), AllNotesScreenActivity.class);
intent.putExtra("username", username);
startActivity(intent);
}
});
// Setting Negative "NO" Btn
deleteNoteAlertDialog.setNegativeButton("NO",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Dialog
deleteNoteAlertDialog.show();
return true;
}
});
I searched for it but I couldn't find it. Any help is appreciated.
Kotlin code:
textView.ellipsize = TextUtils.TruncateAt.END
textView.maxLines = 2 // or = 1
Java code:
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setMaxLines(2); // or setMaxLines(1)
I have a RecyclerView who play the recording when certain item is clicked. I want the behave when a user clicks on item1 that specific recording is playing and button View is changed which is working fine.
But at the same time when item1 recording is playing and user click on item2 then item1 row Button come back to its original position.
Below Image show the View when item1(Row 1) is clicked. (This is working fine)
I have also test this to control the View in inBindViewHolder method.But it is not working because whenever I clicked holder object control the View of current selected row only.
Below Code Section is placed in the ViewHolder
mPlayAudio.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
Log.d(TAG, "onClick: Present in onClick mPlayAudio");
if (listener != null)
{
final int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION)
{
// This section contain the code to play and stop
the audio
// Using below line I only able to change selected
// row button View not other row Button View
mPlayAudio.setImageResource(R.drawable.play);
}
}
}
});
I have also try this with in onBindViewHolder method but still not working.
Below Code added in onBindViewHolder
holder.mPlayAudio.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view)
{
// This section contain code to play and stop audio
//Using below statement I only able to change the
//visibility of current selected row View not others
holder.mPlayAudio.setImageResource(R.drawable.play);
}
}
So I finally was able to try this out on my own project.
Answer
In BindViewHolder, after you have made an item click, save the value of the position of that item. Then call notifyDataSetChanged inside the click event, which will refresh the adapter. Now it obtain your result, inside BindViewHolder have an if statement checking if that value should be set accordingly (or invisible), otherwise display as visible.
Example Code
public class SelectorAdapter extends RecyclerView.Adapter<SelectorAdapter.ItemHolder> implements View.OnClickListener {
private List itemList;
private int selectedKey;
public SelectorAdapter(List list) {
itemList = list;
}
#Override
public void onClick(View v) {
}
/* ViewHolder for each item */
class ItemHolder extends RecyclerView.ViewHolder {
//title
#BindView(R.id.selector_title)
TextView title;
#BindView(R.id.selector_layout)
LinearLayout selector;
ItemHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
#Override
public ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout_selector, parent, false);
return new ItemHolder(itemView);
}
#Override
public void onBindViewHolder(ItemHolder holder, int position) {
String title = (String) itemList.get(position);
holder.title.setText(title);
if (position != selectedKey) {
holder.title.setBackgroundResource(R.drawable.selector);
} else {
holder.title.setBackgroundResource(R.drawable.selector_selected);
}
holder.itemView.setOnClickListener(v -> {
Timber.e("selected item: %s", position);
selectedKey = position;
notifyDataSetChanged();
});
}
#Override
public int getItemCount() {
Timber.e("itemCount: %s", itemList.size());
return itemList.size();
}
}
Here is my own project where when I select an item, it changes the background resource to selected, and then the rest are returned to the default state.
I have a ListView which implements a custom adapter that contains a few TextViews and two Buttons.
Now when i try to add an item to that ListView, if it is already in the list i want to change the text of its row's TextView (Quantity) and make it + 1. But i can't quite figure out how to interact with that particular TextView.
Adapter code:
public class ItemAdapter extends ArrayAdapter<Item> {
public ItemAdapter(#NonNull Context context) {
super(context, R.layout.lay_list_items);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater li = LayoutInflater.from(getContext());
View v = li.inflate(R.layout.lay_list_items, null);
final Item item = getItem(position);
TextView nom = (TextView)v.findViewById(R.id.txtNom);
TextView description = (TextView)v.findViewById(R.id.txtDescription);
final TextView qty = (TextView)v.findViewById(R.id.txtQty);
Button btnAjouter = (Button)v.findViewById(R.id.btnAjouter);
Button btnRetirer = (Button)v.findViewById(R.id.btnRetirer);
nom.setText(item.nom);
description.setText(item.description);
qty.setText("1");
btnAjouter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int qtyCourante = Integer.parseInt(qty.getText().toString());
int newQty = qtyCourante + 1;
qty.setText(Integer.toString(newQty));
}
});
btnRetirer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int qtyCourante = Integer.parseInt(qty.getText().toString());
int newQty = qtyCourante - 1;
if (newQty > 0)
qty.setText(Integer.toString(newQty));
else
ItemAdapter.super.remove(item);
}
});
return v;
}
You need to save the count, and then use it.
Use ArrayList<Integer> or add one more field int count in your Model Class Item. It is better to add one more field in Item class.
Initialize it as 1 for all items.
And use the code,
qty.setText(String.valueOf(item.getCount()));//declare a method to get count field value, here getCount()
In your button click,
btnAjouter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
item.setCount( item.getCount() + 1 ); //declare a method to set value
notifyDataSetChanged();
}
});
And also
btnRetirer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if ( item.getCount() > 0)
item.setCount( item.getCount() - 1 );
else
ItemAdapter.super.remove(item);
notifyDataSetChanged();
}
});
notifyDataSetChanged(); should be invoked to update your changes.
Since you are using an ArrayAdapter as your base Class, if you want to add a new item, you can just call:
adapter.add(newItem);
adapter.notifyDataSetChanged();
and the adapter will help you handle the new item.
I created an imageviewer app. Its working fine but when I select a gridview item to delete it, it stops working. On selecting the item, delete button appears . On clicking the delete button ,an alert dialog appears asking for confirmation.I want the file to get deleted after cliking the YES button. But it does not happen. Instead it throws an indexoutofbounds exception. How can I delete selected file succesfully ?
PhotosActivity.java
import static com.example.dell_1.myapp3.ImageViewer.ImageGallery.al_images;
public class PhotosActivity extends AppCompatActivity {
int int_position;
private GridView gridView;
GridViewAdapter adapter;
ArrayList<Model_images> al_menu = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_gallery);
final ImageButton button1 = (ImageButton) findViewById(R.id.button1);
final ImageButton button2 = (ImageButton) findViewById(R.id.button2);
final ImageButton button3 = (ImageButton) findViewById(R.id.button3);
final ImageButton button4 = (ImageButton) findViewById(R.id.button4);
final ImageButton button5 = (ImageButton) findViewById(R.id.button5);
button1.setVisibility(View.GONE);
button2.setVisibility(View.GONE);
button3.setVisibility(View.GONE);
button4.setVisibility(View.GONE);
button5.setVisibility(View.GONE);
gridView = (GridView) findViewById(android.R.id.list);
int_position = getIntent().getIntExtra("value", 0);
adapter = new GridViewAdapter(this, al_images, int_position);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String abc = "file://" + al_images.get(int_position).getAl_imagepath().get(position);
Intent i = new Intent(getApplicationContext(), FullImageActivity.class);
i.putExtra("id", position);
i.putExtra("folderPosition", int_position);
i.putExtra("abc", abc);
startActivity(i);
}
});
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
for (int j = 0; j < parent.getChildCount(); j++)
parent.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);
// change the background color of the selected element
view.setBackgroundColor(Color.LTGRAY);
button1.setVisibility(View.VISIBLE);
button2.setVisibility(View.VISIBLE);
button3.setVisibility(View.VISIBLE);
button4.setVisibility(View.VISIBLE);
button5.setVisibility(View.VISIBLE);
button3.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
AlertDialog.Builder builder1 = new AlertDialog.Builder(PhotosActivity.this);
builder1.setMessage("Are you sure you want to delete it ?");
builder1.setCancelable(true);
builder1.setPositiveButton(
"Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
File file = new File( al_menu.get(int_position).getAl_imagepath().get(position));
file.delete();
al_menu.remove(position);
adapter.notifyDataSetChanged();
}
});
builder1.setNegativeButton(
"No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
});
return true;
}
});
}
}
GridViewAdapter.java:
public class GridViewAdapter extends ArrayAdapter<Model_images> {
Context context;
ViewHolder viewHolder;
ArrayList<Model_images> al_menu = new ArrayList<>();
int int_position;
public GridViewAdapter(Context context, ArrayList<Model_images> al_menu,int int_position) {
super(context, R.layout.activity_adapter__photos_folder, al_menu);
this.al_menu = al_menu;
this.context = context;
this.int_position = int_position;
}
#Override
public int getCount() {
Log.e("ADAPTER LIST SIZE", al_menu.get(int_position).getAl_imagepath().size() + "");
return al_menu.get(int_position).getAl_imagepath().size();
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getViewTypeCount() {
if (al_menu.get(int_position).getAl_imagepath().size() > 0) {
return al_menu.get(int_position).getAl_imagepath().size();
} else {
return 1;
}
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(R.layout.activity_adapter__photos_folder, parent, false);
viewHolder.tv_foldern = (TextView) convertView.findViewById(R.id.tv_folder);
viewHolder.tv_foldersize = (TextView) convertView.findViewById(R.id.tv_folder2);
viewHolder.iv_image = (ImageView) convertView.findViewById(R.id.iv_image);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv_foldern.setVisibility(View.GONE);
viewHolder.tv_foldersize.setVisibility(View.GONE);
Glide.with(context).load("file://" + al_menu.get(int_position).getAl_imagepath().get(position))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(viewHolder.iv_image);
return convertView;
}
private static class ViewHolder {
TextView tv_foldern, tv_foldersize;
ImageView iv_image;
}
}
LOGCAT :
10-15 11:38:03.449 31844-31844/com.example.dell_1.Myapp3 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dell_1.Myapp3, PID: 31844
java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at com.example.dell_1.myapp3.ImageViewer.PhotosActivity$2$1$1.onClick(PhotosActivity.java:87)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
what is al_images ??
you have not initialized al_images
If you want to delete the item for the Grid, you should also have to notify the grid adapter of the change in the data set.
Delete the item from the data set.
Notify the Grid Adapter of the change in data set.
The above behavior needs to be defined in the Adapter's getView() method. While populating the elements after the (if else) block. You should set a tag with every view in order to correctly identify which item you want to delete. Use
ViewHolder.deleteButton.setTag(position);
In this case param will be your delete button, so that after clicking the button, you will know the item whose button is clicked and perform the following function in the getView() method.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Gets the index of the item to delete
Integer index = (Integer) v.getTag();
// Use the above index to delete item from data set
// Delete your item here
//For e.g: notes.remove(index.intValue());
// Must call this after deletion from the data set
notifyDataSetChanged();
}
});
I have A listview, and in list view I have A textview. So this text view is visible in every item of listview. So when I click on any Textview then it's visibility mus be gone. But when I'll click on another textview then current must gone and previous must be visible.
In adapter class I tried a lot of things but I did't find the correct way. So how can I get this thing in getView().
holder.floorNo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (holder.floorNo.getId() == v.getId()) {
final int position1 = listView
.getPositionForView((LinearLayout) v
.getParent());
} else {
}
}
});
Here position1 is the current position of click. Pleas help me.
You can set tag of textview as holder.settag(holder.floorNo). on click lister of floorNo get this tag by Textview floorno = (Textview) v.gettag();
Here you will get the clicked textview and add code for visible / invisible .
I don't know Which adapter you are using .If you are using CursorAdapter then in CursorAdapter by overridien method newView() it is possible
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
((TextView) (convertView
.findViewById(R.id.main_body_item_title_second_pics)))
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// do your stub here
}
});
}
You can use a textview class member as a "reminder" to know which textview is hidden, something like this :
private View mHiddenView = null
private int mFloorNoId = 0
....
....
holder.floorNo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mHiddenView !=null&&mFloorNoId!=0){
// Show textview that was hidden
mHiddenView.findViewById(mFloorNoId).setVisibility(VISIBLE);
}
// Assign clicked view to hidden one and FloorNo id
mHiddenView = v;
mFloorNoId = holder.floorNo.getId();
// And hide it
mHiddenView.findViewById(mFloorNoId).setVisibility(GONE);
}
});
maintain a list of boolean in your adapter indicating visibility of TextView holder.floorNo.
boolean[] visibilityArray;
in constructor
visibilityArray; = new boolean[ no. Of Elements in your adapter ];
in getView() method
holder.floorNo.setVisibility(visibilityArray[position]);
holder.floorNo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
notifyStateChange(position);
}
});
notifyStateChange(position) method defined as follows
private void notifyStateChange(int position) {
for(int i = 0; i<visibilityArray.length; i++){
visibilityArray[i] = true;
}
visibilityArray[position] = false;
this.notifyDataSetChanged();
}