簡體   English   中英

使用點擊重試選項在 Android 中顯示網絡錯誤的最佳方法

[英]Best approach to show network error in android in Android with Tap to Retry option

我的應用程序中有Navigation Drawer ,除了主應用程序流之外,還有幾個Fragments和一些新的Activity

  • 當前功能
    為了導航到每個Fragment , Network 是必需的,如果出現任何網絡錯誤,我曾經顯示Dialog 用戶需要單擊“確定”按鈕並再次返回導航抽屜重試。
  • 我正在嘗試的新方法
    應向用戶顯示類似於 LinkedIn android 應用程序的錯誤屏幕,並提供重試選項。 在此處輸入圖片說明

由於內部Fragments處理回調可能很麻煩,如何有效地處理這種情況?
對於單個活動,這可以輕松實現,但擔心導航抽屜和內部片段。
有什么建議?

將此錯誤布局隱藏在此片段中。 當出現任何網絡錯誤時,將其可見性更改為 VISIBLE。 並在這個隱藏的布局中添加一個按鈕來調用相同的方法來檢查網絡連接等。

假設您有片段 xml,例如 - 片段 -
相對布局包括 - 1. - 所有布局(可見)& 2. - 帶有按鈕的隱藏網絡錯誤布局(GONE)

當出現網絡錯誤時,將 1. 的可見性更改為 - GONE 並將 2. 的可見性更改為 VISIBLE

並在重試按鈕調用時 -

checkNetworkConnectionCall(); 

我希望這能解決你的問題。

您可以在FrameLayout放置一些ContentFragment ,然后在網絡斷開連接時替換為NetworkDisconnectedFragment 這將需要按鈕調用回調,然后在重新連接時,將NetworkDisconnectedFragment替換為回調實現中的舊ContentFragment

您可以在每個片段中包含此 UI 並創建一個 BaseFragment,它將被導航抽屜中的每個片段擴展。

在該基本片段中編寫一個方法,該方法將完成更改 UI 所需的完整邏輯。

每當您檢測到網絡故障時,只需從那里的基本片段盲目調用該方法。

已經快 3 年了,但我認為它可能對某人有所幫助。 本示例使用 MVP 模式。 BaseNetContentActivity、BaseNetContentFragment 和 NetworkErrorFragment 封裝了更改 UI 邏輯(通過片段的交換),以防網絡錯誤。 它們應該由其他類擴展。

1) BaseNetContentView.java - 所有視圖的基本界面,應該顯示“網絡錯誤”UI。

public interface BaseNetContentView {
    public void showNetworkContentError();
}

2) BaseNetContentFragment.java - 所有片段的基礎,應該顯示“網絡錯誤”UI。 它包含偵聽器和相應的接口。

public abstract class BaseNetContentFragment extends Fragment implements BaseNetContentView {
    @Nullable
    private OnNetworkErrorListener mOnNetworkErrorListener;

    protected final void tryToShowNetworkError() {
        if (mOnNetworkErrorListener != null) {
            mOnNetworkErrorListener.onNetworkError();
        }
    }

    protected final boolean hasOnNetworkErrorListener() {
        return mOnNetworkErrorListener != null;
    }

    public final void setOnNetworkErrorListener(
            @Nullable OnNetworkErrorListener onNetworkErrorListener) {
        mOnNetworkErrorListener = onNetworkErrorListener;
    }

    public interface OnNetworkErrorListener {
        public void onNetworkError();
    }
}

3) BaseNetContentActivity - 基礎活動,通過改變 UI 片段來處理網絡錯誤

public abstract class BaseNetContentActivity<T extends BaseNetContentFragment>
        extends AppCompatActivity implements BaseNetContentFragment.OnNetworkErrorListener {
    private static final String TAG = "BaseNetContentActivity";

    @Override
    public void onNetworkError() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment fragment = getCurrentContentFragment(fragmentManager);

        // Skip if already NetworkErrorFragment
        if (!(fragment instanceof NetworkErrorFragment)) {
            setFragmentToActivity(fragmentManager, new NetworkErrorFragment());
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutResId());
        Fragment fragment = getCurrentContentFragment(getSupportFragmentManager());

        // NetworkErrorFragment is self-sufficient
        if (fragment instanceof NetworkErrorFragment) {
            return;
        }

        setNetworkContentFragmentToActivity(savedInstanceState);

    }

    @Override
    public void onAttachFragment(Fragment fragment) {
        // Set appropriate listener to fragment
        if (fragment instanceof NetworkErrorFragment) {
            ((NetworkErrorFragment) fragment)
                    .setOnReloadContentListener(new NetworkErrorFragment.OnReloadContentListener() {
                        @Override
                        public void onReloadContent() {
                                setNetworkContentFragmentToActivity(null);
                        }
                    });
        } else if (fragment instanceof BaseNetContentFragment) {
            ((BaseNetContentFragment) fragment).setOnNetworkErrorListener(this);
        }
        // Don't do anything with other fragment's type
    }

    @NonNull
    protected abstract T createNetworkContentFragment();

    protected abstract void setPresenter(@NonNull T fragment, @Nullable Bundle savedInstanceState);

    @LayoutRes
    protected int getLayoutResId() {
        return R.layout.basenetworkcontent_act;
    }

    @IdRes
    protected int getContentFrameId() {
        return R.id.network_content_frame;
    }

    private void setNetworkContentFragmentToActivity(@Nullable Bundle savedInstanceState) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment fragment = getCurrentContentFragment(fragmentManager);

        if (fragment == null || fragment instanceof NetworkErrorFragment) {
            fragment = createNetworkContentFragment();
        }

        try {
            setPresenter((T) fragment, savedInstanceState);
        } catch (ClassCastException e) {
            // Unexpected fragment type
            Log.d(TAG,"Can't set Presenter because of wrong View type (wrong fragment)" + e);

            // Casting to T type is safe, because createNetworkFragment() returns T type
            fragment = createNetworkContentFragment(); // returns type T
            setPresenter((T) fragment, savedInstanceState);
        }

        setFragmentToActivity(fragmentManager, fragment);

    }

    private Fragment getCurrentContentFragment(@NonNull FragmentManager fragmentManager) {
        return fragmentManager.findFragmentById(getContentFrameId());
    }

    private void setFragmentToActivity(@NonNull FragmentManager fragmentManager,
                                       @NonNull Fragment fragment) {
        fragmentManager.beginTransaction()
                       .replace(getContentFrameId(), fragment)
                       .commit();
    }
}

4) 網絡錯誤片段

public static class NetworkErrorFragment extends Fragment implements View.OnClickListener {
    @Nullable
    private OnReloadContentListener mOnReloadContentListener;
    private Button mReloadButton;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater,
                             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View root = inflater.inflate(R.layout.networkerror_frag, container, false);
        mReloadButton = (Button) root.findViewById(R.id.reload_content_button);
        if (mOnReloadContentListener != null) {
            mReloadButton.setOnClickListener(this);
        } else {
            mReloadButton.setVisibility(View.INVISIBLE);
        }
        return root;
    }

    @Override
    public void onClick(View v) {
        if (mOnReloadContentListener != null) {
            mOnReloadContentListener.onReloadContent();
        }
    }

    public void setOnReloadContentListener(@Nullable OnReloadContentListener onReloadContentListener) {
        mOnReloadContentListener = onReloadContentListener;
    }

    public interface OnReloadContentListener {
        public void onReloadContent();
    }

}

https://github.com/relativizt/android-network-error-ui 上的完整示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM