Android UI to Enter List Edit Mode - android

I have a short list of items in my activity. I want to add a button somewhere in the UI to switch to edit mode for the list of items. I'm new to Android programming and even to using Android devices. I'm accustomed to iOS. In an iOS table, there is usually an "Edit" button in the top right of the navigation bar. What is the standard way in Android to switch to edit mode in a list? (Is there a standard way?)
When in edit mode, I plan to show edit (e.g. pencil) and delete (e.g. 'X') buttons on the right side of each list item's view.
I don't think it is related but just in case...I'm not using RecyclerView or anything fancy. Just LinearLayout. The list is so short I don't think there is a performance reason to use a recycler. Is there any other reason to use a RecyclerView?
Thanks!

You need to action mode. Example:
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends Activity {
ActionMode actionMode;
final String LOG_TAG = "myLogs";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onClick(View v) {
if (actionMode == null)
actionMode = startActionMode(callback);
else
actionMode.finish();
}
private ActionMode.Callback callback = new ActionMode.Callback() {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.context, menu);
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Log.d(LOG_TAG, "item " + item.getTitle());
return false;
}
public void onDestroyActionMode(ActionMode mode) {
Log.d(LOG_TAG, "destroy");
actionMode = null;
}
};
// ...
}

Related

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
}

Contextual action bar not showing sellection

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.

Error:(9, 30) error: package android.support.v4.app does not exist

I'm using Studio 0.8.9
I have an android-sdks\extras\android\support\v4\android-support-v4.jar
but I still run into the import issue.
I'm using NavUtils.navigateupfromsametask method.
what I'm trying to achieve is simply to use the back button to get to my previous activity.
is it the right way of doing?
when I'm using my email app (for ex yahoo) I'm using the back button to get back to my inbox when I'm viewing an email.
how do they do it? using activities and the back button?
I'm using the standard code:
package com.example.bernard.test;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.util.NavigableMap;
import android.support.v4.app.NavUtils;
public class Statistic extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_statistic);
getActionBar().setDisplayHomeAsUpEnabled(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.statistic, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id)
{
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onBackPressed(){
super.onBackPressed();
}
}

Creating Options Menus for Google Glass

Going by the guidelines and conventions in the StopWatch GDK example, I cannot get the MenuOption to open.
My app compiles and able to output the embedded log statement of ""####TEST", but no OptionsMenu appears.
https://developers.google.com/glass/develop/gdk/ui/immersion-menus
This is the method in the Android API for menu's.
openOptionsMenu();
I'm basing the code off of stopwatch's conventions:
/*
*
* Menu Code
*/
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
#Override
public boolean onKeyDown(int keycode, KeyEvent event) {
if (keycode == KeyEvent.KEYCODE_DPAD_CENTER) {
openOptionsMenu();
Log.v("####","TEST");
return true;
}
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Implement if needed
return false;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection. Menu items typically start another
// activity, start a service, or broadcast another intent.
switch (item.getItemId()) {
case R.id.stop:
//startActivity(new Intent(this, StopStopWatchActivity.class));
Log.v("####","HI");
return true;
case R.id.read_aloud:
Log.v("####","READ_ALOUD");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//open the optionsMenu to make sure
#Override
public void openOptionsMenu() {
super.openOptionsMenu();
}
the XML for menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/read_aloud"
android:title="#string/read_aloud"
android:icon="#drawable/ic_launcher"/>
<item
android:id="#+id/stop"
android:title="#string/stop"
android:icon="#drawable/ic_launcher"/>
</menu>
edit: I discovered what my issue was. I commented out the prepared option which was returning false, which caused my options to not engaged.
Here in reference is a good example to do it properly.
Thanks #w9jds for his help.
I can't find what the issue was in my code, but here is a working example solutions with the correct menu creation and one tap.
https://github.com/w9jds/GlassMenuExample
What the program does is show a glass app that renders a hello world card. On Tap the card creates an options menu that has the 'share' option.
This functionality is a lot similar to how cards work on the timeline.
Menu - Main.Xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/share_menu_item"
android:title="#string/share_label"
android:icon="#drawable/ic_share_50"/>
</menu>
Main Activity
package com.example.glassmenuexample;
import com.google.android.glass.app.Card;
import com.google.android.glass.media.Sounds;
import com.google.android.glass.touchpad.Gesture;
import com.google.android.glass.touchpad.GestureDetector;
import android.media.AudioManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
public class MainActivity extends Activity
{
private GestureDetector mGestureDetector;
private AudioManager maManager;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//initialize the audio manager
maManager = (AudioManager) getSystemService(this.AUDIO_SERVICE);
//create gesture listener
mGestureDetector = createGestureDetector(this);
//create a new card for the view
Card cView = new Card(this);
//set the text of the card to the hello world string
cView.setText(R.string.hello_world);
//set the card as the content view
setContentView(cView.toView());
}
#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;
}
private GestureDetector createGestureDetector(Context context)
{
GestureDetector gdDetector = new GestureDetector(context);
//Create a base listener for generic gestures
gdDetector.setBaseListener( new GestureDetector.BaseListener()
{
#Override
public boolean onGesture(Gesture gesture)
{
if (gesture == Gesture.TAP)
{
//play the tap sound
maManager.playSoundEffect(Sounds.TAP);
//open the menu
openOptionsMenu();
return true;
}
return false;
}
});
return gdDetector;
}
#Override
public boolean onGenericMotionEvent(MotionEvent event)
{
if (mGestureDetector != null)
return mGestureDetector.onMotionEvent(event);
return false;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle item selection. Menu items typically start another
// activity, start a service, or broadcast another intent.
switch (item.getItemId())
{
case R.id.share_menu_item:
//do something on menu item click
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}

How to add/remove menu items at runtime in ICS?

I'm using the ActionBarCompat sample that comes with the SDK. My activity used to have menu items that would change based on the state of the activity. I would modify the menu like so in onPrepareOptionsMenu():
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
if (some condition) {
menu.add(...);
}
...
}
In ICS however, I believe we're supposed to modify menu items by calling invalidateOptionsMenu() and then our onCreateOptionsMenu() is called again. Here we can remove menu items (not add them). So then we might end up with something like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (SDK >= 11) {
// full menu is reloaded from xml every time we
// called invalidateOptionsMenu(), so we have a
// fresh menu here again.
}
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (SDK >= 11) {
// we can remove items depending on our state,
// but not add any, that's ok.
}
else {
// we only have our original menu instance here,
// so if we previously had called menu.remove(),
// we need to call menu.add() here:
if (foo == true) {
menu.remove(R.id.menu_item_foo);
} else {
menu.add(R.id.menu_item_foo, ...);
}
}
}
This seems a bit awkward,
Thanks
Demo project
https://github.com/AlienAsRoger/CourtDeadlines
This is how i solved it:
In ActionBarHelperBase.java of actionbarcompat project
...
private View addActionItemCompatFromMenuItem(final MenuItem item) {
final int itemId = item.getItemId();
....
The creator of this class copy properties of object, but didn't copy the id of item, so it is impossible to find it later with fiven id.
So i added it in that method:
...
actionButton.setId(itemId);
...
and in the same class i just use:
#Override
public void hideMenuItemById(int id, boolean show){
getActionBarCompat().findViewById(id).setVisibility(show? View.VISIBLE: View.GONE);
}
Hope it helps You.
UPDATES:
in ActionBarActivity from ActionBarCompat sample:
package com.chess.ui.activities;
import actionbarcompat.ActionBarActivity;
import actionbarcompat.ActionBarHelper;
import android.app.ActionBar;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.SearchView;
import com.chess.R;
import com.chess.lcc.android.LccHolder;
public abstract class CoreActivityActionBar2 extends ActionBarActivity {
protected boolean showActionSearch;
protected boolean showActionSettings;
protected boolean showActionNewGame;
protected boolean showActionRefresh;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && getActionBar() != null) {
getActionBar().setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP
| ActionBar.DISPLAY_USE_LOGO
| ActionBar.DISPLAY_SHOW_HOME
| ActionBar.DISPLAY_SHOW_TITLE);
}
}
#Override
protected void onStart() {
if (HONEYCOMB_PLUS_API) {
adjustActionBar();
}
super.onStart();
}
#Override
protected void onResume() {
super.onResume();
if (!HONEYCOMB_PLUS_API) {
adjustActionBar();
}
}
private void adjustActionBar() {
getActionBarHelper().showMenuItemById(R.id.menu_settings, showActionSettings);
getActionBarHelper().showMenuItemById(R.id.menu_new_game, showActionNewGame);
getActionBarHelper().showMenuItemById(R.id.menu_refresh, showActionRefresh);
getActionBarHelper().showMenuItemById(R.id.menu_search, showActionSearch);
getActionBarHelper().showMenuItemById(R.id.menu_singOut, LccHolder.getInstance(this).isConnected());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.sign_out, menu);
getActionBarHelper().showMenuItemById(R.id.menu_singOut, LccHolder.getInstance(this).isConnected(), menu);
getActionBarHelper().showMenuItemById(R.id.menu_search, showActionSearch, menu);
getActionBarHelper().showMenuItemById(R.id.menu_settings, showActionSettings, menu);
getActionBarHelper().showMenuItemById(R.id.menu_new_game, showActionNewGame, menu);
getActionBarHelper().showMenuItemById(R.id.menu_refresh, showActionRefresh, menu);
if (HONEYCOMB_PLUS_API) {
// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
backToHomeActivity();
break;
case R.id.menu_settings:
startActivity(new Intent(this, PreferencesScreenActivity.class));
break;
}
return super.onOptionsItemSelected(item);
}
public ActionBarHelper provideActionBarHelper() {
return getActionBarHelper();
}
}
where showActionSettings is a boolean flag to switch visibility

Categories

Resources