2

除了主要的应用程序流程之外,我Navigation Drawer的应用程序中还有Fragments几个新的。Activity

  • 当前功能
    对于导航到每个Fragment,需要网络,如果出现任何网络错误,我曾经显示Dialog. 用户需要单击“确定”按钮并再次返回导航抽屉重试。
  • 我正在尝试的新方法
    应该显示用户并显示类似于 LinkedIn android 应用程序的错误屏幕,并带有重试选项。 在此处输入图像描述

由于内部Fragments处理回调可能很麻烦,如何有效地处理这种情况?
对于个别活动,这可以轻松实现,但担心导航抽屉和内部片段。
有什么建议么?

4

4 回答 4

1

将此错误布局隐藏在此片段中。当出现任何网络错误时,将其可见性更改为 VISIBLE。并在这个隐藏的布局中添加一个按钮来调用相同的方法来检查网络连接等。

假设您有片段 xml,例如 - 片段 -
相对布局,包括 - 1. - 所有布局(可见)和 2. - 带有按钮的隐藏网络错误布局(GONE)

当出现网络错误时,将 1. 的可见性更改为 - GONE 并将 2. 的可见性更改为 VISIBLE

并在重试按钮调用 -

checkNetworkConnectionCall(); 

我希望这能解决你的问题。

于 2016-03-17T07:49:37.900 回答
0

您可以将一些ContentFragment放在 a 中,然后在网络断开连接时FrameLayout用 a 替换。NetworkDisconnectedFragment这将需要按钮调用回调,然后在重新连接时,用回调实现中NetworkDisconnectedFragment的旧按钮替换。ContentFragment

于 2016-03-17T07:41:42.260 回答
0

您可以在每个片段中包含此 UI,并创建一个 BaseFragment,它将被导航抽屉中的每个片段扩展。

在该基本片段中编写一个方法,该方法将完成更改 UI 所需的完整逻辑。

每当您检测到网络故障时,只需从那里的基本片段中盲目地调用该方法。

于 2016-03-17T07:56:29.020 回答
0

已经快 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 - 基础 Activity,通过改变 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

于 2019-01-07T12:50:55.697 回答