Contextual action bar not showing sellection - android

I'm trying to implement a Contextual Action Bar (CAB) but whenever I long click an item it is not showing the item as selected (highlighted) so I'm not able to select multiple items to batch delete either. Below is the fragment attempting to utilize a CAB.
package com.garciaericn.memoryvault.main;
import android.app.Fragment;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import com.garciaericn.memoryvault.R;
import com.garciaericn.memoryvault.data.Memory;
import com.garciaericn.memoryvault.data.MemoryAdapter;
import com.parse.DeleteCallback;
import com.parse.FindCallback;
import com.parse.ParseException;
import java.util.List;
public class MemoriesFragment extends Fragment implements AbsListView.MultiChoiceModeListener, AdapterView.OnItemClickListener {
ListView memoriesListView;
MemoryAdapter memoryAdapter;
public MemoriesFragment() {
// Mandatory empty constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
memoryAdapter = new MemoryAdapter(getActivity());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_memories, container);
memoriesListView = (ListView) view.findViewById(R.id.listView);
memoriesListView.setAdapter(memoryAdapter);
memoriesListView.setOnItemClickListener(this);
memoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
memoriesListView.setMultiChoiceModeListener(this);
return view;
}
private void refreshMemories() {
Memory.getQuery().findInBackground(new FindCallback<Memory>() {
#Override
public void done(List<Memory> memoryList, ParseException e) {
memoryAdapter.loadObjects();
}
});
}
#Override
public void onStart() {
super.onStart();
refreshMemories();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_sync: {
refreshMemories();
Toast.makeText(getActivity(), "Refreshed from fragment", Toast.LENGTH_SHORT).show();
return true;
}
}
return super.onOptionsItemSelected(item);
}
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
// Here you can do something when items are selected/de-selected,
// such as update the title in the CAB
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_delete:
Toast.makeText(getActivity(), "Delete!", Toast.LENGTH_SHORT).show();
// TODO: Delete item
mode.finish(); // Action picked, so close the CAB
return true;
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// Here you can make any necessary updates to the activity when
// the CAB is removed. By default, selected items are deselected/unchecked.
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Memory memory = memoryAdapter.getItem(position);
/*// Un-comment to delete item
memory.deleteInBackground(new DeleteCallback() {
#Override
public void done(ParseException e) {
refreshMemories();
}
});
*/
Toast.makeText(getActivity(), memory.toString() + " was tapped", Toast.LENGTH_SHORT).show();
}
}

If you are implementing custom adapter you need to implement Checkable layout for listview item.
Check this Github page
which explains implementation of Checkable layout with demo adapter.
Use in in your custom list item layout like:
<your.package.CheckableLayout ... />

-Hey correct me if i am wrong I found in your code that you are implementing OnItemClickListener instead use AdapterView.OnItemLongClickListener as you wants you action on Long Click item.

Related

Menu in a custom toolbar not showing in a fragment

So I have had asked this multiple times but I can't get a decent answer to my question.
Can someone please tell me why my menu is not showing in my custom toolbar?
PurchaseItemList.java
package com.example.devcash.Fragments;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.SearchView;
import android.widget.Spinner;
import android.widget.Toast;
import com.example.devcash.R;
/**
* A simple {#link Fragment} subclass.
*/
public class PurchaseItemListFragment extends Fragment implements SearchView.OnQueryTextListener, MenuItem.OnActionExpandListener {
Toolbar itemListToolbar;
Spinner itemListSpinner;
public PurchaseItemListFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//inflate the menu
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_purchase_item_list, container, false);
itemListToolbar = (Toolbar) view.findViewById(R.id.toolbar_purchaseitemlist);
itemListSpinner = (Spinner) view.findViewById(R.id.spinner_allcategories);
///
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(getActivity(),
R.layout.custom_spinner_item,
getResources().getStringArray(R.array.dropdownitempurchase));
myAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
itemListSpinner.setAdapter(myAdapter);
itemListSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getActivity(),
itemListSpinner.getSelectedItem().toString(),
Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
return view;
}
//handles the search menu
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.searchmenu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(this);
searchView.setQueryHint("Search..");
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return true;
}
}
and this is a snippet of my custom toolbar in my fragment_purchase_item_list.xml
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_purchaseitemlist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
style="#style/PrimaryHeaderBar"
android:elevation="4dp">
<Spinner
android:id="#+id/spinner_allcategories"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
</android.support.v7.widget.Toolbar>
I have tried checking all the related posts from the internet and can't find a decent tutorial on YT. Can someone tell me what is going on here?
Add following line in onCreateView() method
setHasOptionsMenu(true)
Also add below line in onViewCreated() method
(activity as AppCompatActivity?)!!.setSupportActionBar(customToolbar as Toolbar?)
Where customToolBar is the id of the toolbar added in xml file
Add this in your onCreateView method
setHasOptionsMenu(true);

Error why working contextual action mode start ActionModeis not applicable for the arguments (ActionMode

I am following a tutorial 11. Exercise: Using the contextual action mode
But I am having this error :
mActionMode = Display.this.startActionMode(mActionModeCallback);
view.setSelected(true);
Error: The method startActionMode(ActionMode.Callback) in the type Activity is not applicable for the arguments (ActionMode.Callback)
I checked this stackoverflow answer
they said to add
ActionBarActivity activity=(ActionBarActivity)getActivity();
activity.startSupportActionMode(modeCallBack);
I had this error
The method getActivity() is undefined for the type Display
what I am doing wrong ? the below is my code.
package com.example.sqlfirst;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
public class Display extends ActionBarActivity {
private final static String TAG = "MainActivity";
protected Object mActionMode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid_main);
//have to use getSupportActionBar from android.support.v7.app
// ActionBar actionBar = getSupportActionBar();
//getActionBar().setDisplayHomeAsUpEnabled(true);
ActionBarActivity activity=(ActionBarActivity)getActivity();
activity.startSupportActionMode(modeCallBack);
View view = findViewById(R.id.gridview);
view.setOnLongClickListener(new View.OnLongClickListener() {
// called when the user long-clicks on someView
public boolean onLongClick(View view) {
if (mActionMode != null) {
return false;
}
// start the CAB using the ActionMode.Callback defined above
mActionMode = Display.this.startActionMode(mActionModeCallback);
view.setSelected(true);
return true;
}
});
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// Send intent to SingleViewActivity
Intent i = new Intent(getApplicationContext(), SingleViewActivity.class);
// Pass image index
i.putExtra("id", position);
startActivity(i);
} });
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main_actions, menu);
return super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item)
{
super.onOptionsItemSelected(item);
switch (item.getItemId()){
case R.id.ic_action_person:
Toast.makeText(this, "Create a new account please", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, Register.class);
startActivity(intent);
return true;
case R.id.ic_action_search:
Toast.makeText(this, "Search for new images", Toast.LENGTH_SHORT).show();
Intent isearch= new Intent(this,Search.class);
startActivity(isearch);
return true;
case R.id.ic_action_picture:
Toast.makeText(this, "Search for new photos", Toast.LENGTH_SHORT).show();
Intent iphotos= new Intent(this,Display.class);
startActivity(iphotos);
return true;
}
return true;
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
// assumes that you have "contexual.xml" menu resources
inflater.inflate(R.menu.activity_main_actions, menu);
return true;
}
// called each time the action mode is shown. Always called after
// onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done
}
// called when the user selects a contextual menu item
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.ic_action_picture:
Toast.makeText(Display.this, "Selected menu",
Toast.LENGTH_LONG).show();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
// called when the user exits the action mode
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
}
Your Display class is extending ActionBarActivity, that means that it´s an Activity so there´s no need to use getActivity(), you can directly make use of the methods like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* this method is available within your ActionBarActivity*/
startSupportActionMode(modeCallBack);
setContentView(R.layout.grid_main);
// The rest of your code comes here
}

How to dynamically add user input into a listView within a fragment?

Im trying to add text into a listview within a fragment but i keep getting an error: cannot find symbol method setListAdapter(ArrayAdapter).
I'm using this tutorial as reference but it only shows how to do it within a activity : http://wptrafficanalyzer.in/blog/dynamically-add-items-to-listview-in-android/
Im trying to move this over to a fragment. Can anyone help please i would highly appreciate it? heres my code :
MainActivity:
import android.app.Activity;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import com.example.fragments.DeleteDialogueFragment;
import com.example.PeopleFragment;
public class MainActivity extends Activity implements PeopleFragment.PeopleFragmentListener, DeleteDialogueFragment.DeleteDialogueListener {
private final String TAG = "MAINACTIVITY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PeopleFragment())
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
//INTERFACE METHODS
public void deleteCharacter(){
PeopleFragment peopleFragment = (PeopleFragment) getFragmentManager().findFragmentById(R.id.container);
peopleFragment.deleteCharacter();
}
}
PeopleFragment :
import android.app.Activity;
import android.app.DialogFragment;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import com.example.actionbardemo.R;
import java.util.ArrayList;
import java.util.Arrays;
public class PeopleFragment extends Fragment{
private final String TAG = "PEOPLEFRAGMENT";
private PeopleFragmentListener mListener;
private ArrayAdapter<String> mPeopleAdapter;
private ActionMode mActionMode;
private int mPersonSelected = -1;
/** Items entered by the user is stored in this ArrayList variable */
private ArrayList<String> pList = new ArrayList<String>();
public interface PeopleFragmentListener {
}
public static PeopleFragment newInstance() {
PeopleFragment fragment = new PeopleFragment();
return fragment;
}
public PeopleFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<String> people = new ArrayList<String>(Arrays.asList(getResources().getStringArray(R.array.people)));
mPeopleAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,people);
// Reference to the button of the layout main.xml
Button btn = (Button) getView().findViewById(R.id.btnAdd);
// Defining a click event listener for the button "Add"
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText edit = (EditText) getView().findViewById(R.id.txtItem);
pList.add(edit.getText().toString());
edit.setText("");
mPeopleAdapter.notifyDataSetChanged();
}
};
// Setting the event listener for the add button
btn.setOnClickListener(listener);
// Setting the adapter to the ListView
setListAdapter(mPeopleAdapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
ListView peopleList = (ListView) rootView.findViewById(R.id.peopleList);
peopleList.setAdapter(mPeopleAdapter);
peopleList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
if(mActionMode != null){
return false;
}
mPersonSelected = position;
mActionMode = getActivity().startActionMode(mActionModeCallback);
return true;
}
});
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (PeopleFragmentListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement PeopleFragmentListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
//INTERFACE METHODS
public void deleteCharacter(){
mPeopleAdapter.remove(mPeopleAdapter.getItem(mPersonSelected));
mPeopleAdapter.notifyDataSetChanged();
}
public String getToDelete(){
return mPeopleAdapter.getItem(mPersonSelected);
}
//CONTEXTUAL ACTION BAR CALLBACK
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.peoplemenu, menu);
return true;
}
// Called each time the action mode is shown. Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.peopleDelete:
Log.i(TAG,mPeopleAdapter.getItem(mPersonSelected));
DialogFragment dialog = new DeleteDialogueFragment();
Bundle args = new Bundle();
args.putString("name",mPeopleAdapter.getItem(mPersonSelected));
dialog.setArguments(args);
dialog.show(getActivity().getFragmentManager(), "DeleteDiaglogueFragment");
mode.finish();
return true;
default:
return false;
}
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
}
activity_main.xml (layout):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:ignore="MergeRootFrame" />
fragment_main.xml (layout):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="#+id/txtItem"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:inputType="text"
android:hint="#string/hintTxtItem"/>
<Button
android:id="#+id/btnAdd"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/lblBtnAdd"
android:layout_toRightOf="#id/txtItem"/>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/peopleList"
android:layout_gravity="center_horizontal" />
</LinearLayout>
strings.xml(values):
<string name="app_name">ActionBarDemo</string>
<string name="action_settings">Settings</string>
<string name="hintTxtItem">Enter an item here ...</string>
<string name="lblBtnAdd">Add Item</string>
<string name="txtEmpty">List is empty</string>
<string name="delete_confirm">Are you sure you want to delete</string>
<string name="delete">Delete</string>
<string name="cancel">Cancel</string>
<string-array name="people">
<item>person 1</item>
<item>person 2</item>
<item>person 3</item>
<item>person 4</item>
<item>person 5</item>
<item>person 6</item>
</string-array>

Selecting and Deleting List View items dynamically through a CAB on a button click, not through long press

I have an application with a list view and a custom adapter where I add custom objects to the list view. I know how to delete objects through long-pressing one of the list items in the list, but I have a trash can action bar button and I want it so that when you click on that button, it brings up the same CAB as if you were long-pressing a list item, and I want the user to be able to select multiple list items, and then click a delete button on the CAB.
What I have tried:
package viva.inspection.com.inspectionpicker;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.List;
import viva.inspection.com.inspectionpicker.R;
public class ListActivity extends Activity {
private static ArrayList<InspectionItem> inspections;
private static final String s = "inspection list";
public static final String PREFS_NAME = "MyPrefsFile";
ListView inspectionList;
private final int GET_VALUE=111;
private final int GET_VAL = 11;
private MyAdapter listviewadapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
inspectionList = (ListView) findViewById(R.id.listView);
inspectionList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
inspections = new ArrayList<InspectionItem>();
inspections.add(new InspectionItem(new GregorianCalendar(7,15,14), "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", new ArrayList<String>()));
if(getIntent().getStringExtra("NEW_VALUE") != null) {
//addItems(getIntent().getStringExtra("NEW_VALUE"));
SharedPreferences.Editor edit = settings.edit();
edit.putString("myKey", TextUtils.join(",", inspections));
edit.commit();
}
if(!(settings.getString("myKey", "hi").equals("hi"))) {
//We have saved values. Grab them.
} else {
//We have no saved values
inspections = new ArrayList<InspectionItem>();
inspections.add(new InspectionItem(new GregorianCalendar(7,15,14), "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", "hi", new ArrayList<String>()));
}
listviewadapter = new MyAdapter(this, R.layout.row_layout,
inspections);
inspectionList.setAdapter(listviewadapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.list, 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();
switch(id) {
case R.id.action_settings:
return true;
case R.id.action_new:
Intent intent = new Intent(this, InitialChoose.class);
startActivity(intent);
return true;
case R.id.action_delete:
inspectionList.setOnItemSelectedListener(new ActionBarCallBack());
startActionMode(new ActionBarCallBack());
//mActionMode.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
class ActionBarCallBack implements ListView.OnItemSelectedListener, ActionMode.Callback {
ActionMode activeMode;
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
// Calls getSelectedIds method from ListViewAdapter Class
SparseBooleanArray selected = listviewadapter
.getSelectedIds();
// Captures all selected ids with a loop
for (int i = (selected.size() - 1); i >= 0; i--) {
if (selected.valueAt(i)) {
InspectionItem selecteditem = listviewadapter
.getItem(selected.keyAt(i));
// Remove selected items following the ids
listviewadapter.remove(selecteditem);
}
}
// Close CAB
mode.finish();
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.cab_menu, menu);
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub
listviewadapter.removeSelection();
}
#Override
public boolean onPrepareActionMode(final ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
listviewadapter.toggleSelection(i);
final int checkedCount = inspectionList.getCheckedItemCount();
// Set the CAB title according to total checked items
activeMode.setTitle(checkedCount + " Selected");
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
/*
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==RESULT_OK){
if(requestCode == GET_VALUE){
if(data.getStringExtra("NEW_VALUE")!=null && data.getStringExtra("NEW_VALUE").length()>0){
addItems(data.getStringExtra("NEW_VALUE"));
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor edit = settings.edit();
edit.putString("myKey", TextUtils.join(",", inspections));
edit.commit();
}
}
}
} */
}
Basically, with this code, if I click on the trash-can action bar button, the CAB shows up, but I can't select any items on the list and proceed to delete them. Any help is greatly appreciated.
This is a tricky one. I used CheckedTextView's for multiple selections inside the list however when the list scrolls the adapter re-uses the old views and sometimes checks the wrong items. To overcome that I used an array of all the currently checked items, so the adapter can know which items should be checked.
Before going back to the original list you need to call notifyDataSetChanged(), which notifies to redrawn the visible views therefore uncheck/delete the selections (depends on what action you chose back at the CAB).
package com.example.simon.cabdelete;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Simon on 2014 Jul 18.
*/
public class MainActivity extends Activity {
private final static String TAG = "MainActivity";
MyAdapter mAdapter;
ListView mListView;
List<String> mListArray;
SparseBooleanArray mCheckedItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (ListView) findViewById(R.id.listView);
// Default list item click listener
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Do something on normal click
}
});
mCheckedItems = new SparseBooleanArray();
int size = 20;
mListArray = new ArrayList<String>(size);
for (int i=0; i<size; i++)
mListArray.add("Item "+i);
mAdapter = new MyAdapter(this, R.layout.list_item, mListArray);
mListView.setAdapter(mAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.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();
switch (id) {
case R.id.action_settings:
break;
case R.id.action_delete:
startActionMode(new ActionBarCallBack());
break;
}
return super.onOptionsItemSelected(item);
}
public class MyAdapter extends ArrayAdapter<String> {
List<String> items;
int itemResource;
LayoutInflater inflater;
public MyAdapter(Context ctx, int resource, List<String> objects) {
super(ctx, resource, objects);
this.items = objects;
this.itemResource = resource;
this.inflater = ((MainActivity)ctx).getLayoutInflater();
}
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
// (Re)Use convertView
if (convertView == null) {
convertView = inflater.inflate(itemResource, parent, false);
}
CheckedTextView checkView = (CheckedTextView) convertView;
checkView.setText(items.get(pos));
if (mCheckedItems.get(pos))
checkView.setChecked(true);
else
checkView.setChecked(false);
return convertView;
}
}
public class ActionBarCallBack implements ListView.OnItemClickListener,
ActionMode.Callback {
ActionMode actionMode;
AdapterView.OnItemClickListener previousListener;
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
Log.v(TAG, "Action mode started");
actionMode = mode;
mode.getMenuInflater().inflate(R.menu.cab_menu, menu);
previousListener = mListView.getOnItemClickListener();
mListView.setOnItemClickListener(this);
mCheckedItems = new SparseBooleanArray(mListView.getCount());
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
Log.v(TAG, "Deleting "+mCheckedItems.size()+" items");
for (int i= mCheckedItems.size()-1; i>=0; i--) {
int key = mCheckedItems.keyAt(i);
Log.v(TAG, "Removing array item # " + key);
mListArray.remove(key);
}
mode.finish();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
Log.v(TAG, "Exiting action mode.");
mListView.setOnItemClickListener(previousListener);
mCheckedItems.clear();
mAdapter.notifyDataSetChanged();
}
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
CheckedTextView checkView = (CheckedTextView) view;
boolean state = checkView.isChecked();
checkView.setChecked(!state);
if (!mCheckedItems.get(position))
mCheckedItems.put(position, true);
else
mCheckedItems.delete(position);
actionMode.setTitle(mCheckedItems.size() + " Items selected");
Log.v(TAG, "Action item # " + position +
" clicked. It's state now is " + state);
}
}
}
And here are my xml files create the whole look:
res/layout/activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="true"/>
<!-- Note that drawSelectorOnTop is important as it lets
the CheckedTextViews to be clicked in a normal way too-->
</RelativeLayout>
res/layout/list_item.xml:
<CheckedTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#drawable/list_selector"/>
res/drawable/list_selector.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/item_default" android:state_checked="false"/>
<item android:drawable="#color/item_checked" android:state_checked="true"/>
</selector>
res/values/colors.xml:
<resources>
<color name="item_default">#33B5E5</color>
<color name="item_checked">#0095CC</color>
</resources>

Android Switch widget force close

Trying to create a switch in android with default ON state and with OnCheckedChangeListener. But application is force closing. What is wrong? please help. New in android development.
package com.tiumca2013.smarthousecontrol;
import android.app.Activity;
import android.app.Fragment;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Switch;
import android.widget.Toast;
public class MainActivity extends Activity{
private Switch switch1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
switch1 = (Switch) findViewById(R.id.Switch1);
switch1.setChecked(true); // force close
switch1.setOnCheckedChangeListener(new OnCheckedChangeListener() // force close again
{
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
Toast.makeText(getApplicationContext(),"switch 1 ON",Toast.LENGTH_SHORT).show();
else
Toast.makeText(getApplicationContext(),"switch 1 OFF",Toast.LENGTH_SHORT).show();
}
});
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
#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 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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}

Categories

Resources