Android: onItemCheckedStateChanged is called only once - java

Fragment class:
public class MultiFragmentListContent extends ListFragment
{
ListView listView;
ActionMode actionMode;
ArrayAdapter<String> arrayAdapter;
List<String> stringList;
Set<String> checkList;
AbsListView.MultiChoiceModeListener choiceModeListener = null;
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
super.onCreateView(inflater,container,savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment, container, false);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
checkList = new HashSet<>();
stringList = new LinkedList<>();
stringList.add("A");
stringList.add("B");
stringList.add("C");
stringList.add("D");
stringList.add("E");
listView = getListView();
arrayAdapter = new ArrayAdapter<String>(getActivity(),R.layout.string,stringList);
listView.setAdapter(arrayAdapter);
choiceModeListener = new AbsListView.MultiChoiceModeListener()
{
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked)
{
if(checked)
checkList.add(stringList.get(position));
else
checkList.remove(stringList.get(position));
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
actionMode = mode;
MenuInflater menuInflater = mode.getMenuInflater();
menuInflater.inflate(R.menu.contentmenu2,menu);
arrayAdapter = new ArrayAdapter<String>(getActivity(),R.layout.checkbox,stringList);
listView.setAdapter(arrayAdapter);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item)
{
switch(item.getItemId())
{
case R.id.contextmenu2:
for(String k : checkList)
{
stringList.remove(k);
Log.i(k,k);
}
actionMode.finish();
break;
}
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode)
{
arrayAdapter = new ArrayAdapter<String>(getActivity(),R.layout.string,stringList);
listView.setAdapter(arrayAdapter);
checkList.removeAll(checkList);
}
};
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(choiceModeListener);
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
{
listView.setMultiChoiceModeListener(choiceModeListener);
return true;
}
});
}
}
I noted that the method onItemCheckedStateChanged is called only once.
Before that method worked, I mean it was always called.
I tried to find on the web but I didn't find a solution.
I think that the problem is
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
but I don't know where to put it. If I put it in other places, the app crashes.

It's possible if you create one boolean value for your control in onItemCheckedStateChanged, the call always called, but will a have control.

Related

set suggestions on androidx.appcompat.widget.SearchView

I am making an android app in which i used a androidx.appcompat.widget.SearchView I have an arraylist which contains different values now i want to set the suggestions of androidx.appcompat.widget.SearchView from that array list. I tried a lot but it didn't work well.
I also toast in onQueryTextChange to test either it is working or not but it is not working because when i change the text i didn't get the toasr
public static ArrayList<String> phoneNo=new ArrayList<>(); // This one contains names
public static ArrayList<String> cname=new ArrayList<>(); // This one contains phone numbers
private SimpleCursorAdapter mAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root= inflater.inflate(R.layout.fragment_messages, container, false);
final String[] from = new String[] {"contacts"};
final int[] to = new int[] {android.R.id.text1};
mAdapter = new SimpleCursorAdapter(home_Activity,
android.R.layout.simple_list_item_1,
null,
from,
to,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
searchView = (SearchView) view.findViewById(R.id.sView);
searchView.setSuggestionsAdapter(mAdapter);
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
#Override
public boolean onSuggestionClick(int position) {
Cursor cursor = (Cursor) mAdapter.getItem(position);
String txt = cursor.getString(cursor.getColumnIndex("contacts"));
searchView.setQuery(txt, true);
return true;
}
#Override
public boolean onSuggestionSelect(int position) {
// Your code here
return true;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String s) {
populateAdapter(s);
Toast.makeText(home_Activity, "ok", Toast.LENGTH_SHORT).show();
return true;
}
});
}

problem opening searchview only zero position

Good day, I'm making a mistake where the search view always opens the zero position
Continuously opens zero position when filtering.
how can I solve this problem
Kitalar Adaptor
public class KitalarAdaptor extends ArrayAdapter {
ArrayList<KitalarVersiyon> items;
public KitalarAdaptor(Context context, int layout, ArrayList<KitalarVersiyon> items) {
super(context,layout);
this.items=items;
}
public void update(ArrayList<KitalarVersiyon> result){
items=new ArrayList<>();
items.addAll(result);
notifyDataSetChanged();
}
public class ViewHolder{
TextView textview;
ImageView ımageView;
TextView yüzölçümü;
TextView nufus;
TextView ülkesayısı;
}
#Override
public int getCount() {
return items.size();
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View row;
row=convertView;
ViewHolder viewHolder;
if (row==null){
row=LayoutInflater.from(getContext()).inflate(R.layout.kitalricinozzellayout,parent,false);
viewHolder=new ViewHolder();
viewHolder.ımageView=row.findViewById(R.id.kitalarimage);
viewHolder.textview=row.findViewById(R.id.kitalartext);
viewHolder.yüzölçümü=row.findViewById(R.id.yüzölçümü);
viewHolder.nufus=row.findViewById(R.id.nufus);
viewHolder.ülkesayısı=row.findViewById(R.id.ülkesayisi);
row.setTag(viewHolder);
}
else{
viewHolder=(ViewHolder) row.getTag();
}
viewHolder.ımageView.setImageResource(items.get(position).kitalarimage);
viewHolder.textview.setText(items.get(position).kitalarname);
viewHolder.yüzölçümü.setText(items.get(position).yüzölçümüaaaa);
viewHolder.nufus.setText(items.get(position).nufus);
viewHolder.ülkesayısı.setText(items.get(position).ülkesayısı);
return row;
}
}
KitalarVersiyon
public class KitalarVersiyon {
String kitalarname;
int kitalarimage;
String yüzölçümüaaaa;
String nufus;
String ülkesayısı;
public KitalarVersiyon(String kitalarname, int kitalarimage, String yüzölçümüaaaa, String nufus, String ülkesayısı) {
this.kitalarname = kitalarname;
this.kitalarimage = kitalarimage;
this.yüzölçümüaaaa = yüzölçümüaaaa;
this.nufus = nufus;
this.ülkesayısı = ülkesayısı;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.mymenu,menu);
MenuItem menuItem=menu.findItem(R.id.searchmenu);
final SearchView searchView=(SearchView)menuItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String s) {
ArrayList<KitalarVersiyon> result=new ArrayList<>();
for (KitalarVersiyon x:items){
if (x.kitalarname.contains(s))
result.add(x);
}
((KitalarAdaptor)listView.getAdapter()).update(result);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position==0){
Intent ıntent=new Intent(view.getContext(),Afrikakitasi2.class);
startActivity(ıntent);
}
}
});

Android: setMultiChoiceModeListener(Contextual Action Mode) isn't invoked immediately

I have a listview and I want to show a menu(Contextual Action Mode) when I do a long click on the list. It doesn't work when I click the first time, but other times it works. I noted that onItemLongClick is always called, but the Contextual Action Mode starts only the second time.
Here is my code:
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
stringList = new LinkedList<>();
stringList.add("A");
stringList.add("B");
stringList.add("C");
stringList.add("D");
stringList.add("E");
listView = getListView();
arrayAdapter = new ArrayAdapter<String>(getActivity(),R.layout.support_simple_spinner_dropdown_item,stringList);
listView.setAdapter(arrayAdapter);
final AbsListView.MultiChoiceModeListener choiceModeListener = new AbsListView.MultiChoiceModeListener()
{
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked)
{
Toast.makeText(getActivity(),position+"",Toast.LENGTH_SHORT).show();
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
MenuInflater menuInflater = mode.getMenuInflater();
menuInflater.inflate(R.menu.contentmenu2,menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
};
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
{
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(choiceModeListener);
Toast.makeText(getActivity(),"LONG CLICK",Toast.LENGTH_SHORT).show();
return true;
}
});
}
I bypassed the problem modyfing this part of the code:
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(choiceModeListener);
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
{
listView.setMultiChoiceModeListener(choiceModeListener);
return true;
}
});
In this way the context menu starts because I call it twice, but I don't understand why I have to call it two times...

null pointer exception in OnOptionItemSelected

I am trying to delete multiple checked rows from listview when click on the delete icon on action bar. However i get these nullpointerexception, i think the problem would be on adapter and dbHelper as i only declare them, but i do not know how i can solve this.
public class MainActivity extends ActionBarActivity {
public static TaskerDbHelper dbHelper;
public static ListView listviewTasks;
public static List<Task> arrayTasks;
public static TaskAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new TaskerDbHelper(this);
arrayTasks = dbHelper.getAllTasks();
listviewTasks = (ListView) findViewById(R.id.Tasks_onDate);
adapter = new TaskAdapter(this,arrayTasks);
listviewTasks.setAdapter(adapter);
listviewTasks.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Intent detailIntent = new Intent(MainActivity.this, DetailTaskActivity.class);
detailIntent.putExtra("rowID", (int)id);
startActivity(detailIntent);
}
});
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
#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.
switch(item.getItemId()){
case R.id.action_search:
return true;
case R.id.action_add:
Intent Addintent = new Intent(MainActivity.this, AddTaskActivity.class);
startActivity(Addintent);
return true;
case R.id.action_delete:
SparseBooleanArray checkedItems = listviewTasks.getCheckedItemPositions();
for (int i = 0; i < checkedItems.size(); i++){
if(checkedItems.valueAt(i)){
dbHelper.deleteTask((int)adapter.getItemId(i));
}
}
listviewTasks.invalidateViews();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
and the log is
http://i.stack.imgur.com/OqLuN.png
My guess is to work with a extended ArrayAdapter. This worked like a charm for me for multiple click->delete listview.
I declared it all like this:
arrayAdapter = new ListAdapter(this,R.layout.list_item, **YOUR LIST**);
listview.setAdapter(arrayAdapter);
listview.setCacheColorHint(Color.TRANSPARENT);
selectedItems = new ArrayList<Integer>();
listview.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
ArrayList<Integer> selectedIds = arrayAdapter.selectedid;
Integer pos = new Integer(position);
if(selectedIds.contains(pos)) {
selectedIds.remove(pos);
}
else {
selectedIds.add(pos);
}
arrayAdapter.notifyDataSetChanged();
}
});
The class I extended.
public class ListAdapter extends ArrayAdapter<ChartItem> {
Context context;
protected ArrayList<**YOUR LIST ITEM**> list;
LayoutInflater inflater;
ArrayList<Integer> selectedid;
public ListAdapter(Context context, int layoutResourceId ,ArrayList<ChartItem> ticket) {
super(context,layoutResourceId,ticket);
selectedid = new ArrayList<Integer>();
this.list = **ARRAY YOU WANT TO LIST**;
this.inflater = LayoutInflater.from(context);
this.context = context;
}
public int getCount() {
return list.size();
}
public ChartItem getItem(int position) {
return list.get(position);
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = this.inflater.inflate(R.layout.list_item, parent, false);
holder.name = (TextView) convertView.findViewById(R.id.rowTextView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ChartItem item = list.get(position);
TextView tv = (TextView) convertView.findViewById(R.id.rowTextView);
tv.setText(item.getName());
TextView tv2 = (TextView) convertView.findViewById(R.id.rowTextView2);
tv2.setText(String.valueOf(item.getPrice()));
if(selectedid.contains(position)){
tv.setBackgroundColor(Color.DKGRAY);
tv.setTextColor(Color.WHITE);
}
else{
tv.setBackgroundColor(Color.TRANSPARENT);
tv.setTextColor(Color.BLACK);
}
return convertView;
}
private class ViewHolder {
TextView name;
}
}
I really had allot of trouble with this aswell and I think this is the best way to do it so far.
If you need any more help or when you have questions about this code snippet let me know!
It is actually the checkedItems is null.
I actually wanna reach something like this. So when user checked the rows, they may delete or mark it as completed
http://i.stack.imgur.com/k4jKT.png
I solve it from another approaches like below.
case R.id.action_delete:
for(int i = 0; i < arrayTasks.size();i++){
if((CheckBox)listviewTasks.getChildAt(i).findViewById(R.id.selected) != null){
CheckBox cBox=(CheckBox)listviewTasks.getChildAt(i).findViewById(R.id.selected);
if(cBox.isChecked()){
dbHelper.deleteTask((int)adapter.getItemId(i));
}
}
}
adapter.notifyDataSetChanged();
return true;
I juz change the action_delete for the onoptionitemselected function.
[1]:

Delete Multiple Selected Items in ListView (cab) in android

I want to delete multiple selected items (row) in my listview (Gmail style).
If I select (with longClick) a row, nothing happens.
I've found this code on internet, and i've tried to insert it in my project.
MainActivity
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_lista, container,
false);
Lista = (ListView) rootView.findViewById(R.id.Lista);
items = new ArrayList<ListViewItem>();
items = GetLists.GetRecordList(rootView.getContext());
adapter = new ListaAdapter(rootView.getContext(),
R.layout.list_view_item, items);
Lista.setAdapter(adapter);
Lista.setMultiChoiceModeListener(this);
Lista.setChoiceMode(Lista.CHOICE_MODE_MULTIPLE_MODAL);
return rootView;
}
#Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menu) {
switch (menu.getItemId()) {
case R.id.menu_delete:
SparseBooleanArray selected = adapter.getSelectedIds();
for (int i = (selected.size() - 1); i >= 0; i--) {
if (selected.valueAt(i)) {
ListViewItem selectedItem = adapter.getItem(selected
.keyAt(i));
adapter.remove(selectedItem);
}
}
actionMode.finish();
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
actionMode.getMenuInflater().inflate(R.menu.delete_menu, menu);
return false;
}
#Override
public void onDestroyActionMode(ActionMode arg0) {
adapter.removeSelection();
}
#Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
return false;
}
#Override
public void onItemCheckedStateChanged(ActionMode actionMode, int position,
long arg2, boolean arg3) {
final int checkedOut = Lista.getCheckedItemCount();
actionMode.setTitle(checkedOut + " selezionato");
adapter.toggleSelection(position);
}
and this is the adapter
public class ListaAdapter extends ArrayAdapter<ListViewItem> {
private Context context;
private ArrayList<ListViewItem> items;
private SparseBooleanArray mSelectedItemsIds;
public ListaAdapter(Context context, int resourceId,
ArrayList<ListViewItem> items) {
super(context, resourceId, items);
mSelectedItemsIds = new SparseBooleanArray();
this.context = context;
this.items = items;
}
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
TextView txtSubTitle;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.list_view_item, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView
.findViewById(R.id.TitoloPrincipale);
holder.txtSubTitle = (TextView) convertView
.findViewById(R.id.Sottotitolo);
holder.imageView = (ImageView) convertView.findViewById(R.id.Image);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
ListViewItem list = getItem(position);
holder.txtTitle.setText(list.getNomeFarmaco());
holder.txtSubTitle.setText(list.getFasceOrarie());
holder.imageView.setImageResource(list.getIcon());
// convertView
// .setBackgroundColor(mSelectedItemsIds.get(position)
// : Color.TRANSPARENT);
return convertView;
}
public void remove(ListViewItem item) {
items.remove(item);
notifyDataSetChanged();
}
public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
notifyDataSetChanged();
}
public void selectView(int position, boolean value) {
if (value)
mSelectedItemsIds.put(position, value);
else
mSelectedItemsIds.delete(position);
notifyDataSetChanged();
}
public int getSelectedCount() {
return mSelectedItemsIds.size();
}
public SparseBooleanArray getSelectedIds() {
return mSelectedItemsIds;
}
have you got any idea?
tks
That code has nothing to do with long-clicks. The only occurrence of "long" is for a long parameter to a method. :-)
This sample project demonstrates an action mode starting up based upon a long-click of a list row. The key is onItemLongClick():
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setItemChecked(position, true);
return(true);
}
Here (courtesy of registering the activity as the OnItemLongClickListener for the ListView), we toggle on CHOICE_MODE_MULTIPLE_MODAL and check the item that was long-clicked, thereby activating the action mode.
The major problem you have not setMultiChoiceModeListener for listview like below
(Plz, see carefully onCreateActionMode and the loop in onActionItemClicked)
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
mode.getMenuInflater().inflate(R.menu.context_menu, menu);
return true;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem menuItem) {
// TODO Auto-generated method stub
switch (menuItem.getItemId()) {
case R.id.mnDelete:
SparseBooleanArray sparseBooleanArray = listView.getCheckedItemPositions();
for(int i = sparseBooleanArray.size() -1; i >= 0; i--)
items.remove(sparseBooleanArray.keyAt(i));
adapter.notifyDataSetChanged();
mode.finish();
break;
default:
break;
}
return true;
}
});
}
I've solved. thank you all.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_lista, container,
false);
Lista = (ListView) rootView.findViewById(R.id.Lista);
items = new ArrayList<ListViewItem>();
items = GetLists.GetRecordList(rootView.getContext());
adapter = new ListaAdapter(rootView.getContext(),
R.layout.list_view_item, items);
Lista.setAdapter(adapter);
Lista.setMultiChoiceModeListener(this);
Lista.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
return rootView;
}
#Override
public boolean onActionItemClicked(ActionMode arg0, MenuItem arg1) {
switch (arg1.getItemId()) {
case R.id.menu_delete:
SparseBooleanArray selected = adapter.getSelectedIds();
for (int i = (selected.size() - 1); i >= 0; i--) {
if (selected.valueAt(i)) {
ListViewItem selecteditem = adapter.getItem(selected
.keyAt(i));
adapter.remove(selecteditem);
}
}
// Close CAB
arg0.finish();
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode arg0, Menu arg1) {
arg0.getMenuInflater().inflate(R.menu.delete_menu, arg1);
return true;
}
#Override
public void onDestroyActionMode(ActionMode arg0) {
adapter.removeSelection();
}
#Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
return false;
}
#Override
public void onItemCheckedStateChanged(ActionMode arg0, int arg1, long arg2,
boolean arg3) {
final int checkedCount = Lista.getCheckedItemCount();
arg0.setTitle(checkedCount + " Selected");
adapter.toggleSelection(arg1);
}
}

Categories