In my app I need to use the ActionMode.
I have followed several Guides and Tutorials (https://medium.com/asos-techblog/style-actionmode-on-android-5e613fa77c32, https://developer.android.com/guide/topics/ui/menus e.g.) on implementing my Contextual Action Menu but as you can see in this image:
https://i.stack.imgur.com/ag2Mp.jpg
There is part of the titleBar still visible on the bottom. My question is if there is anything i can do to change this behaviour.
I also tried to change the style of my ActionModeBar but when i change the styling it becomes invisible (only showing the icons) and the titlebar is completely visible.
I have not made any changes to the ActionMode except the menu that contains the buttons:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/stopCab"
android:title="Stop contextual action bar"
app:showAsAction="ifRoom"
android:icon="#drawable/ic_baseline_cancel_24"/>
<item android:id="#+id/deleteCab"
android:title="Delete selected items"
app:showAsAction="ifRoom"
android:icon="#drawable/ic_delete_white_24dp"/>
</menu>
Initializing the ActionMode:
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.contextual_action_bar_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.deleteCab:
//TODO: do something
return true;
case R.id.stopCab:
//TODO: do something
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode actionMode) {
FieldChooserActivity.this.actionMode = null;
}
};
And starting the ActionMode:
FieldChooserActivity.this.actionMode = startActionMode(FieldChooserActivity.this.actionModeCallback);
In my Style the AppTheme parent is Theme.AppCompat.Light.DarkActionBar
And each Activity has
android:theme="#style/AppTheme.NoActionBar">
in AndroidManifest.
Maybe this is the fault why i cant change the style without the ActionMode becoming invisible.
I hope someone can help me with this matter and thanks in advance!
I found a solution that fixed my problem (where the ActionMode bar doesn't cover the Toolbar).
As i looked at the layout of my activity i saw that in the Toolbar is a height attribute called '?attr/actionBarSize':
<androidx.appcompat.widget.Toolbar
android:id="#+id/fieldChooserToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay">
I then added the height to a custom style for my ActionMode:
<style name="ActionModeTheme" parent="AppTheme">
<item name="windowActionModeOverlay">true</item>
<item name="actionModeCloseDrawable">#drawable/ic_delete_white_24dp</item>
<item name="actionMenuTextColor">#android:color/white</item>
<item name="height">?attr/actionBarSize</item>
<item name="background">#color/colorSecondary</item>
<item name="android:src">#drawable/ic_baseline_close_24</item>
</style>
The last part was that i added following line to my AppTheme-styling:
<item name="actionModeStyle">#style/ActionModeTheme</item>
And then it worked!
The second problem where my ActionMode bar was invisible was most likely caused by adding the actionModeStyling to the AppTheme.NoActionBar.
Related
I'm trying to use the default android action bar with a custom view:
<style name="ActionBar" parent="android:Widget.Material.ActionBar.Solid">
<item name="android:displayOptions">showCustom</item>
<item name="android:customNavigationLayout">#layout/customNavigationLayout</item>
</style>
The options menu contains a single item which should always show with text:
<item
android:id="#+id/action_cancel"
android:showAsAction="always|withText"
android:title="#string/action_cancel" />
Now I'm having the issue with the selectable background, which is still the size of an action icon:
How can I setup the action bar to apply a selectable background which fills the whole box of the item?
You can try setting the android:actionBarItemBackground attribute in styles, like so:
<style name="AppTheme" parent="android:Theme.Material">
...
<item name="android:actionBarItemBackground">?android:selectableItemBackground</item>
</style>
Use one of the following solutions:
Solution 1:
Add <item name="actionButtonStyle">#style/ActionButtonStyle</item> to your base application theme with for exmaple:
<style name="ActionButtonStyle" parent="android:Widget.Material.Button">
<item name="android:textColor">#android:color/black</item>
<item name="android:textSize">16sp</item>
<item name="android:background">#drawable/button_background</item>
</style>
and
button_background
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#color/colorAccent"/>
<item android:state_focused="true"
android:drawable="#color/colorPrimaryDark"/>
<item android:drawable="#color/colorPrimary"/>
</selector>
Solution 2:
Use menuItem.setActionView to apply a custom layout to your menu item as follows:
layout_action_cancel (custom menu item layout):
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"
android:id="#+id/b_action_cancel"
android:gravity="center"
android:background="#drawable/button_background">
</Button>
Then in your onCreateOptionsMenu apply the custom Layout to the menu
item:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu, menu);
LayoutInflater layoutInflater = getLayoutInflater();
View layout = layoutInflater.inflate(R.layout.layout_action_cancel, null, false);
menu.getItem(0).setActionView(layout);
return super.onCreateOptionsMenu(menu);
}
and in onPrepareOptionsMenu set an OnClick Listener (replacing the
onOptionsItemSelected)
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
View layout = menu.getItem(0).getActionView();
if(layout instanceof Button){
Button b_action_cancel = layout.findViewById(R.id.b_action_cancel);
b_action_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//your code
}
});
}
return super.onPrepareOptionsMenu(menu);
}
You can try applying drawable withe selected and normal state at menu item property :
<item
android:id="#+id/action_cancel"
android:showAsAction="always|withText"
android:title="#string/action_cancel"
android:icon="#drawable/mybuttonbackground" />
Okay, so i got a small problem that i really don't know how to fix this.
So i have an application where i use my own style for an Action Bar
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">true</item>
<item name="actionBarStyle">#style/AppTheme.ActionBar</item>
<item name="android:textColorSecondary">#color/action_bar_bg</item>
</style>
<style name="AppTheme.ActionBar" parent="Widget.AppCompat.ActionBar">
<item name="height">30dp</item>
<item name="background">#color/action_bar_bg</item>
</style>
</resources>
The menu that is displayed
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/sortByStatus"
android:title="#string/sort_by_status"
app:showAsAction="never" />
<item android:id="#+id/sortByName"
android:title="#string/sort_by_name"
app:showAsAction="never" />
<item android:id="#+id/sortByCompany"
android:title="#string/sort_by_company"
app:showAsAction="never" />
</menu>
This works great for almost all places, except when i try to display my options menu. I have added the options menu and the handler for it, but when i click on the options menu then the default top icons (from the notification bar) also shows inside my options menu, and i don't want those to show there. It also starts showing the default bottom navigation buttons for Sony phones.
Enabling the menu from onResume
#Override
public void onResume() {
super.onResume();
AppCompatActivity appCompatActivity = (AppCompatActivity) getActivity();
if (appCompatActivity != null && appCompatActivity.getSupportActionBar() != null)
appCompatActivity.getSupportActionBar().setTitle(getResources().getString(R.string.presense_status));
setHasOptionsMenu(true);
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
and then the menu onCreate
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_presense_status, menu);
}
and then the handler for selected item
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getActivity().getFragmentManager().popBackStackImmediate();
break;
case R.id.sortByStatus:
if (null != mDataSource) {
// update data list
reloadData();
}
break;
case R.id.sortByName:
if (null != mDataSource) {
// update data list
reloadData();
}
break;
case R.id.sortByCompany:
if (null != mDataSource) {
// update data list
reloadData();
}
break;
default:
super.onOptionsItemSelected(item);
}
return true;
}
I really can't see where the problem is coming from or how to remove it so that this does not happen. This happens inside a Fragment that is started by my main Activity, meaning i only have one Activity that spawns different fragments for the different in-app tasks.
Any help or thought would be greatly appreciated.
I still don't really know why the notification bar was affected by what i did, but forcing the application to fullscreen in this view stops the problem, so i guess that's an acceptable workaround.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
I wanted to create an option menu which shows up similar to Whatsapp even if the device has its own "hardware" option button. The solution I found online worked just fine until I wanted to add another action to the Bar.
Menu:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:title=""
android:id="#+id/addViewedMovie"
android:icon="#mipmap/ic_add_to_queue_black_24px"
android:showAsAction="always"
></item>
<item
android:title=""
android:id="#+id/menu_overflow"
android:icon="#mipmap/ic_more_vert_white_48dp"
app:showAsAction="always">
<menu>
<item
android:id="#+id/show_settings"
app:showAsAction="never"
android:title="#string/setttings"/>
<item
android:id="#+id/show_help"
app:showAsAction="never"
android:title="#string/help"/>
<item
android:id="#+id/show_about"
app:showAsAction="never"
android:title="#string/about"/>
</menu>
</item>
</menu>
And this in my MainActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
With this the app forces the addViewedMovie Action into an Overflow-Menu. Does anyone know how to prevent this?
Try this code and tell me if its work.. you should use app:showAsAction not android:showAsAction also you do not need to use submenu to show 3 dots.. just below code works fine also show 3 dots
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:title="Movie"
android:id="#+id/addViewedMovie"
android:icon="#mipmap/ic_add_to_queue_black_24px"
app:showAsAction="always"/>
<item
android:id="#+id/show_settings"
app:showAsAction="never"
android:title="#string/setttings"/>
<item
android:id="#+id/show_help"
app:showAsAction="never"
android:title="#string/help"/>
<item
android:id="#+id/show_about"
app:showAsAction="never"
android:title="#string/about"/>
</menu>
Create a folder name Menu in your res folder.
menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/search"
android:icon="#drawable/ic_launcher"
myapp:showAsAction="ifRoom" />
<item android:id="#+id/abc"
android:title="ABC" />
<item android:id="#+id/abc1"
android:title="ABC1" />
<item android:id="#+id/abc2"
android:title="ABC2" />
</menu>
In java file put this:-
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
return true;
case R.id.abc:
return true;
case R.id.abc1:
return true;
case R.id.abc2;
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Simple.
use app instead of android as app is for design support library.
And so, in Gradle build in dependencies, you must have: compile com.android.support:design..... like that. But, I have seen that you already used it below. So,
Just use: app:showAsAction="never" instead of android:showAsAction="always" in your addViewedMovie item.
Remember: never means it will be on overflow menu item. always means is will show in action bar.
If you are using in a fragment, add below line in the onCreate
setHasOptionsMenu(true);
And two more functions
#Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
Inflate your views in the above method. Listen to the action in the below one.
#Override public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
Im trying to do a menu with only one icon, but instead of that icon, i am getting the typican three dots, and inside my option. So, i only want one icon. That is my XML code:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.bartek.gestionpea.MainActivity">
<item
android:id="#+id/ayuda"
android:icon="#android:drawable/ic_dialog_info"
android:title="Ayuda"
app:showAsAction="ifRoom"/>
</menu>
Here goes my class:
public class MainActivity extends Activity {
PeniaSQLiteHelper usdbh;
private SQLiteDatabase db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getActionBar().setTitle("GESTION");
Button btnCrearPena = (Button) findViewById(R.id.btncrearpena);
btnCrearPena.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, CrearNueva.class);
startActivity(i);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_principal, menu);
return true;
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case R.id.ayuda:
return true;
}
return super.onMenuItemSelected(featureId, item);
}
}
You are using some things for the native action bar (e.g., inheriting from Activity) and some things for the appcompat-v7 action bar backport (e.g., app:showAsAction). Choose one and stick with it:
If you wish to use the native action bar, use android:showAsAction
If you wish to use the appcompat-v7 action bar backport, inherit from AppCompatActivity (in the latest appcompat-v7) or ActionBarActivity (for prior versions of appcompat-v7)
Since you use the standard Activity, try this:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/ayuda"
android:icon="#android:drawable/ic_dialog_info"
android:title="Ayuda"
android:showAsAction="always" />
</menu>
You can modify the app theme (in themes.xml):
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:actionOverflowButtonStyle">#style/MyActionButtonOverflow</item>
</style>
<!-- Style to replace actionbar overflow icon. set item 'android:actionOverflowButtonStyle' in AppTheme -->
<style name="MyActionButtonOverflow" parent="android:style/Widget.Holo.Light.ActionButton.Overflow">
<item name="android:src">#drawable/your_icon_here</item>
<item name="android:background">?android:attr/actionBarItemBackground</item>
<item name="android:contentDescription">"options"</item>
</style>
More info here
Note that when using appcompat themes, you sometimes need to set xml attibutes twice:
once with and once without the android namespace
<item name="android:windowNoTitle">true</item>
<item name="windowNoTitle">true</item>
I'm building an Android app using the AppCompat_v7 library and I'm having troubles with the action bar.
I have an AppBarActivity which extends ActionBarActivity - I'm using the same actionbar for all of my activities. MainActivity extends AppBarActivity. I've defined four actionbar icons, two of which I'd like to be displayed at a time. I've been careful to define my own namespace, ie. app:showAsAction="always"/>
In my app, I toggle the visibility of these icons in onPrepareOptionsMenu()
MenuItem contactOn = menu.findItem(R.id.contact_toggle_button_on);
MenuItem contactOff = menu.findItem(R.id.contact_toggle_button_off);
contactOn.setVisible(!useContacts);
contactOn.setEnabled(!useContacts);
contactOff.setVisible(useContacts);
contactOff.setEnabled(useContacts);
Do I need to specify a namespace here somehow? Because it doesn't seem that these methods are doing anything, except, curiously, rearranging their names in the overflow list. Also, only three of the four buttons show up there, which I don't understand either but I expect that's a different problem.
UPDATE: posting code & xml
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inf = new MenuInflater(this);
inf.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem contactOn = menu.findItem(R.id.contact_toggle_button_on);
MenuItem contactOff = menu.findItem(R.id.contact_toggle_button_off);
contactOn.setVisible(!useContacts);
contactOn.setEnabled(!useContacts);
contactOff.setVisible(useContacts);
contactOff.setEnabled(useContacts);
MenuItem locationOn = menu.findItem(R.id.location_toggle_button_on);
MenuItem locationOff = menu.findItem(R.id.location_toggle_button_off);
locationOn.setVisible(useLocation);
locationOn.setEnabled(useLocation);
locationOff.setVisible(!useLocation);
locationOff.setEnabled(!useLocation);
return true;
}
And the XML
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.skortchm.strangerapp.MainActivity" >
<!-- Contacts Toggle, should appear as action button -->
<item
android:id="#+id/contact_toggle_button_on"
android:icon="#drawable/ic_action_call"
android:title="#string/contact_toggle_on"
app:showAsAction="always"/>
<item
android:id="#+id/contact_toggle_button_off"
android:icon="#drawable/ic_action_call_off"
android:title="#string/contact_toggle_off"
app:showAsAction="always"/>
<!-- Location Toggle, should appear as action button -->
<item
android:id="#+id/location_toggle_button_on"
android:icon="#drawable/ic_action_location_searching"
android:title="#string/location_toggle_on"
app:showAsAction="always"/>
<item
android:id="#+id/location_toggle_button_off"
android:icon="#drawable/ic_action_location_off"
android:title="#string/location_toggle_off"
app:showAsAction="always"/>
<!-- Settings, should always be in the overflow -->
<!-- Add gear icon here -->
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never"/>
</menu>
You need to use getMenuInflater to inflate the menu.
You are creating an instance for MenuInflater, that is not right . you have to use the instance associated with the Activity
Change your onCreateOptionsMenu as
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}