答案 0 :(得分:17)
答案 1 :(得分:4)
由于@Elias N回答每个Snackbar
可能包含一个动作。如果您想在Snackbar
中设置更多操作,则需要创建自己的布局。请试试这个我希望这会对你有帮助。
创建一个xml文件 my_snackbar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#000000">
<TextView
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight=".7"
android:gravity="center_vertical"
android:text="Please select any one"
android:textColor="@color/white"/>
<TextView
android:id="@+id/txtOne"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight=".1"
android:gravity="center"
android:text="ONE"
android:textColor="@color/red"/>
<TextView
android:id="@+id/txtTwo"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight=".1"
android:gravity="center"
android:text="TWO"
android:textColor="@color/red"/>
</LinearLayout>
现在,在您的活动文件中,执行以下代码。
public void myCustomSnackbar()
{
// Create the Snackbar
LinearLayout.LayoutParams objLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
Snackbar snackbar = Snackbar.make(llShow, "", Snackbar.LENGTH_LONG);
// Get the Snackbar's layout view
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView();
layout.setPadding(0,0,0,0);
// Hide the text
TextView textView = (TextView) layout.findViewById(android.support.design.R.id.snackbar_text);
textView.setVisibility(View.INVISIBLE);
LayoutInflater mInflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
// Inflate our custom view
View snackView = getLayoutInflater().inflate(R.layout.my_snackbar, null);
// Configure the view
TextView textViewOne = (TextView) snackView.findViewById(R.id.txtOne);
textViewOne.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("One", "First one is clicked");
}
});
TextView textViewTwo = (TextView) snackView.findViewById(R.id.txtTwo);
textViewTwo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("Two", "Second one is clicked");
}
});
// Add the view to the Snackbar's layout
layout.addView(snackView, objLayoutParams);
// Show the Snackbar
snackbar.show();
}
有关详细信息,请参阅this documentation和here。
答案 2 :(得分:3)
感谢Shailesh,我不得不修改代码以使其适用于我。
my_snackbar.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:id="@+id/my_snackbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/dark_grey"
android:padding="15dp">
<TextView
android:id="@+id/message_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".6"
android:gravity="center_vertical"
android:text="Two button snackbar"
android:textColor="@color/white"/>
<TextView
android:id="@+id/first_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".2"
android:gravity="center"
android:text="ONE"
android:textColor="#FFDEAD"/>
<TextView
android:id="@+id/second_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".2"
android:gravity="center"
android:text="TWO"
android:textColor="#FFDEAD"/>
</LinearLayout>
在您的活动中,只要您想要显示小吃栏,请调用此方法:
private void showTwoButtonSnackbar() {
// Create the Snackbar
LinearLayout.LayoutParams objLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
snackbar = Snackbar.make(this.findViewById(android.R.id.content), message, Snackbar.LENGTH_INDEFINITE);
// Get the Snackbar layout view
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView();
// Set snackbar layout params
int navbarHeight = getNavBarHeight(this);
FrameLayout.LayoutParams parentParams = (FrameLayout.LayoutParams) layout.getLayoutParams();
parentParams.setMargins(0, 0, 0, 0 - navbarHeight + 50);
layout.setLayoutParams(parentParams);
layout.setPadding(0, 0, 0, 0);
layout.setLayoutParams(parentParams);
// Inflate our custom view
View snackView = getLayoutInflater().inflate(R.layout.my_snackbar, null);
// Configure our custom view
TextView messageTextView = (TextView) snackView.findViewById(R.id.message_text_view);
messageTextView.setText(message);
TextView textViewOne = (TextView) snackView.findViewById(R.id.first_text_view);
textViewOne.setText("ALLOW");
textViewOne.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Allow", "showTwoButtonSnackbar() : allow clicked");
snackbar.dismiss();
}
});
TextView textViewTwo = (TextView) snackView.findViewById(R.id.second_text_view);
textViewTwo.setText("DENY");
textViewTwo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("Deny", "showTwoButtonSnackbar() : deny clicked");
snackbar.dismiss();
}
});
// Add our custom view to the Snackbar's layout
layout.addView(snackView, objLayoutParams);
// Show the Snackbar
snackbar.show();
}
获取导航栏高度:
public static int getNavBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
答案 3 :(得分:0)
你可以尝试的其他hacky解决方法(在我的情况下有效)。
final Snackbar snackbar = Snackbar.make(view, "UNDO MARKED AS READ", Snackbar.LENGTH_LONG);
snackbar.setAction("DISMISS", new View.OnClickListener() {
@Override
public void onClick(View v) {
if (snackbar != null)
snackbar.dismiss();
}
});
View snackbarView = snackbar.getView();
int snackbarTextId = android.support.design.R.id.snackbar_text;
TextView textView = (TextView) snackbarView.findViewById(snackbarTextId);
textView.setTextColor(Color.WHITE);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (snackbar != null)
snackbar.dismiss();
// undo mark as unread code
}
});
snackbar.show();
答案 4 :(得分:0)
您可以使用BottomSheetDialog
并将其伪装成SnackBar。唯一不同的是,它会被向下滑而不是向右被解雇,它可以留在那里,直到用户解雇它,而SnackBar最终消失。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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/fragment_history_menu_bottom"
style="@style/Widget.Design.BottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal"
android:background="@color/cardview_dark_background"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/appCompatTextView"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
android:layout_weight="0.6"
android:text="Load More ?"
android:textAppearance="@style/TextAppearance.Design.Snackbar.Message"
android:textColor="@color/cardview_light_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/fragment_history_bottom_sheet_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:layout_weight="0.4"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<android.support.v7.widget.AppCompatButton
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Yes" />
<android.support.v7.widget.AppCompatButton
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No"
android:textColor="@color/cardview_light_background" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
并将其用作以下(Kotlin)
val dialog = BottomSheetDialog(this)
dialog.setContentView(this.layoutInflater.inflate(R.layout.bottom_sheet_load_prompt,null))
dialog.show()
结果类似于SnackBar
答案 5 :(得分:0)
以下Shaileshs解决方案:
小吃店类
public class SnackbarOfflineErrorNotification {
/**
* A view from the content layout.
*/
@NonNull
private final View view;
@NonNull
private Context context;
/**
* The snack bar being shown.
*/
@Nullable
private Snackbar snackbar = null;
/**
* Construct a new instance of the notification.
*
* @param view A view from the content layout, used to seek an appropriate anchor for the
* Snackbar.
*/
public SnackbarOfflineErrorNotification(@NonNull final View view, @NonNull Context context) {
this.view = view;
this.context = context;
}
public void showOfflineError (){
if (snackbar == null){
//create snackbar
snackbar = Snackbar.make(this.view, R.string.offline_text, LENGTH_INDEFINITE);
// Create the Snackbar
LinearLayout.LayoutParams objLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
// Get the Snackbar's layout view
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView();
layout.setPadding(0,0,0,0);
// Hide the text
TextView textView = (TextView) layout.findViewById(android.support.design.R.id.snackbar_text);
textView.setVisibility(View.INVISIBLE);
// Inflate our custom view
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View snackView = inflater.inflate(R.layout.snackbar_offline, null);
// Configure the view
Button btnOne = (Button) snackView.findViewById(R.id.btnOne);
btnOne.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// action 1
}
});
Button btnTwo = (Button) snackView.findViewById(R.id.btnTwo);
btnTwo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// action 2
}
});
// Add the view to the Snackbar's layout
layout.addView(snackView, objLayoutParams);
// Show the Snackbar
snackbar.show();
}
}
/**
* Hides the currently displayed error.
*/
public void hideError() {
if (snackbar != null) {
snackbar.dismiss();
snackbar = null;
}
}
}
快餐栏xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#000000">
<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_weight=".7"
android:gravity="center_vertical"
android:text="offline"
android:textColor="@color/white"
android:paddingLeft="16dp"/>
<Button
android:id="@+id/btnOne"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_weight=".1"
android:gravity="center"
android:text="one" />
<Button
android:id="@+id/btnTwo"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_weight=".1"
android:gravity="center"
android:text="two"/>
</LinearLayout>
目标活动
constructor(){
snackbarOfflineErrorNotification = new SnackbarOfflineErrorNotification(findViewById(R.id.coordinator_layout), getApplicationContext());
}
public void hideSnackbar(){
snackbarOfflineErrorNotification.hideError();
}
public showSnackbar(){
snackbarOfflineErrorNotification.showOfflineError();
}
答案 6 :(得分:0)
您可以使用“关闭”作为其他操作
Snackbar snackbar = Snackbar.make(requireView(), "Marked as read", BaseTransientBottomBar.LENGTH_SHORT);
snackbar.setAction("undo", view -> {
//undo action
});
snackbar.addCallback(new Snackbar.Callback() {
@Override
public void onDismissed(Snackbar transientBottomBar, int event) {
//dismiss action
}
});
snackbar.show();
答案 7 :(得分:0)
这是一个带有 Kotlin 的 proper solution,我在处理 Fulguris 时第一次部署它。
使用 Kotlin 扩展,我们将 Snackbar 类扩展如下:
/**
* Adds an extra action button to this snackbar.
* [aLayoutId] must be a layout with a Button as root element.
* [aLabel] defines new button label string.
* [aListener] handles our new button click event.
*/
fun Snackbar.addAction(@LayoutRes aLayoutId: Int, @StringRes aLabel: Int, aListener: View.OnClickListener?) : Snackbar {
addAction(aLayoutId,context.getString(aLabel),aListener)
return this;
}
/**
* Adds an extra action button to this snackbar.
* [aLayoutId] must be a layout with a Button as root element.
* [aLabel] defines new button label string.
* [aListener] handles our new button click event.
*/
fun Snackbar.addAction(@LayoutRes aLayoutId: Int, aLabel: String, aListener: View.OnClickListener?) : Snackbar {
// Add our button
val button = LayoutInflater.from(view.context).inflate(aLayoutId, null) as Button
// Using our special knowledge of the snackbar action button id we can hook our extra button next to it
view.findViewById<Button>(R.id.snackbar_action).let {
// Copy layout
button.layoutParams = it.layoutParams
// Copy colors
(button as? Button)?.setTextColor(it.textColors)
(it.parent as? ViewGroup)?.addView(button)
}
button.text = aLabel
/** Ideally we should use [Snackbar.dispatchDismiss] instead of [Snackbar.dismiss] though that should do for now */
//extraView.setOnClickListener {this.dispatchDismiss(BaseCallback.DISMISS_EVENT_ACTION); aListener?.onClick(it)}
button.setOnClickListener {this.dismiss(); aListener?.onClick(it)}
return this;
}
然后我们需要定义我们的按钮资源:
<?xml version="1.0" encoding="utf-8"?>
<!--
Used to create and extra button in our snackbar popup messages.
Though most properties including layout params and colors are overridden at runtime.
They are just copied from the standard snackbar action button to make sure they both lookalike.
-->
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/snackbar_extra_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginStart="0dp"
android:layout_gravity="center_vertical|right|end"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:textColor="?attr/colorAccent"
style="?attr/borderlessButtonStyle"/>
这是你如何使用它:
Snackbar.make(aView, aMessage, aDuration).setAction(R.string.button_one) {
// Do your thing after regular button press
}.addAction(R.layout.snackbar_extra_button, R.string.button_two){
//Do your thing after extra button push
}.show()