【问题标题】:Snackbar in fragments gives IllegalArgumentException: No suitable parent found from the given view片段中的 Snackbar 给出 IllegalArgumentException:从给定视图中找不到合适的父级
【发布时间】:2019-05-21 14:04:57
【问题描述】:

我的应用程序有两个标签。对于标签,我使用片段。每个选项卡都有一个使用 Volley 的网络调用。对于凌空错误,我使用 Snackbar 来显示错误。我的问题是,如果我在触发错误时处于该特定片段中,则 Snackbar 运行良好。如果我在错误触发此错误之前返回。

Logcat..

12-21 09:11:18.782 3707-3707/com.dushanmadushanka.slicdashboard.slicdashboard E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.dushanmadushanka.slicdashboard.slicdashboard, PID: 3707
    java.lang.IllegalArgumentException: No suitable parent found from the given view. Please provide a valid view.
        at android.support.design.widget.Snackbar.make(Snackbar.java:181)
        at com.dushanmadushanka.slicdashboard.slicdashboard.other.VolleyErrorHandle.handleVolleyErrorThree(VolleyErrorHandle.java:102)
        at com.dushanmadushanka.slicdashboard.slicdashboard.fragment.general.GeneralRegionalFragment$4.onErrorResponse(GeneralRegionalFragment.java:288)
        at com.android.volley.Request.deliverError(Request.java:617)
        at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:104)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        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:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

片段...

    @Override
        public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            final View lView = inflater.inflate(R.layout.fragment_life_regional, container, false);

getTableJsonData(1, AppConfig.URL_GET, 1, lView);

    return lView;
    }

方法...

private void getTableJsonData(int currentMonth, String mUrl, int screenType, final View lView) {

    StringRequest stringRequest = new StringRequest(Request.Method.GET, newUrl, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {


        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            if (requestQueue != null) {
                myList.clear();
                lrAdapter.setJsonData(myList);
                VolleyErrorHandle.handleVolleyErrorThree(error, progressBar, lView.findViewById(R.id.fragment_life_region_layout));
            }
        }
    });
    //AppController.getInstance().addToRequestQueue(stringRequest, TAG_REQ);
    requestQueue.add(stringRequest);
    stringRequest.setRetryPolicy(new DefaultRetryPolicy(15 * 1000, 1,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}

小吃店....

public static void handleVolleyErrorThree(VolleyError error, ProgressBar p, View view) {
    if (error instanceof TimeoutError || error instanceof NoConnectionError) {
        Snackbar snackbar = Snackbar.make(view, "Please connect to the network!", Snackbar.LENGTH_LONG);
        View snackbarView = snackbar.getView();
        TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.WHITE);
        snackbarView.setBackgroundColor(Color.RED);
        snackbar.show();
    } else if (error instanceof AuthFailureError) {
        Snackbar snackbar = Snackbar.make(view, "Authentication error!", Snackbar.LENGTH_LONG);
        View snackbarView = snackbar.getView();
        TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.WHITE);
        snackbarView.setBackgroundColor(Color.RED);
        snackbar.show();
    } else if (error instanceof ServerError) {
        Snackbar snackbar = Snackbar.make(view, "No data!", Snackbar.LENGTH_LONG);
        View snackbarView = snackbar.getView();
        TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.WHITE);
        snackbarView.setBackgroundColor(Color.RED);
        snackbar.show();
    } else if (error instanceof NetworkError) {
        Snackbar snackbar = Snackbar.make(view, "Network error!", Snackbar.LENGTH_LONG);
        View snackbarView = snackbar.getView();
        TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.WHITE);
        snackbarView.setBackgroundColor(Color.RED);
        snackbar.show();
    } else if (error instanceof ParseError) {
        Snackbar snackbar = Snackbar.make(view, "Database connection error!", Snackbar.LENGTH_LONG);
        View snackbarView = snackbar.getView();
        TextView textView = snackbarView.findViewById(android.support.design.R.id.snackbar_text);
        textView.setTextColor(Color.WHITE);
        snackbarView.setBackgroundColor(Color.RED);
        snackbar.show();
    }
    p.setVisibility(View.GONE);
}

【问题讨论】:

  • 小吃店代码在哪里?
  • 从片段中传递 getActivity() 而不是传递视图 ID
  • 它将在空对象引用上提供 'android.view.View android.support.v4.app.FragmentActivity.findViewById(int)'

标签: android android-snackbar


【解决方案1】:

您可以尝试在调用 SnackBar 时使用 Activity content 视图作为参数,如下所示:

View view = getActivity().findViewById(android.R.id.content);

Snackbar snackbar = Snackbar.make(view, "Please connect to the network!", Snackbar.LENGTH_LONG);
...
snackbar.show();

【讨论】:

    【解决方案2】:

    似乎您在代码中定义了两次 lView 变量。 您在 onCreateView() 方法中使用了本地最终变量 lView,并尝试在您的快餐栏方法中传递相同的视图。所以尝试在你的方法中传递一个有效的视图,它应该可以工作。

    final View lView = inflater.inflate(R.layout.fragment_life_regional, container, false)
    

    这是您的局部变量,然后您尝试像这样在句柄 volley 错误方法调用中访问它

    VolleyErrorHandle.handleVolleyErrorThree(error, progressBar, lView.findViewById(R.id.fragment_life_region_layout));
    

    在上面的代码中,lView 应该为 null,因为第一个是局部变量,在您的第二种方法中无法访问。

    【讨论】:

    • 不,我一开始只定义了一次
    【解决方案3】:

    我已经发现为什么会出现这个问题,它是在您使用接口来传达异步调用的结果(例如发出网络请求)时出现的。当您从一个选项卡导航时,它的视图将变为无效(被破坏)。但是,当异步调用最终调用您在导航的选项卡中定义的接口时,您为小吃店提供的视图将不再有效,因此会引发错误。

    可能的解决方案:

    取消所有可以在您导航的视图中调用回调的活动

    【讨论】:

      猜你喜欢
      • 2020-01-15
      • 2018-12-14
      • 1970-01-01
      • 2018-05-19
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多