首页 > 解决方案 > 我无法在 Android 的 CustomSnackbar 上编写 setAction 代码

问题描述

我有一个 CustomSnackBar 类和一个 Activity,我想在该 Activity 中显示一个 Snackbar。我有一个小吃店的自定义布局,但是当我在 CustomSnackBar 中编写 setAction 代码时出现问题,我的错误是:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.mohammaddvi.snappfood/com.test.mohammaddvi.snappfood.RestaurantDetails}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View com.test.mohammaddvi.snappfood.Model.CustomSnackBar.getContentView()' on a null object reference

我的 CustomSnackBar 是:

package com.test.mohammaddvi.snappfood.Model;
import android.content.Context;
import android.content.Intent;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.TextView;

import com.test.mohammaddvi.snappfood.BuyBasket;
import com.test.mohammaddvi.snappfood.MainActivity;

@SuppressWarnings("SpellCheckingInspection")
public class CustomSnackBar {

private LayoutInflater layoutInflater;
private int layout;
private int background;
private View contentView;
private LENGTH duration;
private boolean swipe;

private Snackbar snackbar;
private Snackbar.SnackbarLayout snackbarView;

private CustomSnackBar(Context context) {
    this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.duration = LENGTH.LONG;
    this.background = -1;
    this.layout = -1;
    this.swipe = true;
}

public static CustomSnackBar Builder(Context context) {
    return new CustomSnackBar(context);
}

public CustomSnackBar layout(int layout) {
    this.layout = layout;
    return this;
}

public CustomSnackBar background(int background) {
    this.background = background;
    return this;
}

public CustomSnackBar duration(LENGTH duration) {
    this.duration = duration;
    return this;
}

public CustomSnackBar swipe(boolean swipe) {
    this.swipe = swipe;
    return this;
}

public CustomSnackBar build(View view) {
    if (view == null) throw new CustomSnackbarException("view can not be null");
    if (layout == -1) throw new CustomSnackbarException("layout must be setted");
    switch (duration) {
        case INDEFINITE:
            snackbar = Snackbar.make(view, "", Snackbar.LENGTH_INDEFINITE);
            break;
        case SHORT:
            snackbar = Snackbar.make(view, "", Snackbar.LENGTH_SHORT);
            break;
        case LONG:
            snackbar = Snackbar.make(view, "", Snackbar.LENGTH_LONG);
            break;
    }
    snackbarView = (Snackbar.SnackbarLayout) snackbar.getView();

    if (!swipe) {
        snackbarView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                snackbarView.getViewTreeObserver().removeOnPreDrawListener(this);
                ((CoordinatorLayout.LayoutParams) snackbarView.getLayoutParams()).setBehavior(null);
                return true;
            }
        });
    }

    snackbarView.setPadding(0, 0, 0, 0);
    if (background != -1) snackbarView.setBackgroundResource(background);
    contentView = layoutInflater.inflate(layout, null);
    snackbarView.addView(contentView, 0);
    return this;
}

public void show() {
    snackbar.show();
}

public boolean isShowing() {
    return snackbar != null && snackbar.isShown();
}

public void dismiss() {
    if (snackbar != null) snackbar.dismiss();
}

public View getContentView() {
    return contentView;
}


public enum LENGTH {
    INDEFINITE, SHORT, LONG
}

public class CustomSnackbarException extends RuntimeException {

    public CustomSnackbarException(String detailMessage) {
        super(detailMessage);
    }

}
public void setAction(View v,CharSequence ch, int x){
    snackbar = Snackbar.make(v,ch,x).setAction("", new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            v.getContext().startActivity(new Intent(v.getContext(),MainActivity.class));
        }
    });
}

}

我的活动是:

package com.test.mohammaddvi.snappfood;


public class RestaurantDetails extends AppCompatActivity implements        MenuFragment.MenuFragmentListener {
private final static String TAG = RestaurantDetails.class.getName();
private ViewPager mViewPager;
private CustomSnackBar snackbar;
private Context context;
private android.support.v7.widget.Toolbar toolbar;
private CoordinatorLayout coordinatorLayout;
private TextView totalnumber;
private LayoutInflater layoutInflater;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_restaurant_details);
    mViewPager = (ViewPager) findViewById(R.id.viewpager);
    coordinatorLayout = findViewById(R.id.coordinatorlayout);
    TabLayout tabLayout = findViewById(R.id.tabs);
    toolbar = findViewById(R.id.toolbar);
    snackbar = new CustomSnackBar(this);
    setupViewPager(mViewPager);
    tabLayout.setupWithViewPager(mViewPager);


    snackbar=CustomSnackBar.Builder(RestaurantDetails.this)
            .layout(R.layout.snackview)
            .background(R.color.colorPrimary)
            .duration(CustomSnackBar.LENGTH.LONG)
            .swipe(true)
            .build(coordinatorLayout)
            .setAction();

    totalnumber = snackbar.getContentView().findViewById(R.id.totalnumber);
}

private void setupViewPager(ViewPager viewPager) {
    FragmentsAdapter adapter = new   FragmentsAdapter(getSupportFragmentManager());
    adapter.addFragment(new CommentFragment(), "نظرات");
    adapter.addFragment(new InfoFragment(), "اطلاعات");
    adapter.addFragment(new MenuFragment(), "منو");
    viewPager.setAdapter(adapter);
    viewPager.setOffscreenPageLimit(2); // this code for save screen info for 2 pages except the screen page
    viewPager.setCurrentItem(2); // this code is for setting first view of view pager
}


@Override
public void onMenuFragmentCount(int count) {
    totalnumber.setText(count + "");
    snackbar.show();
}

@Override
public void oMenuFragmentDismiss() {
    snackbar.dismiss();
}

}

如果你认为你需要什么来回答我,告诉我把它。我改变了我的 setAction:

    public CustomSnackBar setAction() {
    snackbar.setAction("", new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            v.getContext().startActivity(new Intent(v.getContext(), BuyBasket.class));
        }
    });
    return this;
}

我的日志是:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.test.mohammaddvi.snappfood, PID: 14112
              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.mohammaddvi.snappfood/com.test.mohammaddvi.snappfood.RestaurantDetails}: java.lang.ClassCastException: android.widget.FrameLayout cannot be cast to android.support.design.internal.SnackbarContentLayout
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2331)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2391)
                  at android.app.ActivityThread.access$800(ActivityThread.java:151)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:135)
                  at android.app.ActivityThread.main(ActivityThread.java:5349)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at java.lang.reflect.Method.invoke(Method.java:372)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
               Caused by: java.lang.ClassCastException: android.widget.FrameLayout cannot be cast to android.support.design.internal.SnackbarContentLayout
                  at android.support.design.widget.Snackbar.setAction(Snackbar.java:243)
                  at com.test.mohammaddvi.snappfood.Model.CustomSnackBar.setAction(CustomSnackBar.java:62)
                  at com.test.mohammaddvi.snappfood.RestaurantDetails.onCreate(RestaurantDetails.java:49)
                  at android.app.Activity.performCreate(Activity.java:6020)
                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2284)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2391) 
                  at android.app.ActivityThread.access$800(ActivityThread.java:151) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:135) 
                  at android.app.ActivityThread.main(ActivityThread.java:5349) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at java.lang.reflect.Method.invoke(Method.java:372) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703) 

这是我的小吃店布局:

and this is my snackbarlayout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
android:background="@color/colorPrimary">

<ImageView
    android:id="@+id/buybasket"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:layout_gravity="right|center_vertical"
    android:layout_marginRight="100dp"
    android:src="@drawable/basket" />

<TextView
    android:id="@+id/buybaskettext"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:fontFamily="@font/iranyekanregular"
    android:text="  مشاهده سبد خرید"
    android:textColor="#ffffff"
    android:textSize="18sp" />

<TextView
    android:id="@+id/totalnumber"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:layout_gravity="center_vertical|left"
    android:layout_marginStart="50dp"
    android:fontFamily="@font/iranyekanregular"
    android:gravity="center"
    android:text="0"
    android:textColor="#ffffff"
    android:textSize="18sp" />

标签: androidandroid-snackbar

解决方案


你进入nullpointerException这条线

totalnumber = snackbar.getContentView().findViewById(R.id.totalnumber);

因为你没有初始化snackbar这样做:

snackbar = new CustomSnackBar(this);
totalnumber = snackbar.getContentView().findViewById(R.id.totalnumber);

希望对你有帮助!!


推荐阅读