android - 我无法在 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" />
解决方案
你进入nullpointerException
这条线
totalnumber = snackbar.getContentView().findViewById(R.id.totalnumber);
因为你没有初始化snackbar
这样做:
snackbar = new CustomSnackBar(this);
totalnumber = snackbar.getContentView().findViewById(R.id.totalnumber);
希望对你有帮助!!
推荐阅读
- swift - 如何快速知道这个 NSObject 是类还是协议?
- node.js - 跟踪 Node.js 程序执行
- blazor-server-side - 如何在 Blazor 应用程序中将文件流发送到浏览器
- botframework - 向机器人发送消息:v3 directline.postActivity 与来自网络聊天商店的 v4 调度
- c# - DependencyObject 不依赖于 WPF?
- javascript - 如何避免使用分配给两个变量的随机数生成器生成相同的数字?
- android - Android - 试图停止处理程序
- vba - VBA将列表变成5列表
- c++ - 我正在尝试显示 Worley Noise,有人知道为什么输出看起来像这样吗?使用 SFML 2.5.1
- react-native - React Native openID Connect auth 密码流没有网络浏览器