In my android application I would like my options menu to have a white background so that my icons show up better, I have seen many apps that had this but I am unable to figure out how to get this done.
The answers int his link will probably help you. This site gives you answer in many ways, for example using android:state_pressed=true and other options too(selected, focused) in your menu item will show your background of your item in white color.
How to change the background color of the options menu?
I'm not a fan of the standard options menu at all that's why I ALWAYS create a customized menu with ViewStubs. Just create a new layout where you design your menu bar, integrate it with ViewStub in your layout files and let the menu slide in.
Sample java code:
public boolean onKeyDown( int keyCode, KeyEvent event ) {
switch (keyCode) {
case KeyEvent.KEYCODE_MENU:
mMenuPanel = ( ( ViewStub ) findViewById( R.id.stub_onoption ) ).inflate();
// initialize buttons of your menu layout and define setOnClickListener()
if( !menuVisible ) {
constants.showPanel( this, mMenuPanel, true );
menuVisible = true;
} else {
constants.hidePanel( this, mMenuPanel, true );
menuVisible = false;
}
return true;
default:
break;
}
}
public static void hidePanel( Context context, View panel, boolean slideDown ) {
panel.startAnimation( AnimationUtils.loadAnimation( context, slideDown ? R.anim.slide_out : R.anim.slide_in_top ) );
panel.setVisibility( View.GONE );
}
public static void showPanel( Context context, View panel, boolean slideUp ) {
panel.startAnimation( AnimationUtils.loadAnimation( context, slideUp ? R.anim.slide_in : R.anim.slide_out_top ) );
panel.setVisibility( View.VISIBLE );
}
This way you'll be able to fully customize your menu bar (background buttons etc.)
Edit: This is just the rough idea how to do it. And if you're doing it for the first time it might be a little bit overweight just for changing the background color but You'll be able to use this concept later on in various occasions like different slide in effects, adjusting the menu design according to your application design, change location, size and many more things.
Furthermore this kind of concept can also be used for optional search bars, or in-app notifications (if you don't want to use a dialog). So it's definitely worth looking into it.
Related
I am using this tool to get a toggle button behavior, this is the library:
https://github.com/ceryle/SegmentedButton
I want the left and right buttons to have different colors when selected. When I change the color programmatically, it works fine except from inside the listener, any hin on why this would happen?
SegmentedButtonGroup toggle = dialogView.findViewById(R.id.my_toggle);
toggle.setSelectorColor(activity.getResources().getColor(R.color.green));
toggle.setRippleColor(activity.getResources().getColor(R.color.green));
toggle.setOnPositionChanged(new SegmentedButtonGroup.OnPositionChanged() {
#Override
public void onPositionChanged(int position) {
SegmentedButtonGroup toggle = dialogView.findViewById(R.id.my_toggle);
toggle.setSelectorColor(activity.getResources().getColor(R.color.red));
toggle.setRippleColor(activity.getResources().getColor(R.color.red));
}
});
I am also open to other implementations of this functionality, I am having a hard time with this...
I'm trying to disable all clickable items in the app bar layout when the opaque background appears after clicking the floating action button. But I also need to make sure that all the floating action buttons are all still clickable. I'm thinking maybe I can disable all items in the app bar programmatically?
How to achieve this?
UPDATE
Code to set fab visibility and animation. When the Fabs displayed, the tabs and toolbar finally disabled and unclickable. But i want to make my Fabs still clickable. How can i do this? Please advice. Thank you!
public void fabVisibility(){
if (isOpen){
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
fabActivity.startAnimation(fabClose);
textViewActivities.startAnimation(fabClose);
fabPost.startAnimation(fabClose);
textViewPosts.startAnimation(fabClose);
fabMedia.startAnimation(fabClose);
textViewMedia.startAnimation(fabClose);
fabPlus.startAnimation(fabRotateAntiClockwise);
fabActivity.setClickable(false);
fabPost.setClickable(false);
fabMedia.setClickable(false);
shadowView.setVisibility(View.INVISIBLE);
isOpen = false;
}else {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
fabActivity.startAnimation(fabOpen);
textViewActivities.startAnimation(fabOpen);
fabPost.startAnimation(fabOpen);
textViewPosts.startAnimation(fabOpen);
fabMedia.startAnimation(fabOpen);
textViewMedia.startAnimation(fabOpen);
fabPlus.startAnimation(fabRotateClockwise);
fabPlus.setEnabled(true);
fabActivity.setClickable(true);
fabActivity.setEnabled(true);
fabPost.setClickable(true);
fabPost.setEnabled(true);
fabMedia.setClickable(true);
fabMedia.setEnabled(true);
shadowView.setVisibility(View.VISIBLE);
isOpen = true;
}
}
To disable the user interaction you just need to add the following code
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
To get user interaction back you just need to add the following code
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
To disable action bar (app bar) buttons on clicking FAB icon, you could set a flag, let's say DisableAppBarButton.
Now call invalidateOptionsMenu() which will trigger onCreateOptionsMenu and will regenerate your menu.
Modify your onCreateOptionsMenu to disable the buttons.
if (DisableAppBarButton) {
menu.someItem(R.id.yourItem).setEnabled(false);
} else {
menu.someItem(R.id.yourItem).setEnabled(true);
}
Two options:
1 - You can set a view group to be disabled by recursively setting all of its children disabled. Example:
public static setEnabled(View view, boolean enabled) {
view.setEnabled(enabled);
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0; i < viewGroup.getChildCount(); i++) {
setEnabled(viewGroup.getChild(i), enabled);
}
}
}
Then in your code in response to the FAB showing or hiding:
ViewUtil.setEnabled(mAppBarLayout, true /* or false */);
2 - You can make the opaque background focusable and clickable to intercept clicks while it's overlayed over the app bar, while the FAB buttons that float above that background would still receive clicks.
Hope that helps!
I am trying to change the background color of my whole application through a settings page, I have searched for a long time and so far cannot find a solution.
So, inside the fragment I have a button, and it acts as a toggle. When clicking the background color changes as it should, from white to grey interchangeably.
Here is the logic for the button:
Button changeBGButton = (Button) view.findViewById(R.id.btn_change_bg);
changeBGButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (((MainActivity)getActivity()).bgWhite == true)
{
//White is true, set to grey
((MainActivity)getActivity()).bgWhite = false;
((MainActivity)getActivity()).bgGrey = true;
Toast.makeText(getActivity(), "Set is white to false, grey to true.", Toast.LENGTH_SHORT).show();
}
else if (((MainActivity)getActivity()).bgWhite == false && ((MainActivity)getActivity()).bgGrey == true)
{
//White is true, set to grey
((MainActivity)getActivity()).bgWhite = true;
((MainActivity)getActivity()).bgGrey = false;
Toast.makeText(getActivity(), "Set is white to true, grey to false.", Toast.LENGTH_SHORT).show();
}
}
});
The main activity, inside OnCreateView override method is responsible for changing the background color, and it does. Upon clicking the button it changes.
But...
When pressing the back button to return to the previous screen in the backstack the background becomes white, if I then go to the settings page again it is grey, and again changes to white on pressing back.
It is acting as if only the fragment has the background changed, but the layout contentLayout only exists on the mainLayout not the fragment.
I suspect during the calling of the Fragment Lifecycle Methods the background is being reset, But I do not know how to make it persist as no instance is saved on the back button pressed.
Anyway. Here is the logic that changes the background, including the overriding method:
#Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs)
{
if (contentMain != null) //Only do this if we have a hope at not crashing the application/
if (bgWhite == true && bgGrey == false)
{
contentMain.setBackgroundColor(Color.parseColor("#FFFFFF"));
}
else if (bgGrey == true && bgWhite == false)
{
contentMain.setBackgroundColor(Color.parseColor("#888888"));
}
return super.onCreateView(parent, name, context, attrs);
}
I have tried to do it inside of the OnBackstackChangeListener too but the same result is experienced. Please help me out.
Cheers.
The problem is a bit ambiguous, but by what i think the problem is mainly because the color you are setting is from the onCreateView() method of your fragment, if the contentMain layout in resident on the activity which holds the fragments then you can create a method on that activity that change the color from the activity rather than the onCreateView of the fragment.
Thus you button click will look like this::
(MainActivity)getActivity().changeBgColor(bgGrey);
so the changes that you make here are done through the activity which controls all the fragments rather than the fragment itself.
Hope that help, good luck.
This is a short question:
I'm trying to force the action bar (used by a Toolbar) to use LTR alignment. I've succeeded making the layout itself use LTR, but not the "up" button (as I've done here, before Toolbar was introduced) .
It seems this view doesn't have an ID, and I think using getChildAt() is too risky.
Can anyone help?
The answer
Here's one way I've found to solve this, based on this answer .
I made it so that it is guarranteed to find only the "up" button, and whatever it does, it will revert back to the previous state it was before.
Here's the code:
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public boolean onCreateOptionsMenu(final Menu menu)
{
// <= do the normal stuff of action bar menu preparetions
if(VERSION.SDK_INT>=VERSION_CODES.JELLY_BEAN_MR1&&getResources().getConfiguration().getLayoutDirection()==View.LAYOUT_DIRECTION_RTL)
{
final ArrayList<View> outViews=new ArrayList<>();
final CharSequence previousDesc=_toolbar.getNavigationContentDescription();
for(int id=0;;++id)
{
final String uniqueContentDescription=Integer.toString(id);
_toolbar.findViewsWithText(outViews,uniqueContentDescription,View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if(!outViews.isEmpty())
continue;
_toolbar.setNavigationContentDescription(uniqueContentDescription);
_toolbar.findViewsWithText(outViews,uniqueContentDescription,View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty())
if (BuildConfig.DEBUG)
throw new RuntimeException(
"You should call this function only when the toolbar already has views");
else
break;
outViews.get(0).setRotation(180f);
break;
}
_toolbar.setNavigationContentDescription(previousDesc);
}
//
return super.onCreateOptionsMenu(menu);
}
It seems this view doesn't have an ID
You're right, the navigation view is created programmatically and never sets an id. But you can still find it by using View.findViewsWithText.
View.findViewsWithText comes with two flags:
View.FIND_VIEWS_WITH_TEXT
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION
The navigation view's default content description is "Navigate up" or the resource id is abc_action_bar_up_description for AppCompat and action_bar_up_description for the framework's, but you can easily apply your own using Toolbar.setNavigationContentDescription.
Here's an example implementation:
final Toolbar toolbar = ...;
toolbar.setNavigationContentDescription("up");
setActionBar(toolbar);
final ArrayList<View> outViews = Lists.newArrayList();
toolbar.findViewsWithText(outViews, "up", View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
outViews.get(0).setRotation(180f);
Results
I would like to dynamically change the "home" icon in the ActionBar. This is easily done in v14 with ActionBar.setIcon(...), but I can't find anyway to accomplish this in previous versions.
If your actionbar works like Sherlock and is based on menu items, this is my solution:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem switchButton = menu.findItem(R.id.SwitchSearchOption);
if(searchScriptDisplayed){
switchButton.setIcon(R.drawable.menu_precedent);
}else{
switchButton.setIcon(R.drawable.icon_search);
}
return super.onPrepareOptionsMenu(menu);
}
If you are using the ActionbarCompat code provided by google, you can access the home icon via the ActionBarHelperBase.java class for API v4 onwards.
//code snippet from ActionBarHelperBase.java
...
private void setupActionBar() {
final ViewGroup actionBarCompat = getActionBarCompat();
if (actionBarCompat == null) {
return;
}
LinearLayout.LayoutParams springLayoutParams = new LinearLayout.LayoutParams(
0, ViewGroup.LayoutParams.MATCH_PARENT);
springLayoutParams.weight = 1;
// Add Home button
SimpleMenu tempMenu = new SimpleMenu(mActivity);
SimpleMenuItem homeItem = new SimpleMenuItem(tempMenu,
android.R.id.home, 0, mActivity.getString(R.string.app_name));
homeItem.setIcon(R.drawable.ic_home_ftn);
addActionItemCompatFromMenuItem(homeItem);
// Add title text
TextView titleText = new TextView(mActivity, null,
R.attr.actionbarCompatTitleStyle);
titleText.setLayoutParams(springLayoutParams);
titleText.setText(mActivity.getTitle());
actionBarCompat.addView(titleText);
}
...
You should be able to modify the code to the home button accessible to the activities that extend ActionBarActivity and change it that way.
Honeycomb seems a little harder and it doesn't seem to give such easy access. At a guess, its id should also be android.R.id.home so you may be able to pull that from the view in ActionBarHelperHoneycomb.java
I would say you do something like this :
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_menu_drawer);
see the link How to change the icon actionBarCompat
The ActionBar will use the android:logo attribute of your manifest, if one is provided. That lets you use separate drawable resources for the icon (Launcher) and the logo (ActionBar, among other things).