正如Android文档所说
Snackbars提供有关操作的轻量级反馈。它们在移动屏幕底部显示简短消息,在较大设备上显示左下方。
我们可以在屏幕顶部而不是底部显示snackbars
吗?
现在我正在做这样的事情,在屏幕底部显示snackbar
。
Snackbar.make(findViewById(android.R.id.content), "Hello this is a snackbar!!!",
Snackbar.LENGTH_LONG).setAction("Undo", mOnClickListener)
.setActionTextColor(Color.RED)
.show();
答案 0 :(得分:153)
可以使用以下方法使小吃条显示在屏幕顶部:
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();
来自OP:
我不得不改变第一行:
Snackbar snack = Snackbar.make(findViewById(android.R.id.content), "Had a snack at Snackbar", Snackbar.LENGTH_LONG);
答案 1 :(得分:37)
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();
答案 2 :(得分:11)
以上组合的解决方案:
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);
仍然受到动画不当的影响。
答案 3 :(得分:3)
您可以执行以下操作将SnackBar放置在布局内的任何位置(此方法没有动画问题)
1)根据:
小吃店制作(查看视图, 字符序列文本, 整数持续时间)
制作一个Snackbar以显示一条消息 Snackbar将尝试找到一个父视图来保存Snackbar的视图 查看的值。小吃店将走上视图树,试图 查找合适的父对象,该父对象定义为CoordinatorLayout或 窗口装饰的内容视图,以先到者为准。
因此,只需在所需位置添加Coordinator Layout并将该Coordinator Layout用作上述Snackbar.make方法中的view自变量,就可以将快餐栏放置在布局内的任何位置。
<?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)用于显示SnackBar的协调器布局应位于所有其他视图的顶部(最高海拔)。为此,您可以在协调器布局上调用bringToFront()
或提升协调器布局(添加
例如android:elevation="10dp"
3)此时,snakeBar将显示在所需的位置,但以从底部到顶部的动画(默认行为)显示SnackBar。为了实现从上到下的动画,您可以执行以下操作:
4)在第3步之后,snakeBar将显示为从上到下的动画,但是消息和动作文本被旋转并且重力被反转,因此作为最后一步,我执行了以下操作:
5)示例:
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)结果:
答案 4 :(得分:1)
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()
snackBarView.animationMode = BaseTransientBottomBar.ANIMATION_MODE_FADE
上一行将解决动画问题。
替代解决方案- snackBarView.anchorView =要在其上面显示SnackBar的人提及viewId
答案 5 :(得分:1)
这使Snackbar出现在顶部,而不会出现奇怪的幻灯片。
科特林最好的简单解决方案:
public function login(Request $request)
{
if(Auth::attempt($credentials))
{
$userid = auth()->user()->id;
}
}
答案 6 :(得分:1)
在显示快餐栏之前,请添加以下代码
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));
当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" />
答案 7 :(得分:0)
2年后,这是我的解决方法。
设置顶部和底部边距会改变效果结果,...我已尝试添加尽可能多的自定义选项,覆盖动画是此处未编写的另一个选项。
感谢大家在几个问题上的回答...
{
// 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();
}
}
答案 8 :(得分:0)
在屏幕顶部显示小食(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>
答案 9 :(得分:0)
如果您使用 Constraintlayoutas
作为根父级,在指南和 CoordinatorLayout
的帮助下,您可以尝试:
更改 Guideline 中的 layout_constraintGuide_end="Your bottom margin value" 值,如下例所示。
<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" />
在活动中,您可以将 CoordinatorLayout 作为小吃店的视图传递
mSnackBar = Snackbar.make(
coordinator,
getString(R.string.no_internet_connection),
Snackbar.LENGTH_INDEFINITE
)
mSnackBar.show()