我们可以在Android中一次在Snack栏中执行2个不同的操作吗?

时间:2016-12-19 13:48:41

标签: android android-snackbar snackbar

我正在创建一个Android应用程序,我想在其中使用Snack Bar, 在那个小吃店里,我想要2个不同的单词,我们必须在这两个单词上执行2个不同的操作。

enter image description here

8 个答案:

答案 0 :(得分:17)

来自Google design specifications

  

每个小吃栏可能包含一个动作,其中任何一个都不能是“Dismiss”或“Cancel”。

对于多个操作,请使用对话框。

答案 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 documentationhere

答案 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

Similar to 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()