Remove "Done" button of ActionMode - android

0I'm using startActionMode(ActionMode) on my app.
By default it's add a "Done" button on the bar, I want to remove it.
Also, if there's a way to change it's text, I want to know too, cause a different description than "Done" can make the action be correspondent to the behaviour of what it does.

I agree with #CommonsWare that it is invalid design to hide the Done button.
However, there are customers that want to have this button removed and I can understand that the checkmark may cause confusion to users because it actually does nothing in some cases.
So, here is how to remove the button with styles:
<style name="AppTheme" parent="android:Theme.Holo">
<item name="android:actionModeCloseButtonStyle">#style/NoCloseButton</item>
</style>
<style name="NoCloseButton" parent="#android:style/Widget.ActionButton.CloseMode">
<item name="android:visibility">gone</item>
</style>

If you are using ActionBarSherlock you can hide the "Done" button with this style:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="NoCloseButton" parent="#style/Widget.Sherlock.ActionButton.CloseMode">
<item name="android:visibility">gone</item>
</style>
<style name="AppBaseTheme" parent="Theme.Sherlock.Light.DarkActionBar">
<item name="actionModeCloseButtonStyle">#style/NoCloseButton</item>
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
</style>
</resources>
Please make sure to put this style in each style directory (values, value-v11, values-v14). After that you can create a custom menu with this code:
LayoutInflater inflater = LayoutInflater.from(getSherlockActivity());
View actionView = inflater.inflate(R.layout.actionmode, null);
ActionMode am = getSherlockActivity().startActionMode(mActionModeCallback);
am.setCustomView(actionView);

Even I was stuck with same and I found this way to solve it.
int doneButtonId = Resources.getSystem().getIdentifier("action_mode_close_button", "id", "android");
LinearLayout layout = (LinearLayout) findViewById(doneButtonId);
TextView doneview = (TextView) layout.getChildAt(1);
doneview.setText("");
Hope this helps!!

Thanks for Matthias Robbers, it works. But i perfer to use "invisible":
<style name="NoCloseButtonActionModeStyle">
<item name="android:visibility">invisible</item>
</style>
So the custom view position in ActionMode will not indent to parent left.

any one find out screen width solution? – Mayur R. Amipara Jun 5 '15 at 10:27
override your custom view's onMeasure, set it's width to screen width. and in onLayout, relayout your child views.
it works for me.
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.RelativeLayout;
import com.android.gallery3d.R;
public class SelectActionModeCustomView extends RelativeLayout {
private View mLeftButton;
private View mRightButton;
private int mScreenWidth;
private static final String TAG = "SelectActionView";
public SelectActionModeCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
mScreenWidth = metrics.widthPixels;
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
mLeftButton = findViewById(R.id.cancel);
mRightButton = findViewById(R.id.select_action);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
this.setMeasuredDimension(mScreenWidth, this.getMeasuredHeight());
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
int childLeft = 0;
int childTop = 0;
childLeft = 0;
childTop = ((b - t) - mLeftButton.getMeasuredHeight()) / 2;
mLeftButton.layout(childLeft, childTop,
childLeft + mLeftButton.getMeasuredWidth(),
childTop + mLeftButton.getMeasuredHeight());
childLeft = (r - l) - mRightButton.getMeasuredWidth();
childTop = ((b - t) - mRightButton.getMeasuredHeight()) / 2;
mRightButton.layout(childLeft, childTop,
childLeft + mRightButton.getMeasuredWidth(),
childTop + mRightButton.getMeasuredHeight());
}
}

Related

How To Create Activity Over Home Button

I want to create an activity over home button on phone.
In some devices home button overlay activity.
How can I solve this problem?
Thanks
If you mean navigation bar and based on this question, the solution would be adding these properties in value-21 style.xml :
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:fitsSystemWindows">true</item>
another way would be:
public static int getSoftButtonsBarSizePort(Activity activity) {
// getRealMetrics is only available with API 17 and +
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int usableHeight = metrics.heightPixels;
activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int realHeight = metrics.heightPixels;
if (realHeight > usableHeight)
return realHeight - usableHeight;
else
return 0;
}
return 0;
}

How to set custom font for TabLayout in Android?

I want use TabLayout and ViewPager in my app, but i want set custom font for TabLayout but i can't this!
I use this code :
Typeface droidSerifMonoTF = Typeface.createFromAsset(getAssets(), "fonts/DroidSerif.ttf");
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
TextView t = new TextView(this);
t.setText(mSectionsPagerAdapter.getPageTitle(i) );
t.setTypeface(droidSansMonoTF);
actionBar.addTab(actionBar.newTab()
.setCustomView(t)
.setTabListener(this));
}
from this link : Link but don't work me!
How can i it?
You can do that by extending TabLayout class. Override onLayout method as bellow:
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom){
super.onLayout(changed, left, top, right, bottom);
final ViewGroup tabStrip = (ViewGroup)getChildAt(0);
final int tabCount = tabStrip.getChildCount();
ViewGroup tabView;
int tabChildCount;
View tabViewChild;
for(int i=0; i<tabCount; i++){
tabView = (ViewGroup)tabStrip.getChildAt(i);
tabChildCount = tabView.getChildCount();
for(int j=0; j<tabChildCount; j++){
tabViewChild = tabView.getChildAt(j);
if(tabViewChild instanceof AppCompatTextView){
if(fontFace == null){
fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
}
((TextView) tabViewChild).setTypeface(fontFace, Typeface.BOLD);
}
}
}
}
Must Overwrite onLayout method, because, when you use setupWithViewPager method to bind the TabLayout with the ViewPager, you have to set tabs text either with setText method or in the PagerAdapter after that and when this happened, onLayout method get called on the parent ViewGroup (TabLayout) and that's the place to put setting fontface.(Changing a TextView text cause calling onLayout method of it's parent - A tabView has two children, one is ImageView another is TextView)
Another Solution:
First, these lines of code:
if(fontFace == null){
fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.IranSans));
}
In above solution, should be written outside of two loops.
But better solution for API >= 16 is using android:fontFamily:
Create a Android Resource Directory named font and copy your desired font to the directory.
Then use these styles:
<style name="tabLayoutTitles">
<item name="android:textColor">#color/white</item>
<item name="android:textSize">#dimen/appFirstFontSize</item>
<item name="android:fontFamily">#font/vazir_bold</item>
</style>
<style name="defaultTabLayout">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">#dimen/defaultTabLayoutHeight</item>
<item name="android:gravity">right</item>
<item name="tabTextAppearance">#style/tabLayoutTitles</item>
<item name="tabSelectedTextColor">#color/white</item>
<item name="tabIndicatorColor">#color/white</item>
<item name="tabIndicatorHeight">#dimen/accomTabIndicatorHeight</item>
<item name="tabMode">fixed</item>
<item name="tabGravity">fill</item>
<item name="tabBackground">#drawable/rectangle_white_ripple</item>
<item name="android:background">#color/colorPrimary</item>
</style>

How can I Animate the color change of the statusbar and toolbar (like the new Calendar app does)

The new Google Calendar app has an animation I would like to do in my app. When you create a new event you can choose a color for the event. When you do, the statusbar and toolbar change to that color with a circular effect that covers both of them.
Here's an example of what I'd like to do:
I can change the color of the statusbar and toolbar, but how can I apply the circular animation effect (or similar) to both of them as the color is changed?
I don't know if this is the exact way the Calendar app does it, but it's close enough for me.
Caveats
The method uses the ViewAnimationUtils.createCircularReveal method introduced in Lollipop.
It requires knowing the height of the status bar and your toolbar actionbar. You can still use ?attr/actionBarSize for your actionbar and get both dynamically, but for simplicity here I've assumed 56dp for the actionbar height and 24dp for the status bar height.
General Idea
The general idea is to set your actionbar and status bar to transparent. This will shift your actionbar up under the statusbar so you have to adjust the size and padding of the actionbar to compensate. You then use a view behind it and ViewAnimationUtils.createCircularReveal to reveal the new background color. You need one more view behind that to show the old background color as the middle view is revealing the new one.
The Animation
The animation requires:
The transparent toolbar actionbar that covers the space of the regular actionbar and the statusbar. The hard-coded height, in this case, is 56dp (actionbar) + 24dp (statusbar) = 80dp. You also need to set the top padding to 24dp to keep the actionbar content our from under the statusbar.
A middle view (I'll call it the reveal view) that's the same size (80dp height) but just behind the actionbar. This will be the view the ViewAnimationUtils.createCircularReveal acts on.
A bottom view (I'll call it the reveal background view) that's the same size as the reveal view but behind it. This view is there to show the old background color while the reveal view is revealing the new color on top of it.
Code
Here are the key pieces of code I used. See the example project at https://github.com/shaun-blake-experiments/example-toolbar-animation.
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<View
android:id="#+id/revealBackground"
android:layout_width="match_parent"
android:layout_height="80dp"
android:paddingTop="24dp"
android:background="#color/primary"
android:elevation="4dp">
</View>
<View
android:id="#+id/reveal"
android:layout_width="match_parent"
android:layout_height="80dp"
android:paddingTop="24dp"
android:background="#color/primary"
android:elevation="4dp">
</View>
<Toolbar
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="80dp"
android:paddingTop="24dp"
android:background="#android:color/transparent"
android:elevation="4dp"
android:theme="#style/TranslucentActionBar">
</Toolbar>
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Invert Toolbar Colors"
android:textOn="Invert Toolbar Colors On"
android:textOff="Invert Toolbar Colors Off"
android:id="#+id/toggleButton"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
styles.xml
<resources>
<style name="AppTheme" parent="#android:style/Theme.Material.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowContentOverlay">#null</item>
</style>
<style name="TranslucentActionBar" parent="#android:style/Widget.Material.ActionBar">
<item name="android:textColorPrimary">#color/primary_text_dark_background</item>
</style>
</resources>
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primary">#2196F3</color>
<color name="primary_dark">#1976D2</color>
<color name="primary_light">#BBDEFB</color>
<color name="accent">#009688</color>
<color name="primary_text">#DD000000</color>
<color name="primary_text_dark_background">#FFFFFF</color>
<color name="secondary_text">#89000000</color>
<color name="icons">#FFFFFF</color>
<color name="divider">#30000000</color>
</resources>
MainActivity.java
package com.example.android.toolbaranimation;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.widget.ToggleButton;
import android.widget.Toolbar;
public class MainActivity extends Activity {
private View mRevealView;
private View mRevealBackgroundView;
private Toolbar mToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.appbar);
mToolbar.setTitle(getString(R.string.app_name));
mRevealView = findViewById(R.id.reveal);
mRevealBackgroundView = findViewById(R.id.revealBackground);
ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
toggleButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean on = ((ToggleButton) v).isChecked();
if (on) {
animateAppAndStatusBar(R.color.primary, R.color.accent);
} else {
animateAppAndStatusBar(R.color.accent, R.color.primary);
}
}
});
setActionBar(mToolbar);
}
private void animateAppAndStatusBar(int fromColor, final int toColor) {
Animator animator = ViewAnimationUtils.createCircularReveal(
mRevealView,
mToolbar.getWidth() / 2,
mToolbar.getHeight() / 2, 0,
mToolbar.getWidth() / 2);
animator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationStart(Animator animation) {
mRevealView.setBackgroundColor(getResources().getColor(toColor));
}
});
mRevealBackgroundView.setBackgroundColor(getResources().getColor(fromColor));
animator.setStartDelay(200);
animator.setDuration(125);
animator.start();
mRevealView.setVisibility(View.VISIBLE);
}
}
Notes
Be careful of the android:elevation property on the toolbar, reveal, and reveal background views. If the elevation is lower on the toolbar, the others will cover the buttons and text.
I don't know how they achieved the ripple effect, but you can have a smooth color transition of both bars simultaneously with the following code.
private void tintSystemBars() {
// Initial colors of each system bar.
final int statusBarColor = getResources().getColor(R.color.status_bar_color);
final int toolbarColor = getResources().getColor(R.color.toolbar_color);
// Desired final colors of each bar.
final int statusBarToColor = getResources().getColor(R.color.status_bar_to_color);
final int toolbarToColor = getResources().getColor(R.color.toolbar_to_color);
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
// Use animation position to blend colors.
float position = animation.getAnimatedFraction();
// Apply blended color to the status bar.
int blended = blendColors(statusBarColor, statusBarToColor, position);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow.setStatusBarColor(blended);
}
// Apply blended color to the ActionBar.
blended = blendColors(toolbarColor, toolbarToColor, position);
ColorDrawable background = new ColorDrawable(blended);
getSupportActionBar().setBackgroundDrawable(background);
}
});
anim.setDuration(500).start();
}
private int blendColors(int from, int to, float ratio) {
final float inverseRatio = 1f - ratio;
final float r = Color.red(to) * ratio + Color.red(from) * inverseRatio;
final float g = Color.green(to) * ratio + Color.green(from) * inverseRatio;
final float b = Color.blue(to) * ratio + Color.blue(from) * inverseRatio;
return Color.rgb((int) r, (int) g, (int) b);
}
After A great amount of research ,
I've found an answer that you'd want.
This animation is called a reveal animation introduced in the 21.0 Android API - lollipop . Unfortunately , it is not backwards compatible.
I've found a library which does the same reveal animation but not exactly a backport , but the effect you want can be achieved API 14 onwards with this library
https://github.com/markushi/android-ui
Thank You,
If you are keen on using this animation only with lollipop then just google "Android Reveal Colour Animation implementation".
Try this, it works great for me and it gets the same effect Google Calendar app does.
private void reveal(CollapsingToolbarLayout toolbarLayout, int colorPrimary, int colorPrimaryDark){
// get the center for the clipping circle
int cx = toolbarLayout.getWidth() / 2;
int cy = toolbarLayout.getHeight() / 2;
// get the final radius for the clipping circle
float finalRadius = (float) Math.hypot(cx, cy);
// create the animator for this view (the start radius is zero)
Animator anim =
ViewAnimationUtils.createCircularReveal(toolbarLayout, cx, cy, 0, finalRadius);
// make the view visible and start the animation
toolbarLayout.setBackgroundColor(colorPrimary);
anim.start();
Window window = getWindow();
window.setStatusBarColor(colorPrimaryDark);
toolbarLayout.setContentScrimColor(colorPrimary);
}

Changing ActionBar background affects Navigation drawer

I'm changing the ActionBar background in a fragment with a ScrollView. I have a ScrollView listener which changes the alpha of the items in the layered-list based on the scroll distance. The action bar actually works great. However, the Navigation Drawer background gets affected by this alpha change and I have no idea why; the nav drawer background becomes invisible. I can reproduce this easily on a Nexus 7 running Android L but it doesn't always happen for some 4.4 devices.
The main part is:
ActionBar actionBar = activity.getSupportActionBar();
LayerDrawable mActionBarBg = (LayerDrawable) getResources().getDrawable(R.drawable.background_actionbar);
if (mActionBarBg != null) {
setActionBarBgAlpha(0);
actionBar.setBackgroundDrawable(mActionBarBg);
}
Alpha calculator is this:
scrollView.setOnScrollChangedLitstener(new OnScrollChangedListener() {
#Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
t = Math.max(t, 0);
endpointHeader.setTranslationY(endpointHeader.getTop() + (t * 0.25f));
mScrollAlpha = (int) Math.min(alphaToHeightRatio * t, 255);
updateActionBarElemsAlpha(mScrollAlpha);
}
});
Couple of other methods:
private void updateActionBarElemsAlpha(int updatedAlpha){
if(mActionBarTitleColor != null){
mActionBarTitleColor.setAlpha(updatedAlpha);
mActionBarTitleView.setTextColor(mActionBarTitleColor.getColor());
}
setActionBarBgAlpha(updatedAlpha);
}
private void setActionBarBgAlpha(int alpha){
if(mActionBarBg != null){
mActionBarBg.getDrawable(1).setAlpha(alpha);
mActionBarBg.getDrawable(2).setAlpha(alpha);
}
}
background_actionbar.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/gradient" />
<item android:drawable="#color/grey_divider"/>
<item android:bottom="2dp"
android:drawable="#color/White"/>
</layer-list>
You should always mutate drawables before changing any attributes, otherwise you'll end up modifying the cached state which is by default shared across all instances.
if (mActionBarBg != null) {
mActionBarBg.mutate();
mActionBarBg.getDrawable(1).setAlpha(alpha);
mActionBarBg.getDrawable(2).setAlpha(alpha);
}

setting a max width for my dialog

My dialog is using a linearlayout for its root, and its using the following code as its custom theme:
<style name="HuskyBusDialog">
<item name="android:windowNoTitle">true</item>
<item name="android:windowFrame">#null</item>
<item name="android:windowBackground">#drawable/panel_background</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowAnimationStyle">#android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:colorBackgroundCacheHint">#null</item>
</style>
Is it possible to set a max width? Its fine on phones but im trying to optimize it for tablets and they are too big.
The width will be dealt with in the XML for the linear layout, not in the style that you apply to it. Use the android:layout_width tag in XML to specify how wide it could possibly be.
An old question, however no replies are suitable, but you can find some hint here: How to customize the width and height when show an Activity as a Dialog
This helps customize the width and height, but not set the max width and height! To achieve that on an activity using a dialog theme, I had to do a couple of things:
1) set a layout listener to know when the dialog layout is set.
2) Adjust the dialog layout if its size was beyond the desired limit, effectively setting max size
Here is the working snippet I'm currently using, called after setContentView():
getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener()
{
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout()
{
adjustDialog();
}
});
Now the dialog size adjustment, as a percentage of actual screen size:
private void adjustDialog()
{
Window w = getWindow();
w.setGravity(Gravity.CENTER);
int current_width = w.getDecorView().getWidth();
int current_height = w.getDecorView().getHeight();
WindowManager.LayoutParams lp = w.getAttributes();
DisplayMetrics dm = getResources().getDisplayMetrics();
int max_width = (int) (dm.widthPixels * 0.90);
int max_height = (int) (dm.heightPixels * 0.90);
if (current_width > max_width)
{
lp.width = max_width;
}
if (current_height > max_height)
{
lp.height = max_height;
}
w.setAttributes(lp);
}
yeaa if u wanna do with Widht GO for ur xml
and try to do
android:layout_width="Defined in pixels//20px"
or u can try this also
android:width="Defined in pixels// 30px"
i hope it will be hepful to u

Categories

Resources