隐藏和显示视图可防止碎片更改

时间:2015-07-28 21:23:09

标签: android android-fragments android-view

我遇到了更换片段的问题,步骤如下:

  • 将加载屏幕可见性设置为可见
  • 启动webcall
  • 在回调中,隐藏加载屏幕
  • 在回调中仍然执行片段事务来替换片段

按照这些步骤,我的片段不会改变,我仍然留在显示加载屏幕的片段上。

如果我:

,我的片段交易将成功完成
  • 不要显示加载屏幕,或
  • 在交易后隐藏加载屏幕

但是,如果我在交易后隐藏加载屏幕,则片段不会显示,我只会收到白色背景。我已经遇到了这个问题好几天了,并且已经考虑过这个问题,但却无法想到可能导致它的原因。

以下是我的XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:background="@color/orange"
            android:layout_width="match_parent"
            android:layout_height="@dimen/toolbar_height"/>

        <FrameLayout
            android:layout_below="@id/toolbar"
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

        <LinearLayout
            android:id="@+id/loading"
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:visibility="gone"
            android:clickable="true"
            android:background="#40000000"
            android:orientation="vertical"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:padding="16dp"
                android:layout_margin="16dp"
                android:background="#FFFFFF"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:id="@+id/tvMessage"
                    android:text="Loading..."
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent" />

                <ProgressBar
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />

            </LinearLayout>

        </LinearLayout>

    </RelativeLayout>

    <include
        android:id="@+id/drawer"
        android:layout_gravity="start"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        layout="@layout/nav_drawer"/>

</android.support.v4.widget.DrawerLayout>

编辑:

显示加载屏幕:

public void showLoading(String message){
    tvLoadingText.setText(message);
    loading.setVisibility(View.VISIBLE);
}

隐藏加载屏幕:

public void hideLoading(){
    loading.setVisibility(View.GONE);
}

编辑2:

我在上面评论了方法签名,因此很容易遵循这些步骤,这是我几周前看到的另一个错误,但有些不同,而不是尝试更改碎片,我试图显示Snackbar但它不会显示除非我禁用hideLoading()或showLoading()。

LoginFragment:

public class LoginFragment extends Fragment implements ILoginView{

    private static final String ERROR_MESSAGE = "error message";

    ILoginPresenter mLoginPresenter;
    ILoginModel mLoginModel;
    BaseActivity baseActivity;

    @Bind(R.id.etUsername)EditText etUsername;
    @Bind(R.id.etPassword)EditText etPassword;
    @Bind(R.id.etSFApiKey)EditText etToken;

    public static LoginFragment newInstance(String errorMessage){

        Bundle args = new Bundle();
        args.putString(ERROR_MESSAGE, errorMessage);
        LoginFragment loginFragment = new LoginFragment();
        loginFragment.setArguments(args);

        return loginFragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String errorMessage = getArguments().getString(ERROR_MESSAGE);
        mLoginModel = new LoginModel(getActivity());
        mLoginPresenter = new LoginPresenter(this, mLoginModel);
        baseActivity = (BaseActivity) getActivity();
        showErrorMessage(errorMessage);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_login, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void showMainActivity() {
        startActivity(new Intent(getActivity(), MainActivity.class));
        getActivity().finish();
    }

    //4th step, hide the loading screen, show a snackbar... 
    //except showing the snackbar doesn't work
    @Override
    public void showErrorMessage(String errorMessage) {
        baseActivity.hideLoading();
        baseActivity.snackbar(errorMessage, Snackbar.LENGTH_INDEFINITE);
    }

    @Override
    public void hideToken() {
        etToken.setVisibility(View.GONE);
    }

    //If you're not familiar with ButterKnife, 
    //this is where my button's onclick listener is set
    //first step, press login, next step in LoginPresenter
    @OnClick(R.id.bLogin) void login() {
        baseActivity.showLoading("Logging in...");
        mLoginPresenter.login(
                etUsername.getText().toString(),
                etPassword.getText().toString(),
                etToken.getText().toString());
    }
}

LoginPresenter:

public class LoginPresenter implements ILoginPresenter{

    ILoginView mLoginView;
    ILoginModel mLoginModel;

    public LoginPresenter(ILoginView loginView, ILoginModel loginModel){
        mLoginView = loginView;
        mLoginModel = loginModel;

        if(CCMobile.crm != CCMobile.SALESFORCE)
            mLoginView.hideToken();
    }

    //Second step, attempt web call login, next step in callback
    @Override
    public void login(String username, String password, String token) {
        if((username.equals("") || password.equals("")))
            mLoginView.showErrorMessage("All fields required");
        else
            mLoginModel.login(username, password + token, mLoginCallback);

    }

    LoginCallback mLoginCallback = new LoginCallback() {

        @Override
        public void onSuccess(String request, String response) {
            super.onSuccess(request, response);
            mLoginView.showMainActivity();
        }

        //Third step, force a failure
        @Override
        public void onFailure(String request, String response, String errorMessage) {
            super.onFailure(request, response, errorMessage);
            if(errorMessage != null)
                mLoginView.showErrorMessage(errorMessage);
        }
    };
}

0 个答案:

没有答案