使用 'Retry' 和 'Wifi Settings'、'Mobile Network' 等其他选项显示 'Cant access network' 视图的有效方式

Efiicient way to show 'Cant access network' View with 'Retry' and additional options like 'Wifi Settings', 'Mobile Network'

我需要将其包含在我的应用程序中

When should it get triggered?

What I tried?

  1. 我使用 Volley。触发 AlertDialog inside Response.ErrorListener of Volley, 每次我写一个 JsonObjectRequest

问题: 过于重复,AlertDialog 代码行数过多

  1. 添加了一个名为 Alerts 的通用 class 并从中调用了 AlertDialog,如

    DialogInterface.OnClickListener onClickTryAgain = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Swift.getInstance(ProfileActivity.this).addToRequestQueue(jsonObjectRequest);
        }
    };
    if(error instanceof TimeoutError) Alerts.timeoutErrorAlert(ProfileActivity.this, onClickTryAgain);
    else if(error instanceof NoConnectionError) Alerts.internetConnectionErrorAlert(ProfileActivity.this, onClickTryAgain);
            else Alerts.unknownErrorAlert(ProfileActivity.this);
    

我的Alerts.class

    public class Alerts {


        public static void internetConnectionErrorAlert(final Context context, DialogInterface.OnClickListener onClickTryAgainButton) {
            String message = "Sometimes the internet gets a bit sleepy and takes a nap. Make sure its up and running then we'll give it another go";
            new AlertDialog.Builder(context)
                    .setIconAttribute(android.R.attr.alertDialogIcon)
                    .setTitle("Network Error")
                    .setMessage(message)
                    .setPositiveButton("Try Again", onClickTryAgainButton)
                    .setNegativeButton("Turn Internet On", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Intent i = new Intent(Settings.ACTION_SETTINGS);
                            ((Activity) context).startActivityForResult(i, 0);
                        }
                    })
                    .show();
        }

        public static void timeoutErrorAlert(Context context, DialogInterface.OnClickListener onClickTryAgainButton) {
            String message = "Are you connected to internet? We guess you aren't. Turn it on and we'll rock and roll!";
            new AlertDialog.Builder(context)
                    .setIconAttribute(android.R.attr.alertDialogIcon)
                    .setTitle("Network Error")
                    .setMessage(message)
                    .setPositiveButton("Try Again", onClickTryAgainButton)
                    .show();
        }

        public static void unknownErrorAlert(Context context) {
            new AlertDialog.Builder(context)
                    .setIconAttribute(android.R.attr.alertDialogIcon)
                    .setTitle("Server Error")
                    .setMessage("We all have bad days! We'll fix this soon...")
                    .setPositiveButton("Hmm, I understand", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        }
                    })
                    .show();
        }
    }

问题Try again 按钮不符合我的要求。好吧,假设有人为此提供了修复程序,我可以说,它只是用 5 行代码替换了大约 30 行代码,好吧,但是转换呢?我需要说 connecting,直到收到回复

  1. 这次,我添加了一个名为 ConnectingLayout 的布局,覆盖了整个屏幕。

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center_horizontal"
        android:id="@+id/loading_layout"
        android:visibility="gone">
    
        <ProgressBar
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:indeterminate="true" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/loading"
            android:gravity="center_horizontal"
            android:textSize="25sp"
            android:fontFamily="sans-serif-light"
            android:layout_margin="5dp"
            android:singleLine="true" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/loading_description"
            android:gravity="center_horizontal"
            android:fontFamily="sans-serif-light"
            android:layout_margin="5dp"
            android:singleLine="true" />
    </LinearLayout>
    

并像在

中一样使用它
    jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, getString(R.string.api_root_path) + "/profile", getJson(), new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            try {
                if(response.getBoolean("success")) {
                    Animations.fadeOut(loadingLayout,500);
                    Animations.fadeIn(mainLayout,500);
                    JSONObject dataJson = response.getJSONObject("data");
                    JSONObject userJson = dataJson.getJSONObject("user");
                    name.setText(userJson.getString("name"));
                    dob.setText(userJson.getString("dob").equals("null")?null:userJson.getString("dob"));
                    email.setText(userJson.getString("email"));
                    phone.setText(userJson.getString("mobile_no"));
                    promotionOffers.setChecked(userJson.getBoolean("offers"));
                } else {
                    Alerts.requestUnauthorisedAlert(ProfileActivity.this);
                    System.out.println(response.getString("error"));
                }
            } catch (JSONException e) { e.printStackTrace(); }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            DialogInterface.OnClickListener onClickTryAgain = new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    VolleyBaseClass.getInstance(ProfileActivity.this).addToRequestQueue(jsonObjectRequest);
                }
            };
            if(error instanceof TimeoutError) Alerts.timeoutErrorAlert(ProfileActivity.this, onClickTryAgain);
            else if(error instanceof NoConnectionError) Alerts.internetConnectionErrorAlert(ProfileActivity.this, onClickTryAgain);
            else Alerts.unknownErrorAlert(ProfileActivity.this);
            System.out.println("Response Error: " + error);
        }
    });
    Animations.fadeIn(loadingLayout, 500);
    Animations.fadeOut(mainLayout, 500);
    VolleyBaseClass.getInstance(this).addToRequestQueue(jsonObjectRequest);

假设 Animations.fadeIn(View view, int ms);Animations.fadeOut(View view, int ms); 已正确定义并完成工作。

问题: 各种activities重复布局和写代码fade的痛苦

  1. 了解 ViewStub。以编程方式生成代码以获取相同的 ConnectingLayout。现在我可以更改文本,如保存、加载等。

问题: 不是很大的飞跃,但是... ..,这是我刚刚踏上的又一块垫脚石

  1. 连载中不用我说,只说'Hey, your phone is processing someething'。所以我只是想为什么不在 SwipeRefreshLayouts 中使用加载圈?

问题: 太好了,它在顶部显示了一个小的加载圆形缺口,如果加载失败,我可以调用警报,但是在哪里打开 wifi,打开 3G 和其他东西,对于 AlertDialog 来说太大了,无法容纳所有这些,有没有其他方法可以显示 try again

  1. 考虑使用 same fragment in all activitiesredirecting to a callActivityForResult(抱歉,我不能添加两个以上的链接)

问题:嗯...!将用户带到一个新的 activity 是我发现消耗资源并大大降低性能的原因。还有碎片?

I am not giving up! I know I'm learning it the hard way, but with great hopes that the developer community will help me.

我也遇到过同样的需求和问题。我正在研究基于 Volley 的库 jus where most the issues you have had i handle with rxJava global observables and of course Alerts class with static alerts/views generators. the connectivity handling I try to make it smooth using ConnectivityManager and NoConnectionPolicy 概念。

Volley DETROYS all listeners as soon as it receives something from the server, regardless of whether the response is a proper response or an error response.

每次发送或重发时都需要构造一个请求。

这些步骤将有助于实现它

  • 使用 Retry 和其他必要的按钮(如 Wifi SettingsMobile Network Settings
  • 创建片段
  • 在必要的视图 RelativeLayout 中创建一个全尺寸 FrameLayout 以容纳创建的片段 并最初隐藏它
  • 当请求失败时,使 FrameLayout 可见并且重试按钮应该调用 构造的函数并调用 请求