I try to make android toolbar transition from recyclerview item name to toolbar title (text). I create it like Alex Lockwood recommendation. In appcompat-v7:22 all works fine, when I update to appcompat-v7:23 transition does't work.
Does somebody know whats happen with appcompat-v7:23?
My code (with appcompat-v7:22 all works fine):
private void startDataActivity(Activity activity, View toolbar,
Category category) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
View decor = activity.getWindow().getDecorView();
View statusBar = decor.findViewById(android.R.id.statusBarBackground);
View navBar = decor.findViewById(android.R.id.navigationBarBackground);
List<Pair> participants = new ArrayList<>(3);
participants.add(new Pair<>(toolbar, activity.getString(R.string.transition_toolbar)));
addNonNullViewToTransitionParticipants(statusBar, participants);
addNonNullViewToTransitionParticipants(navBar, participants);
ActivityOptions sceneTransitionAnimation = ActivityOptions
.makeSceneTransitionAnimation(activity,
participants.toArray(new Pair[participants.size()]));
final Bundle transitionBundle = sceneTransitionAnimation.toBundle();
activity.startActivity(ShowCategoryActivity.getStartIntent(activity,
category.getId()), transitionBundle);
} else {
activity.startActivity(ShowCategoryActivity.getStartIntent(activity,
category.getId()));
}
}
Related
i recently faced a pretty strange issue with activity transitions. I'm trying to make a slide in transition with exclusions, which are native status bar, native navigation bar and my custom bottom navigation bar. So i created piece of code based on documentation (link here) which in most cases works pretty well, but sometimes all views in the activity have visibility set as View.INVISIBLE (i know that fact from Layout Inspector).
So, i have activity A and activity B. Then i'm navigating from activity A to B via startActivity(). When i click back on activity B sometimes transition works fine, but in some cases all views on activity A (except bottom navigation bar, which was excluded from transition) are set to View.INVISIBLE
My code:
Activity A :
Intent i = new Intent(this, ActivityB.class);
Transition slide = new Slide(Gravity.RIGHT);
slide.excludeTarget(findViewById(R.id.bottom_navigation_bar), true);
slide.excludeTarget(findViewById(android.R.id.navigationBarBackground), true);
slide.excludeTarget(findViewById(android.R.id.statusBarBackground), true);
getWindow().setExitTransition(slide);
startActivity(i,
ActivityOptionsCompat.makeSceneTransitionAnimation(this, createPairs()).toBundle());
private Pair[] createPairs() {
Pair[] pairs = new Pair[2];
pairs[0] = Pair.create(findViewById(android.R.id.statusBarBackground), Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME);
pairs[1] = Pair.create(findViewById(android.R.id.navigationBarBackground), Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME);
return pairs;
}
Activity B:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
setContentView(R.layout.activity);
final View decor = getWindow().getDecorView();
decor.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
decor.getViewTreeObserver().removeOnPreDrawListener(this);
Transition fade = new Fade();
fade.excludeTarget(findViewById(R.id.bottom_navigation_bar), true);
fade.excludeTarget(findViewById(android.R.id.navigationBarBackground), true);
fade.excludeTarget(findViewById(android.R.id.statusBarBackground), true);
getWindow().setEnterTransition(fade);
return true;
}
});
Image shows versions 7.1 and 4.4,the top two images are the default ones, to the bottom two we added some customization ,see description
What I want to achieve is that on Android 4.4 the hamburger button to have a space in front so that it doesn't start right from the edge of the action bar/screen(much like on 7.1,see screenshot).Can I add a padding to the hamburger button?I am using Xamarin.Forms with Xamarin Studio.
The problem seems to be worse when we add a custom view to the action bar,it sets the hamburger button more to the left I think,and doesn't entirely fit in the screen and somehow "cuts it off".
This is the relevant part of how we add the custom view to the action bar.We do this with a custom NavigationRenderer and we do the UI from code.
actionBar.SetDisplayShowCustomEnabled(true);
LinearLayout linearLayout = new LinearLayout(activity);
linearLayout.SetGravity(GravityFlags.CenterVertical);
LinearLayout.LayoutParams textViewParameters = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.MatchParent);
switch (activity.Resources.DisplayMetrics.DensityDpi)
{
case DisplayMetricsDensity.Xhigh:
textViewParameters.RightMargin = (int)(48 * activity.Resources.DisplayMetrics.Density);
break;
case DisplayMetricsDensity.Xxhigh:
textViewParameters.RightMargin = (int)(64 * activity.Resources.DisplayMetrics.Density);
break;
default:
textViewParameters.RightMargin = (int)(48 * activity.Resources.DisplayMetrics.Density);
break;
}
TextView modelTitle = new TextView(activity);
modelTitle.Text = view;
modelTitle.Gravity = GravityFlags.Center;
modelTitle.TextSize = 17f;
Typeface type = Typeface.CreateFromAsset(Forms.Context.Assets, "abc.ttf");
modelTitle.SetTypeface(type, TypefaceStyle.Bold);
modelTitle.SetTextColor(Android.Graphics.Color.White);
linearLayout.AddView(modelTitle, textViewParameters);
ActionBar.LayoutParams actionbarParams =
new ActionBar.LayoutParams(ActionBar.LayoutParams.MatchParent, ActionBar.LayoutParams.MatchParent);
activity.ActionBar.SetCustomView(linearLayout, actionbarParams);
I also tried to change the hamburger icon to a drawable(I added a space before the same hamburger icon,and it would do the job),but once I navigate back to the page using the back button (from the same action bar),my icon is replaced by the default hamburger button again.
I would appreciate any help.Thank you!
Edit:
public class MainView : MasterDetailPage
{
public MainView(parameter){
......
sideMenu = new CustomContentPage();//my custom Content Page with listview items
base.MasterBehavior = MasterBehavior.Split;
sideMenu.Padding = new Thickness(0, Device.OnPlatform(50, 0, 0), 0, 0);
Master = sideMenu;
.......
}
...
}
public class App : Application
{
private MainView lcMenu = null;
.....
if (lcMenu == null)
{
MustSet = true;
lcMenu = new MainView(parameter);
lcMenu.RequestPage += LcMenu_RequestPage;
}
....
MainPage = lcMenu;
}
This is the relevant part of how we add the custom view to the action bar.We do this with a custom NavigationRenderer and we do the UI from code.
Seems that you're creating your own master detail instead of using the MasterDetailPage of XF? Not sure, but I think you went the wrong direction, for setting the padding of hamburger button we need to customize MasterDetailPage.
I also tried to change the hamburger icon to a drawable(I added a space before the same hamburger icon,and it would do the job),but once I navigate back to the page using the back button (from the same action bar),my icon is replaced by the default hamburger button again.
As I said, we can customize the MasterDetailPage, in the renderer, we can find the ImageButton for hamburger button, for example:
public class MyMasterDetailRenderer : MasterDetailPageRenderer
{
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
for (var i = 0; i < toolbar.ChildCount; i++)
{
var imageButton = toolbar.GetChildAt(i) as ImageButton;
var drawerArrow = imageButton?.Drawable as DrawerArrowDrawable;
if (drawerArrow == null)
continue;
//set drawable
imageButton.SetImageDrawable(Forms.Context.GetDrawable(Resource.Drawable.hamburger));
//set padding
imageButton.SetPadding(80, 30, 80, 30);
//set background
imageButton.SetBackgroundColor(Android.Graphics.Color.Red);
}
}
}
I'm trying to create an application with similar to Google Photos app UI. Support Libary Version = 25.1.0.
The problem in that with translucent status and navigation bars, widgets inside CoorinatorLayout looks not as expected. Setting fitsSystemWindows=true attribute for the BottomNavigationView makes it too large (screenshot 1) and SnakBar in that case appears behind navigation bar, not above BottomNavView or nav bar as expected. If I add fitsSystemWindows=true in Toolbar (screenshot 2) then BottomNavigationView looses it's fitsSystemWindows attribute and Toolbar content gone somewhere. It looks as a support library bug, but I'm not sure in that.
Here is my DSL code:
coordinatorLayout {
customToolbar {
id = TOOLBAR
// fitsSystemWindows = true
title = createTitle(ctx)
lparams(matchParent, dip(48))
}
frameLayout {
id = CONTENT_FRAME
backgroundResource = R.color.colorBackground
lparams(matchParent, matchParent)
}
bottomNavigationView(R.style.Base_ThemeOverlay_AppCompat_Dark) {
id = BOTTOM_NAVIGATION_VIEW
fitsSystemWindows = true
itemIconTintList = ContextCompat.getColorStateList(ctx, R.drawable.nav_item_color_state)
itemTextColor = ContextCompat.getColorStateList(ctx, R.drawable.nav_item_color_state)
backgroundResource = R.color.colorAccent
inflateMenu(R.menu.menu_drawer_2)
lparams(matchParent) {
anchorGravity = Gravity.BOTTOM
anchorId = CONTENT_FRAME
}
}
}
I have been looking a way to change the color of all elements in a toolbar working like an ActionBar dynamically.
Specifications:
Using parent="Theme.AppCompat.Light.NoActionBar" on styles.xml
Appcompat v7 22
setting setSupportActionBar() in my AppCompatActivity
I got the colors from a POST request (usually #FF------ format)
I have read following post:
How do I change the color of the ActionBar hamburger icon?
How to change color of hamburger icon in material design navigation drawer
Can't change navigation drawer icon color in android
ActionBarDrawerToggle v7 arrow color
Android Toolbar color change
Android burger/arrow icon dynamic change color (this one worked in someway but I don't like using own image wihtout animation).
And others links related to this topic... none of them worked for me.
What I'm doing right now is searching for ImageButton on the toolbar (Get reference to drawer toggle in support actionbar), and applying setColorFilter() to all of them like the following code:
for (int i = 0; i < toolbar.getChildCount(); i++){
if (toolbar.getChildAt(i) instanceof ImageButton) {
ImageButton ib = (ImageButton) toolbar.getChildAt(i);
ib.setColorFilter(Color.parseColor("#A74231"), PorterDuff.Mode.SRC_ATOP);
}
}
I'm changing background and text color with: toolbar.setBackgroundColor and toolbar.setTitleTextColor.
For menu icons (including overflow menu icon):
MenuItem item2 = mMenu.findItem(R.id.actionbar_group_moreoverflow);
item2.getIcon().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
the QUESTION: is there a better way to do it (change toolbar's elements color dynamically)?
I was facing same problem here. What I did for ToolBar's elements:
For background color: toolbar.setBackgroundColor(Color.parseColor("#xxxxxxxx"));
For text color: toolbar.setTitleTextColor(Color.parseColor("#xxxxxxxx"));
For hamburger/drawer button:
int color = Color.parseColor("#xxxxxxxx");
final PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP);
for (int i = 0; i < toolbar.getChildCount(); i++){
final View v = toolbar.getChildAt(i);
if(v instanceof ImageButton) {
((ImageButton)v).setColorFilter(colorFilter);
}
}
For ActionMenuItemView (toolbar's buttons including overflow button):
private void colorizeToolBarItem(AppCompatActivity activity, final PorterDuffColorFilter colorFilter, final String description) {
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
final ArrayList<View> outViews = new ArrayList<>();
decorView.findViewsWithText(outViews, description,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty())
return;
ActionMenuItemView overflow = (ActionMenuItemView)outViews.get(0);
overflow.getCompoundDrawables()[0].setColorFilter(colorFilter);
removeOnGlobalLayoutListener(decorView,this);
}
});
}
For overflow menu's items text: take a look at this link
To get all Toolbar views, iterate through all it’s child views and colorize them separately. The loop code for it looks like this:
public static void colorizeToolbar(Toolbar toolbarView, int toolbarIconsColor, Activity activity) {
final PorterDuffColorFilter colorFilter
= new PorterDuffColorFilter(toolbarIconsColor, PorterDuff.Mode.MULTIPLY);
for(int i = 0; i < toolbarView.getChildCount(); i++) {
final View v = toolbarView.getChildAt(i);
//Step 1 : Changing the color of back button (or open drawer button).
if(v instanceof ImageButton) {
//Action Bar back button
((ImageButton)v).getDrawable().setColorFilter(colorFilter);
}
if(v instanceof ActionMenuView) {
for(int j = 0; j < ((ActionMenuView)v).getChildCount(); j++) {
//Step 2: Changing the color of any ActionMenuViews - icons that
//are not back button, nor text, nor overflow menu icon.
final View innerView = ((ActionMenuView)v).getChildAt(j);
if(innerView instanceof ActionMenuItemView) {
int drawablesCount = ((ActionMenuItemView)innerView).getCompoundDrawables().length;
for(int k = 0; k < drawablesCount; k++) {
if(((ActionMenuItemView)innerView).getCompoundDrawables()[k] != null) {
final int finalK = k;
//Important to set the color filter in seperate thread,
//by adding it to the message queue
//Won't work otherwise.
innerView.post(new Runnable() {
#Override
public void run() {
((ActionMenuItemView) innerView).getCompoundDrawables()[finalK].setColorFilter(colorFilter);
}
});
}
}
}
}
}
//Step 3: Changing the color of title and subtitle.
toolbarView.setTitleTextColor(toolbarIconsColor);
toolbarView.setSubtitleTextColor(toolbarIconsColor);
//Step 4: Changing the color of the Overflow Menu icon.
setOverflowButtonColor(activity, colorFilter);
}
}
Second,implement the method responsible for finding and colorizing the Overflow Icon:
private static void setOverflowButtonColor(final Activity activity, final PorterDuffColorFilter colorFilter) {
final String overflowDescription = activity.getString(R.string.abc_action_menu_overflow_description);
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
final ArrayList<View> outViews = new ArrayList<View>();
decorView.findViewsWithText(outViews, overflowDescription,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty()) {
return;
}
TintImageView overflow=(TintImageView) outViews.get(0);
overflow.setColorFilter(colorFilter);
removeOnGlobalLayoutListener(decorView,this);
}
});
}
Toolbar background color
mToolbarView.setBackgroundColor(color);
ToolbarColorizeHelper.colorizeToolbar(mToolbarView, mToolbarIconsColor, getActivity());
Have a look at this link, it may help you https://snow.dog/blog/how-to-dynamicaly-change-android-toolbar-icons-color/
Okay, a quick background : I've been developing a simple music player app and to enhance the user experience (especially on newer devices) I decided to implement a tinted StatusBar using the fabled SystemBarTint library.
Imported the .JAR, followed the usage directions, modified the application theme and voila! My app looks fancier than an 10-years old show bike. But wait, there's more!
As you can see, the ListView is now covered by the ActionBar and its tabs. I did my homework and found this workaround -- which works, sort of.
My ListView is no longer covered by the ActionBar but it's still covered by the tabs!
How do I sort this one out?
This is my BaseActivity onCreate method which activates the SystemBarTint library :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SystemBarTintManager tintManager = new SystemBarTintManager(this);
tintManager.setStatusBarTintEnabled(true);
tintManager.setTintColor(getResources().getColor(R.color.wowza_orange));
}
..and this is the workaround, supplied in my Fragment (which houses the ListView) :
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
musicList.setClipToPadding(false); // musicList is my ListView instance.
setInsets(getActivity(), (View) musicList);
}
public static void setInsets(Activity context, View view) {
SystemBarTintManager tintManager = new SystemBarTintManager(context);
SystemBarTintManager.SystemBarConfig config = tintManager.getConfig();
view.setPadding(0, config.getPixelInsetTop(true),
config.getPixelInsetRight(), config.getPixelInsetBottom());
}
Thanks in advance!
Its a little late, but I was facing the same problem. My solution is add this method:
private int getActionBarHeight() {
int actionBarHeight =0;
final TypedValue tv = new TypedValue();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
} else if (context.getTheme().resolveAttribute(R.attr.actionBarSize, tv, true))
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
return actionBarHeight;
}
and replace:
view.setPadding(0, config.getPixelInsetTop(true),
config.getPixelInsetRight(), config.getPixelInsetBottom());
with:
view.setPadding(0, config.getPixelInsetTop(true) + getActionBarHeight(),
config.getPixelInsetRight(), config.getPixelInsetBottom());