Snackbar half width on tablet - android

I have problem with setting Snackbar on tablet (API 22), on phones (API 23 and 22) it works fine (from edge to edge), even when horizontal.
Result is such Snackbar as below:
FloatingActionButton (support library) also doesn't move (when on phone it does).
My layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
android:id="#+id/snackParent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="#dimen/margin_fab"
android:layout_marginRight="#dimen/margin_fab"
app:pressedTranslationZ="12dp" />
</android.support.design.widget.CoordinatorLayout>
And using in MainActivity
private void showMessage(String msg) {
if(snackParent != null) {
snackbar = Snackbar.make(snackParent, msg, Snackbar.LENGTH_SHORT);
snackbar.setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View v) {
snackbar.dismiss();
}
});
snackbar.show();
}
}
I have only other resources file with dimensions (fab margin) for tablets (w820dp), styles folder is same between phone and tablet. I have also tried invalidating Android Studio cache.
I use com.android.support:design:23.0.1 targetSdkVersion=23 and compileSdkVersion=23, buildToolsVersion=23.0.1.

I think this is the default behavior of snackbar on tablets. check this out .

You can do whatever you want with your snackbar. We had the same issue with tablets and we solved like this (e.g. code below is positioning snackbar at top and gives it the full width of the parent)
View view = snackbar.getView();
// Position snackbar at top
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
params.width = FrameLayout.LayoutParams.MATCH_PARENT;
view.setLayoutParams(params);

ViewGroup.LayoutParams layoutParams = snackbarView.getLayoutParams();
if (layoutParams instanceof FrameLayout.LayoutParams) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) layoutParams;
params.gravity = Gravity.TOP;
params.width = FrameLayout.LayoutParams.MATCH_PARENT;
snackbarView.setLayoutParams(params);
} else if (layoutParams instanceof CoordinatorLayout.LayoutParams) {
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) layoutParams;
params.gravity = Gravity.TOP;
params.width = FrameLayout.LayoutParams.MATCH_PARENT;
snackbarView.setLayoutParams(params);
} else {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) layoutParams;
params.gravity = Gravity.TOP;
params.width = FrameLayout.LayoutParams.MATCH_PARENT;
snackbarView.setLayoutParams(params);
}

After digging into code from github. I found one workaround. You just need to add below lines into styles.xml. Change the width as per your requirement
<style name="Widget.Design.Snackbar" parent="android:Widget">
<item name="maxActionInlineWidth">500dp</item>
</style>
If you want to change number of lines of default textview of Snackbar, you can change following style.
<style name="Widget.MaterialComponents.Snackbar.TextView" parent="Widget.AppCompat.TextView">
<item name="android:maxLines">3</item>
</style>

Related

Gravity.CENTER in GridLayout is not working

This is the XML that work fine, when I run in Android Studio, how to make this programmatically?
<?xml version="1.0" encoding="utf-8"?>
<GridLayout
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"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:context="com.test.MainActivity">
<TextView
android:text="Texto 1"/>
</GridLayout>
This is the code, that I try to make without success...
//TODO create Grid params
GridLayout.LayoutParams gridParams = new GridLayout.LayoutParams();
gridParams.height = GridLayout.LayoutParams.WRAP_CONTENT;
gridParams.width = GridLayout.LayoutParams.WRAP_CONTENT;
//TODO set gravity to CENTER
gridParams.setGravity(Gravity.CENTER);
//TODO create GridLayout
GridLayout gridLayout = new GridLayout(context);
//TODO set Grid Params
gridLayout.setLayoutParams(gridParams);
//TODO create TextView
TextView textView = new TextView(context);
textView.setText("Text 1");
//TODO add to Grid
gridLayout.addView(textView);
setContentView(gridLayout);
Android Studio version 2.3.3
Tested in Tablet running Android 4.2.2
EDIT Working
RelativeLayout.LayoutParams layoutParams =
new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
RelativeLayout parentRelativeLayout = new RelativeLayout(context);
parentRelativeLayout.setLayoutParams(layoutParams);
parentRelativeLayout.setGravity(Gravity.CENTER);
parentRelativeLayout.addView(gridLayout);
Your grid layout needs to be inside another layout like RelativeLayout that has a width and height of match parent.
Its not that it isn't working, just think of it like this, the gridLayout is only big enough to contain its own containers, which isn't the size of the screen.
Try this.
GridLayout.LayoutParams gridParams = new GridLayout.LayoutParams();
gridParams.height = GridLayout.LayoutParams.WRAP_CONTENT;
gridParams.width = GridLayout.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.CENTER;
params.weight=1.0f;
//TODO create Grid params

Gravity set dynamically not working with Framelayout

FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
params.gravity = Gravity.BOTTOM;
myFrameLayout.setLayoutParams(params);
I have only a text-view inside my frame-layout and I want to set its gravity to bottom dynamically in some condition. I am trying with this code but its not working.
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top|center_horizontal">
<TextView
android:id="#+id/preview_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
params.gravity = Gravity.BOTTOM;
myTextView.setLayoutParams(params);
Use this code which sets the params to instance of textview.
maybe you are trying to do it on OnCreate, and the frame layout is not yet created , you can try using
ViewTreeObserver viewTreeObserver = myFrameLayout.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
myFrameLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
params.gravity = Gravity.BOTTOM;
myFrameLayout..setLayoutParams(params);
}
}
}
this will set the gravity only after the frame layout created.
Try to use Linear Layout instead of Frame Layout or use linear layout inside your frame layout.

Show a SnackBar on the top (below of the toolbar)

I'm trying to show a SnackBar on top below of the ToolBar in my MainActivity,
I've tried this code :
mToolbar = (Toolbar) findViewById(R.id.toolbar);
Snackbar snack = Snackbar.make(findViewById(android.R.id.content), "Had a snack at Snackbar", Snackbar.LENGTH_LONG);
View view = snack.getView();
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.TOP;
view.setLayoutParams(params);
snack.show();
but the SnackBar is showing on the top, but not below the Toolbar.
I want something similar to Hangout application like :
Main Activity:
<android.support.design.widget.CoordinatorLayout 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"
android:id="#+id/Coordinator"
xmlns:fab="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<ImageView
android:layout_width="75dp"
android:layout_height="28dp"
android:src="#drawable/athena"/>
</android.support.v7.widget.Toolbar>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progressBar5"
android:layout_marginTop="10dp"
android:layout_gravity="center_horizontal" />
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
<com.melnykov.fab.FloatingActionButton
android:id="#+id/add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
fab:fab_colorNormal="#color/colorPrimary"
android:src="#drawable/ic_action_name9" />
</android.support.design.widget.CoordinatorLayout>
I'm using TSnackbar, the SnackBar is showing over the toolbar
TSnackbar.make(findViewById(android.R.id.content),"Hello from TSnackBar.",TSnackbar.LENGTH_LONG).show();
set margin on top of snackbar
Snackbar snack = Snackbar.make(findViewById(android.R.id.content), "Had a snack at Snackbar", Snackbar.LENGTH_LONG);
View view = snack.getView();
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
// calculate actionbar height
TypedValue tv = new TypedValue();
int actionBarHeight=0;
if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true))
{
actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}
// set margin
params.setMargins(0, actionBarHeight, 0, 0);
view.setLayoutParams(params);
snack.show();
use PopupWindow using handler as
if(!topPopupWindow.isShowing()){
topPopupWindow.showAsDropDown(toolbar);
}
handler.removeMessages(0);
handler.sendEmptyMessageDelayed(0,2500);
This worked for me,
set top margin for your snackbar, consider your toolbar size:
View view = snack.getView();
CoordinatorLayout.LayoutParams params2 =(CoordinatorLayout.LayoutParams)view.getLayoutParams();
params2.setMargins(0,50,0,0);
I am giving below the code that I have used in my app and which is working properly for range of devices
Complie : compile 'com.androidadvance:topsnackbar:1.1.1'
define view :
private CoordinatorLayout CSnakbarLayout;
CSnakbarLayout = (CoordinatorLayout) rootView.findViewById(R.id.snackbar_event_mesg);
XML :
<android.support.design.widget.CoordinatorLayout
android:id="#+id/snackbar_event_mesg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
Below code in the activity / Fragment you want to implement the Snackbar from top :
/**
* Method to display message for on going Event
*/
private void displaySnackbar() {
int duration = 4000;
final TSnackbar snackbar = TSnackbar.make(CSnakbarLayout, getString(R.string.on_going_event_mesg), TSnackbar.LENGTH_INDEFINITE);
snackbar.setActionTextColor(Color.WHITE);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
try {
snackbar.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
}
}, duration);
snackbar.setAction("Ok", new View.OnClickListener() {
#Override
public void onClick(View view) {
snackbar.dismiss();
}
});
View snackbarView = snackbar.getView();
ViewGroup.LayoutParams params = snackbarView.getLayoutParams();
params.height = 300;
snackbarView.setLayoutParams(params);
snackbarView.setBackgroundColor(Color.BLACK);
TextView textView = (TextView) snackbarView.findViewById(com.androidadvance.topsnackbar.R.id.snackbar_text);
textView.setTextColor(Color.WHITE);
textView.setMaxLines(5);
snackbar.show();
}
Thank you :)
Got a solution in Kotlin, Give a try :)
val mainLayout: ConstraintLayout = root.findViewById(R.id.main_layout)
val button: Button = root.findViewById(R.id.button)
button.setOnClickListener {
val snackBar = TSnackbar.make(mainLayout, "Snacking with VectorDrawable", TSnackbar.LENGTH_INDEFINITE)
snackBar.setActionTextColor(Color.WHITE)
snackBar.setIconLeft(R.drawable.ic_announcement_black_24dp, 24f)
val snackBarView = snackBar.view
val tv = TypedValue()
if (activity!!.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
val actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, resources.displayMetrics)
val params = view!!.getLayoutParams() as FrameLayout.LayoutParams
params.setMargins(0, actionBarHeight, 0, 0)
params.height = 70
snackBarView.setLayoutParams(params)
}
snackBarView.setBackgroundColor(Color.parseColor("#CC00CC"))
val textView = snackBarView.findViewById(com.androidadvance.topsnackbar.R.id.snackbar_text) as TextView
textView.setTextColor(Color.YELLOW)
snackBar.setIconPadding(10)
snackBar.show()
}
Thanks to #Shijil solution i've managed to display MinimalKSnack below the toolbar.
MinimalKSnack minimalKSnack = new MinimalKSnack(MainActivity.this);
minimalKSnack.setMessage(getResources().getString(R.string.notification))
.setStyle(MinimalKSnackStyle.STYLE_SUCCESS)
.setBackgroundColor(R.color.metallic_blue)
.setAnimation(Fade.In.getAnimation(), Fade.Out.getAnimation())
.setDuration(2000);
View view = minimalKSnack.getMinimalSnackView();
LinearLayout.LayoutParams params =(LinearLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.CENTER_VERTICAL | Gravity.TOP;
TypedValue typedValue = new TypedValue();
int actionBarHeight =0;
if(getTheme().resolveAttribute(R.attr.actionBarSize,typedValue,true)){
actionBarHeight = TypedValue.complexToDimensionPixelOffset(typedValue.data,getResources().getDisplayMetrics());
}
params.setMargins(0,actionBarHeight,0,0);
view.setLayoutParams(params);
minimalKSnack.show();
Github Library link onurkagan /
KSnack

How to show Snackbar at top of the screen

As the Android documentation says
Snackbars provide lightweight feedback about an operation. They show a brief message at the bottom of the screen on mobile and lower left on larger devices.
Is there any alternative by which we can show snackbars at top of the screen instead of the bottom?
Right now I am doing something like this which shows a snackbar at the bottom of the screen.
Snackbar.make(findViewById(android.R.id.content), "Hello this is a snackbar!!!",
Snackbar.LENGTH_LONG).setAction("Undo", mOnClickListener)
.setActionTextColor(Color.RED)
.show();
It is possible to make the snackbar appear on top of the screen using this:
Snackbar snack = Snackbar.make(parentLayout, str, Snackbar.LENGTH_LONG);
View view = snack.getView();
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.TOP;
view.setLayoutParams(params);
snack.show();
From the OP:
I had to change the first line:
Snackbar snack = Snackbar.make(findViewById(android.R.id.content), "Had a snack at Snackbar", Snackbar.LENGTH_LONG);
CoordinatorLayout coordinatorLayout=(CoordinatorLayout)findViewById(R.id.coordinatorLayout);
Snackbar snackbar = Snackbar.make(coordinatorLayout, "Text", Snackbar.LENGTH_LONG);
View view = snackbar.getView();
CoordinatorLayout.LayoutParams params=(CoordinatorLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.TOP;
view.setLayoutParams(params);
snackbar.show();
Kotlin-
val snackBarView = Snackbar.make(view, "SnackBar Message" , Snackbar.LENGTH_LONG)
val view = snackBarView.view
val params = view.layoutParams as FrameLayout.LayoutParams
params.gravity = Gravity.TOP
view.layoutParams = params
view.background = ContextCompat.getDrawable(context,R.drawable.custom_drawable) // for custom background
snackBarView.animationMode = BaseTransientBottomBar.ANIMATION_MODE_FADE
snackBarView.show()
below line will resolve the animation issue.
snackBarView.animationMode = BaseTransientBottomBar.ANIMATION_MODE_FADE
Alternate solution-
snackBarView.anchorView = mention viewId above whom you want to show SnackBar
You can do the following to position a SnackBar anywhere inside a layout (This method has No Animation Issues)
1) According to:
https://developer.android.com/reference/android/support/design/widget/Snackbar.html#make(android.view.View, java.lang.CharSequence, int)
Snackbar make (View view,
CharSequence text,
int duration)
Make a Snackbar to display a message Snackbar will try and find a parent view to hold Snackbar's view from
the value given to view. Snackbar will walk up the view tree trying to
find a suitable parent, which is defined as a CoordinatorLayout or the
window decor's content view, whichever comes first.
So, one can position a snackBar anywhere inside a layout simply by adding a Coordinator Layout in the desired location and using that Coordinator Layout as the view argument inside Snackbar.make method above.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity"
android:orientation="vertical"
android:id="#+id/rl"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Coordinator Layout used to position the SnackBar -->
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cl"
android:layout_alignParentTop="true"
android:background="#android:color/transparent">
</android.support.design.widget.CoordinatorLayout>
<!-- add your layout here -->
</RelativeLayout>
2) The Coordinator Layout used to display the SnackBar should be on top of all other views (highest elevation). In order to do that, one might either call bringToFront() on the coordinator layout or elevate the coordinator layout (add
android:elevation="10dp" for example)
3) At this point the snackBar will show up in the desired location, but the snackBar is displayed with a bottom to top animation (default behavior). In order to achieve a top to bottom animation, you can do the following:
Rotate Coordinator layout used inside Snackbar.make method by 180 degrees
4) After step 3, the snackBar will be displayed with a top to bottom animation, but the message and action text are rotated and the gravity is reversed, so as a final step, I did the following:
Got SnackBar View, found the LinearLayout holding the TextView responsible about displaying the message and the TextView responsible about the action, and rotated the parent LinearLayout by 180 degress
5) Example:
public class MainActivity extends AppCompatActivity {
private final String TAG = MainActivity.class.getSimpleName();
private RelativeLayout rl;
private CoordinatorLayout cl;
private CoordinatorLayout cl1;
private CoordinatorLayout cl2;
private CoordinatorLayout cl3;
private CoordinatorLayout cl4;
private Snackbar snackbar_updated;
private Snackbar snackbar_updated1;
private Snackbar snackbar_updated2;
private Snackbar snackbar_updated3;
private Snackbar snackbar_updated4;
private Snackbar snackbar_ordinary;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rl = (RelativeLayout) findViewById(R.id.rl);
cl = (CoordinatorLayout) findViewById(R.id.cl);
cl1 = (CoordinatorLayout) findViewById(R.id.cl1);
cl2 = (CoordinatorLayout) findViewById(R.id.cl2);
cl3 = (CoordinatorLayout) findViewById(R.id.cl3);
cl4 = (CoordinatorLayout) findViewById(R.id.cl4);
cl.bringToFront();
cl1.bringToFront();
cl2.bringToFront();
cl3.bringToFront();
cl4.bringToFront();
snackbar_updated = Snackbar.make(cl, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated.setAction("Ok", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
/** Snackbar message and action TextViews are placed inside a LinearLayout
*/
final Snackbar.SnackbarLayout snackBarLayout = (Snackbar.SnackbarLayout) snackbar_updated.getView();
for (int i = 0; i < snackBarLayout.getChildCount(); i++) {
View parent = snackBarLayout.getChildAt(i);
if (parent instanceof LinearLayout) {
((LinearLayout) parent).setRotation(180);
break;
}
}
snackbar_updated1 = Snackbar.make(cl1, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated1.setAction("Ok", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
/** Snackbar message and action TextViews are placed inside a LinearLayout
*/
final Snackbar.SnackbarLayout snackBarLayout1 = (Snackbar.SnackbarLayout) snackbar_updated1.getView();
for (int i = 0; i < snackBarLayout1.getChildCount(); i++) {
View parent = snackBarLayout1.getChildAt(i);
if (parent instanceof LinearLayout) {
((LinearLayout) parent).setRotation(180);
break;
}
}
snackbar_updated2 = Snackbar.make(cl2, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated2.setAction("Ok", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
snackbar_updated3 = Snackbar.make(cl3, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated3.setAction("Ok", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
/** Snackbar message and action TextViews are placed inside a LinearLayout
*/
Snackbar.SnackbarLayout snackBarLayout3 = (Snackbar.SnackbarLayout) snackbar_updated3.getView();
for (int i = 0; i < snackBarLayout3.getChildCount(); i++) {
View parent = snackBarLayout3.getChildAt(i);
if (parent instanceof LinearLayout) {
((LinearLayout) parent).setRotation(180);
break;
}
}
snackbar_updated4 = Snackbar.make(cl4, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_updated4.setAction("Ok", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
snackbar_ordinary = Snackbar.make(rl, "Message", Snackbar.LENGTH_INDEFINITE);
snackbar_ordinary.setAction("Ok", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
rl.post(new Runnable() {
#Override
public void run() {
snackbar_updated.show();
rl.postDelayed(new Runnable() {
#Override
public void run() {
snackbar_updated1.show();
rl.postDelayed(new Runnable() {
#Override
public void run() {
snackbar_updated2.show();
rl.postDelayed(new Runnable() {
#Override
public void run() {
snackbar_updated3.show();
rl.postDelayed(new Runnable() {
#Override
public void run() {
snackbar_updated4.show();
rl.postDelayed(new Runnable() {
#Override
public void run() {
snackbar_ordinary.show();
}
}, 2000);
}
}, 2000);
}
}, 2000);
}
}, 2000);
}
}, 2000);
}
});
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity"
android:orientation="vertical"
android:id="#+id/rl"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Coordinator Layout used to position the SnackBar -->
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cl"
android:rotation="180"
android:layout_alignParentTop="true"
android:background="#android:color/transparent">
</android.support.design.widget.CoordinatorLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:itemIconTint="#333"
app:itemTextColor="#333"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="#id/appbar"
android:layout_gravity="bottom">
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:id="#+id/tv_top"
android:text="Layout Top"
android:gravity="center"
android:textSize="15sp"
android:textColor="#android:color/white"
android:layout_alignParentTop="true"
android:background="#color/colorAccent">
</TextView>
<!-- Coordinator Layout used to position the SnackBar -->
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cl1"
android:rotation="180"
android:layout_below="#id/tv_top"
android:background="#android:color/transparent">
</android.support.design.widget.CoordinatorLayout>
<!-- Coordinator Layout used to position the SnackBar -->
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cl2"
android:paddingBottom="75dp"
android:layout_centerInParent="true"
android:background="#android:color/transparent">
</android.support.design.widget.CoordinatorLayout>
<!-- Coordinator Layout used to position the SnackBar -->
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:id="#+id/tv_center"
android:text="Center"
android:gravity="center"
android:textSize="15sp"
android:layout_centerInParent="true"
android:textColor="#android:color/white"
android:background="#color/colorAccent">
</TextView>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cl3"
android:rotation="180"
android:paddingBottom="75dp"
android:layout_centerInParent="true"
android:background="#android:color/transparent">
</android.support.design.widget.CoordinatorLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:id="#+id/tv_bottom"
android:text="Layout Bottom"
android:gravity="center"
android:textSize="15sp"
android:textColor="#android:color/white"
android:layout_alignParentBottom="true"
android:background="#color/colorAccent">
</TextView>
<!-- Coordinator Layout used to position the SnackBar -->
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cl4"
android:layout_above="#id/tv_bottom"
android:background="#android:color/transparent">
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
6) Result:
Combined solution from the above ones:
final ViewGroup.LayoutParams params = snackbar.getView().getLayoutParams();
if (params instanceof CoordinatorLayout.LayoutParams) {
((CoordinatorLayout.LayoutParams) params).gravity = Gravity.TOP;
} else {
((FrameLayout.LayoutParams) params).gravity = Gravity.TOP;
}
snackbar.getView().setLayoutParams(params);
Still suffers from the improper animation.
This makes the Snackbar appears on Top without the strange slide in transition.
Best simple solution in Kotlin:
val snackbar = Snackbar.make(view, string, Snackbar.LENGTH_LONG)
val layoutParams = LayoutParams(snackbar.view.layoutParams)
layoutParams.gravity = Gravity.TOP
snackbar.view.setPadding(0, 10, 0, 0)
snackbar.view.layoutParams = layoutParams
snackbar.animationMode = BaseTransientBottomBar.ANIMATION_MODE_FADE
snackbar.show()
Idiomatic Kotlin version
snackbar.view.layoutParams = (snackbar.view.layoutParams as FrameLayout.LayoutParams).apply {
gravity = Gravity.TOP
}
Kotlin extension
/** Kotlin extension that adds this snackbar at the top of the screen. */
fun Snackbar.gravityTop() {
this.view.layoutParams = (this.view.layoutParams as FrameLayout.LayoutParams).apply {
gravity = Gravity.TOP
}
}
Then just call:
snackbar.gravityTop()
Before displaying the Snackbar, please add the following code
View snackbarView = snackbar.getView();
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) snackbarView.getLayoutParams();
params.gravity = Gravity.TOP;
snackbarView.setLayoutParams(params);
snackbarView.startAnimation(AnimationUtils.loadAnimation(host, R.anim.slide_in_snack_bar));
And when dismiss()
View snackbarView = snackbar.getView();
snackbarView.startAnimation(AnimationUtils.loadAnimation(_snackbar.getContext(), R.anim.slide_out_snack_bar));
snackbar.dismiss()
slide_in_snack_bar.xml
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="-100%p"
android:toYDelta="0%p" />
slide_out_snack_bar.xml
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_longAnimTime"
android:fromYDelta="0%p"
android:toYDelta="-100%p" />
if you are using Constraintlayoutas as the root parent, with the help of Guidelines and CoordinatorLayout you can try this:
changing the value of: layout_constraintGuide_end="Your bottom margin value" inside Guideline as below example.
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/guideline3" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_end="150dp" />
in the activty you can pass CoordinatorLayout as the view for the snackbar
mSnackBar = Snackbar.make(
coordinator,
getString(R.string.no_internet_connection),
Snackbar.LENGTH_INDEFINITE
)
mSnackBar.show()
why not anchor it to some other view say you have other views in layout just anchor the snackbar to some view so that it displays there for example:
<LinearLayout>
......<Button>
<LinearLayout>
<TextView>
</LinearLayout>
</LinearLayout>
in code:
Snackbar snackbar = Snackbar.make(view,message, snackbar.LENGTH_SHORT).setAnchorView(R.id.reg_button);
R.id.reg_button is the button in the layout it can be anywhere snackbar will show up right there
No need to use any frame etc app will function as expected will not crash
2 years later, here's my solution..
Setting the Top and Bottom Margin changes the effect result,... I have tried to add as much customization options as i could, Overriding the animation is another option not written here.
Thanks to everyone's answers on several questions...
{
// usage for setSnackBar
int view = R.id.toolbar;
String snackMessage = "";
boolean useAction = false;
Runnable ifUseActionRunnable = null;
String actionText = "";
int leftMargin = 0;
int topMargin = 0;
int rightMargin = 0;
int bottomMargin = 0;
int backgroundColour = Color.BLACK;
int textColor = Color.WHITE;
int duration = Snackbar.LENGTH_LONG;
setSnackBar(view, snackMessage, useAction, ifUseActionRunnable, actionText, leftMargin, topMargin, rightMargin, bottomMargin, backgroundColour, textColor, duration);
}
Snackbar snb;
public void setSnackBar(int targetView, String snackMessage, boolean useAction, final Runnable ifUseActionRunnable, String actionText , int leftMargin, int topMargin, int rightMargin, int bottomMargin, int backgroundColour, int textColor, int duration)
{
snb = Snackbar.make(findViewById(targetView), snackMessage, duration);
View view = snb.getView();
view.setBackgroundColor(backgroundColour);
snb.setActionTextColor(textColor);
FrameLayout.LayoutParams params =(FrameLayout.LayoutParams)view.getLayoutParams();
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
params.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
view.setLayoutParams(params);
if (useAction)
{
snb.setAction(actionText, new View.OnClickListener(){
#Override
public void onClick(View p1)
{
ifUseActionRunnable.run();
}
});
}
if (snb.isShown())
{
snb.dismiss();
snb.show();
}
else
{
snb.show();
}
}
to show Snackbar at top of the screen (kotlin)
// Custom snackbar : banner model
val customSnackBar = Snackbar.make(snackbar_id, "", Snackbar.LENGTH_INDEFINITE)
val view = customSnackBar.view
val params = view.layoutParams as CoordinatorLayout.LayoutParams
params.gravity = Gravity.TOP
view.layoutParams = params
val layout = customSnackBar.view as Snackbar.SnackbarLayout
val customSnackView = layoutInflater.inflate(R.layout.snackbar_banner, null)
val actionButton1 = customSnackView.findViewById(R.id.action_button_1) as MaterialButton
actionButton1.setOnClickListener {
customSnackBar.dismiss()
}
val actionButton = customSnackView.findViewById(R.id.action_button_2) as MaterialButton
actionButton.setOnClickListener {
customSnackBar.dismiss()
}
// We can also customize the above controls
layout.setPadding(0, 0, 0, 0)
layout.addView(customSnackView, 0)
customSnackBar.show()
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#android:color/white"
>
<TextView
android:padding="16dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/snackbar_banner_message"
android:textColor="#android:color/black"
android:textSize="16sp" />
<LinearLayout
android:gravity="end"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="#+id/action_button_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:background="#android:color/black"
android:text="Close"
style="#style/Widget.MaterialComponents.Button.TextButton"
/>
<com.google.android.material.button.MaterialButton
android:id="#+id/action_button_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/black"
android:text="Fix it"
android:textStyle="bold"
style="#style/Widget.MaterialComponents.Button.TextButton"
/>
</LinearLayout>
</LinearLayout>

set width of custom dialog to wrap content android

I want to set the width of custom dialog to wrap content
but always it fill all the width of the screen
I have tested this
android.view.WindowManager.LayoutParams params = mydialog.getWindow().getAttributes();
params.width = android.view.WindowManager.LayoutParams.WRAP_CONTENT;
mydialog.getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
and that
mydialog.getWindow().setLayout(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
I also having a hard time in solving this problem and finally got a better way in solving this.
Here is the workaround. In your code
mydialog.getWindow().setLayout(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
This is not working because the default layout for ProgressDialog has match_parent with margins left and right. To resize the ProgressDialog you need a Custom View like below:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#android:drawable/dialog_holo_light_frame"
android:layout_gravity="center_horizontal"
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ProgressBar
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginLeft="30dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/progressBar"/>
<TextView
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginRight="30dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:gravity="center"
android:id="#+id/message"/>
</LinearLayout>
and inflate it after showing the ProgressDialog. After inflating the custom view, get the width of the custom view by using the GlobalLayoutListener and set the layout width.
mDialog.show();
final Window window = mDialog.getWindow();
window.setContentView(R.layout.custom_progress_dialog); // this is the above code
final LinearLayout dialogContainer = (LinearLayout) window.findViewById(R.id.container);
TextView message = (TextView) window.findViewById(R.id.message);
message.setText("Loading . . .");
dialogContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int width = dialogContainer.getWidth();
window.setLayout(width, WindowManager.LayoutParams.WRAP_CONTENT);
dialogContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
I know this question is old, but if someone doesn't want to add WindowManager.LayoutParams then just set theme of the dialog to android.R.style.Theme_Holo_Light_Dialog_NoActionBar this will make the dialog to wrap it's width to its contents.
Example:
AlertDialog alert = new AlertDialog.Builder(context, android.R.style.Theme_Holo_Light_Dialog_NoActionBar).create();
Make sure that the layout you are inflating is set to wrap_content for both height and width.
Did you try using this
mydialog.getWindow().setLayout(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
after writing mydialog.show()?
That should work.
Try below code to have a dialog with wrap content.
(In dialogs layout xml use layout_width= WRAP_PATENT and height as WRAP_CONTENT)
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(dialog.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
dialog.show();
dialog.getWindow().setAttributes(lp);
set style to custom dialog with following attribute:
<style name="CustomDialogTheme" parent="#android:style/Theme.Dialog">
<item name="android:windowIsFloating">false</item>
</style>

Categories

Resources