How to clear animation of adding/removing actionbar? - android

At my application I am using container where I change several fragments. At some fragments I have to hide actionbar at parent activity. I managed to do it, but the process of hiding and viewing toolbar is supported with weird and uncomfortable animation. I hide and show toolbar via:
Objects.requireNonNull(getSupportActionBar()).hide();
Maybe I can clear animation?

I managed to find a solution for my problem with this method:
public static void disableShowHideAnimation(ActionBar actionBar) {
try
{
actionBar.getClass().getDeclaredMethod("setShowHideAnimationEnabled", boolean.class).invoke(actionBar, false);
}
catch (Exception exception)
{
try {
Field mActionBarField = actionBar.getClass().getSuperclass().getDeclaredField("mActionBar");
mActionBarField.setAccessible(true);
Object icsActionBar = mActionBarField.get(actionBar);
Field mShowHideAnimationEnabledField = icsActionBar.getClass().getDeclaredField("mShowHideAnimationEnabled");
mShowHideAnimationEnabledField.setAccessible(true);
mShowHideAnimationEnabledField.set(icsActionBar,false);
Field mCurrentShowAnimField = icsActionBar.getClass().getDeclaredField("mCurrentShowAnim");
mCurrentShowAnimField.setAccessible(true);
mCurrentShowAnimField.set(icsActionBar,null);
}catch (Exception e){
//....
}
}
}
link.

Related

CollapsingToolbarLayout's setCollapsedTitleTextColor and setExpandedTitleColor don't do anything

I'm trying to set the expanded and collapsed CollapsingToolbarLayout's title text color to be different, but no matter what I do, it is always white.
Here is the code in question:
mCollapsingToolbar.setCollapsedTitleTextColor(getResources.getColor(R.color.foo));
mCollapsingToolbar.setExpandedTitleColor(getResources.getColor(R.color.bar));
In my layout XML file, I'm not specifying any color styles on either the AppBarLayout, the CollapsingToolbarLayout, or the Toolbar itself.
Is there some sort of interference with my Activity's theme settings?
Thanks!
I think you need to try below code:
private void changeCollapsedTitleTextColor(CollapsingToolbarLayout collapsingToolbarLayout) {
try {
final Field field = collapsingToolbarLayout.getClass().getDeclaredField("mCollapsingTextHelper");
field.setAccessible(true);
final Object object = field.get(collapsingToolbarLayout);
final Field tpf = object.getClass().getDeclaredField("mTextPaint");
tpf.setAccessible(true);
((TextPaint) tpf.get(object)).setColor(getResources().getColor(R.color.your_color));
} catch (Exception ignored) {
}
}
I found here.
I hope it may help you.

Actionbar convert tabs to list navigation if there is no room

I have an actionbar with a logo, a title, 2 tabs and a search function.
On a phone (3.5") everything works fine.
The actionbar has 2 lines. The logo title and the search function appear on the first line and the tabs apear on the second line.
On my tablet (7") everyting is shown on a single line. But the tabs will be convert to a list when i click the search icon.
How can i split the (sherlock)actionbar in 2 lines on my 7" tabblet?
Or is there an other way to solve this problem?
In ActionBarSherlock, there is a boolean value(abs__action_bar_embed_tabs) that determine whether the Tabs should be embed in ActionBar, and this value is stored in two files.
In values/abs__bools.xml. It is false.
In values-w480/abs__bools.xml. It is true.
This means Tabs will be embed only if the width of device is bigger than 480dp.
If you want to control it all by yourself, you can just create values-w480 in your own project, and set abs__action_bar_embed_tabs to false to override the value in library project.
I found a solution to separate the tabs in code.
private void embeddedTabs(Object actionBar, Boolean embed_tabs) {
try {
if (actionBar instanceof ActionBarWrapper) {
//ICS and forward
try {
Field actionBarField = actionBar.getClass().getDeclaredField("mActionBar");
actionBarField.setAccessible(true);
actionBar = actionBarField.get(actionBar);
} catch (Exception e) {
Log.e("", "Error enabling embedded tabs", e);
}
}
Method setHasEmbeddedTabsMethod = actionBar.getClass().getDeclaredMethod("setHasEmbeddedTabs", boolean.class);
setHasEmbeddedTabsMethod.setAccessible(true);
setHasEmbeddedTabsMethod.invoke(actionBar, embed_tabs);
} catch (Exception e) {
Log.e("", "Error marking actionbar embedded", e);
}
}
But now I have a new problem. The tabs don't fill the tabbar completely.
Actionbar tabs don't fill the tabbar
this method works fine for me:
JUST PUT THE NAVIGATION METHOD, AFTER ADDING ADDING TABS:
... // adding tabs
bar.setNavigationMode(ActionBar.Navigation_mode_tabs);

Android SDK Crash at android.widget.PopupWindow$1.onScrollChanged(PopupWindow.java:132)

Can someone with google dev team explain how to avoid this crash on pre-ics devices? In my case an ImageButton on the ListView item is the anchor of the PopupWindow to create a dropdown. I have tried everything popup.dismiss() , popup= null, etc but nothing seems to prevent this being an issue when the adapter is reset.
I am getting the following exception:
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.widget.PopupWindow$1.onScrollChanged(PopupWindow.java:132)
05-21 17:02:27.736: E/AndroidRuntime(25836): at
android.view.ViewTreeObserver.dispatchOnScrollChanged(ViewTreeObserver.java:607)
This Popup is on a list item. Once the last list item is removed from the ListView I resetAdapter to set a footer. Then when I move away from the screen this error occurs.
Not in Ice Cream Sandwich: Icecream Sandwich. See https://android.googlesource.com/platform/frameworks/base/+/749b0eb2c9a52bb188fd8900859b3725889e0ec0%5E!/
This suggests a fix related to null anchor of PopupWindow. What can be done?
In my case a button in ListView item is the anchor of the popup window.
and same issue here:
https://github.com/JakeWharton/ActionBarSherlock/issues/487
Not sure if OP still needs this since it is half year later that I just saw this..
This is fixed in ICS. However, you may assign a fixed scroll listener via reflection!
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.ICE_CREAM_SANDWICH){
try {
final Field fAnchor = PopupWindow.class.getDeclaredField("mAnchor");
fAnchor.setAccessible(true);
Field listener = PopupWindow.class.getDeclaredField("mOnScrollChangedListener");
listener.setAccessible(true);
final ViewTreeObserver.OnScrollChangedListener originalListener = (ViewTreeObserver.OnScrollChangedListener) listener.get(window);
ViewTreeObserver.OnScrollChangedListener newListener=
new ViewTreeObserver.OnScrollChangedListener() {
public void onScrollChanged() {
try {
// PopupWindow implementation has WeakReference<View>
WeakReference<View> mAnchor = (WeakReference<View>) fAnchor.get(window);
if (mAnchor == null || mAnchor.get() == null) {
return;
} else {
originalListener.onScrollChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
listener.set(window,newListener);
} catch (Exception e) {
e.printStackTrace();
}
}

PopupWindow z ordering

I play with menus using PopupWindow, which overlap EditText.
It works fine, except that my PopupWindow is overlapped by some items from EditText IME system (selection marks, Paste button).
My question is: how do I force z-ordering of my PopupWindow so that it appears above those decorations?
Here's image of what's happening. I need my PopupWindow (the menu) be drawn on top of everything, thus somehow tell WindowManager how to order windows.
Thanks.
Found anwer myself.
Those decorations are normal PopupWindow-s, managed by EditText.
Z-ordering of any Window is defined by WindowManager.LayoutParams.type, actually it defines purpose of Window. Valid ranges are FIRST_SUB_WINDOW - LAST_SUB_WINDOW for a popup window.
App typically can't change "type" of PopupWindow, except of calling hidden function PopupWindow.setWindowLayoutType(int) using Java reflection, and setting desired window type.
Result:
EDIT:
Code that does that:
Method[] methods = PopupWindow.class.getMethods();
for(Method m: methods){
if(m.getName().equals("setWindowLayoutType")) {
try{
m.invoke(getPopupWindow(), WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
}catch(Exception e){
e.printStackTrace();
}
break;
}
}
import android.support.v4.widget.PopupWindowCompat;
PopupWindowCompat.setWindowLayoutType(popupWindow, WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
public void compatibleSetWindowLayoutType(int layoutType) {
if (Build.VERSION.SDK_INT >= 23) {
setWindowLayoutType(layoutType);
} else {
try {
Class c = this.getClass();
Method m = c.getMethod("setWindowLayoutType", Integer.TYPE);
if(m != null) {
m.invoke(this, layoutType);
}
} catch (Exception e) {
}
}
}
Make are complement.
The PopupWindowCompat.setWindowLayoutType API must be called before show popWindow.

Change HorizontalScrollView's light color - OverScrollMode

At the end of the HorizontalScrollView, a light appears to show that the scroll content has ended. Is there a way to change this color? It is appearing in my phone as a yellow one. I have already set the HorizontalScrollView's background color to the one that I desire, but this "end-of-scroll" light isn't the one I want.
EDIT:
I just noticed that this light appears due to the onOverScrollMode (since API level 9 - see this link). Is there a way to set OVER_SCROLL_NEVER and also keep the compatibility with the Eclair versions? Or even better: to set the color of this light (if it appears)?
Unfortunately there is no simple way to set the color for the OverScroll EdgeEffect.
To safely set OVER_SCROLL_NEVER and remain compatible with early SDK revs, you can introspect for the setOverScrollMode method and if found call it. (tested on 3.1 and 2.2)
setContentView(R.layout.main);
// find scroll view
HorizontalScrollView hscroll = (HorizontalScrollView)findViewById(R.id.hscroll);
try {
// look for setOverScrollMode method
Method setOverScroll = hscroll.getClass().getMethod("setOverScrollMode", new Class[] { Integer.TYPE } );
if (setOverScroll != null) {
try {
// if found call it (OVER_SCROLL_NEVER == 2)
setOverScroll.invoke(hscroll, 2);
} catch (InvocationTargetException ite) {
} catch (IllegalAccessException ie) {
}
}
} catch (NoSuchMethodException nsme) {
}
Although this question has already been answered, I wanted to add a couple of more ways that you can go about setting the overScrollMode attribute.
1) Create a "layout-v10" folder and put your alternate xml layout with the overScrollMode attribute set as desired.
2) If #1 would mean copying a ton of files and duplication, you can alternatively create a style for the HorizontalScrollView.
You can set the EdgeEffect color using reflection. The following will work from API 14+:
public static void setEdgeGlowColor(final HorizontalScrollView hsv, final int color) {
try {
final Class<?> clazz = HorizontalScrollView.class;
for (final String name : new String[] {
"mEdgeGlowLeft", "mEdgeGlowRight"
}) {
final Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
setEdgeEffectColor((EdgeEffect) field.get(hsv), color);
}
} catch (final Exception ignored) {
}
}
public static void setEdgeEffectColor(final EdgeEffect edgeEffect, final int color) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
edgeEffect.setColor(color);
return;
}
final Field edgeField = EdgeEffect.class.getDeclaredField("mEdge");
edgeField.setAccessible(true);
final Field glowField = EdgeEffect.class.getDeclaredField("mGlow");
glowField.setAccessible(true);
final Drawable mEdge = (Drawable) edgeField.get(edgeEffect);
final Drawable mGlow = (Drawable) glowField.get(edgeEffect);
mEdge.setColorFilter(color, PorterDuff.Mode.SRC_IN);
mGlow.setColorFilter(color, PorterDuff.Mode.SRC_IN);
mEdge.setCallback(null); // free up any references
mGlow.setCallback(null); // free up any references
} catch (final Exception ignored) {
}
}

Categories

Resources