【问题标题】:How to call fragment from non activity class in android如何从android中的非活动类调用片段
【发布时间】:2019-11-22 00:31:12
【问题描述】:

我有一个登录 Fragment 和一个名为 CServerResponse 的类。

我想在CServerResponse 班级里给LoginFragment 打电话。

我该怎么做?

这是CServerResponse类代码:

public class CServerResponse {
    public static CServerResponse s_m_oServerResponse;
    public Context m_Context;

    private CServerResponse(Context m_Context) {
        this.m_Context = m_Context;
    }

    public static CServerResponse getInstance() {
        if (s_m_oServerResponse == null) {
            s_m_oServerResponse = new CServerResponse();
        }
        return s_m_oServerResponse;
    }

    public void getLoginResponse() throws JSONException {
        final Fragment activity = (Fragment) m_Context;
        if (CLoginScreen.m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Transaction Successful")) {

            CLoginScreen.m_oLoginSession.setLoginData(
                CLoginScreen.s_szResponseMobile, CLoginScreen.s_szResponsePassword);

            getActivity().getSupportFragmentManager()
                         .beginTransaction()
                         .replace(R.id.container, new CDealMainListing()).commit();

            CToastMessage.getInstance().showToast(getActivity(), "You are successfully Logged In");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Agentcode Can Not Be Empty")) {

            CToastMessage.getInstance().showToast(getActivity(), "Please Enter Valid Mobile Number");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Pin Can Not Be Empty")) {

            CToastMessage.getInstance().showToast(getActivity(), "Please Enter Password");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Invalid PIN")) {

            CToastMessage.getInstance().showToast(getActivity(), "Please enter correct Password");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Subscriber/Agent Blocked due to Wrong Attempts")) {

            CToastMessage.getInstance().showToast(getActivity(), "You are blocked as You finished your all attempt");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Connection Not Available")) {

            CToastMessage.getInstance().showToast(getActivity(), "Connection Lost ! Please Try Again");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("Subscriber/Agent Not Found")) {

            CToastMessage.getInstance().showToast(getActivity(), "User not found ! Kindly Regiter before Login");

        } else if (m_oResponseobject.getString("resultdescription").equalsIgnoreCase("OTP not verify")) {

            CToastMessage.getInstance().showToast(getActivity(), "Otp not Verify ! Kindly Generate Otp on Sign Up");
        }
    }
}

【问题讨论】:

标签: android android-fragments android-activity


【解决方案1】:

您需要访问需要调用片段的 Activity 的上下文。

假设您在名为 startLoginFragment(Context context) 的方法中拥有相应 Activity 的上下文。该方法的代码如下:

public void startLoginFragmemt(Context context) {
    Activity activity = (Activity) context;
    FragmentManager fragmentManager = activity.getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    LoginFragment fragment = new LoginFragment();
    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();
}

【讨论】:

    【解决方案2】:

    如果您使用的是AppCompatActivity,则相应地转换您的context,否则您将获得 Illegel cast Exception。所以用

    AppCompatActivity activity = (AppCompatActivity) context;
    

    而不是简单的activity

    Activity activity = (Activity) context;
    

    【讨论】:

      【解决方案3】:

      您可以从 Activity 中创建 Fragment,但不应在 Activity 之外使用它们,因为它们的生命周期方法仅在附加到 Activity 时才会被调用。

      如果您想在 Fragment 中操作数据,您可以创建一个 Fragment 类。从一个 Activity 构造和膨胀它,然后从另一个具有公共方法的类访问它以修改信息。

      根据您的情况,您可以:

      • LoginFragment: 处理 UI 元素的类
      • LoginActivity: 膨胀 LoginFragment 并调用 Login 服务。
      • LoginService:它处理登录服务(AsyncTask ?),当它完成后,它会向 LoginActivity 返回您需要的信息,并且 Activity 会将更新发送到最终处理信息的 Fragment。

      一些代码.. 正如我在 cmets 中所说的那样,此代码可能不是很有用.. 一切都取决于您如何处理所有事情...我个人喜欢将 AsyncTask 与自定义接口一起使用,用于在任务和 UI 线程(使用它们在它们之间交换数据并触发 UI 更改)。这段代码没有向您展示这种方法,而是您应该如何(以我的拙见)组织您的流程

      片段:

      Class LoginFragment extends Fragment {
      
          private PROP1 prop1;
          private PROP2 prop2;
      
          private LoginFragment(){}
      
          public static LoginFragment createInstance( PROP1 prop1, PROP2 prop2){
              this.prop1 = prop1;
              this.prop2 = prop2;
          }
      
          // Fragment lifecycle methods
      
          // Methods used by activity to trigger changes in UI..
          // They could be setters or.. really.. whatever fits best in your flow. 
          public void changeProp1(PROP1 prop1){
               this.prop1 = prop1;
               // EDIT UI ELEMENTS.. DO WHATEVER YOU NEED TO DO..
          }
      }
      

      活动:

      Class LoginActivity extends Activity { // Activity or whatever Activity class you're using.
      
           private LoginFragment mLoginFragment;
      
           @Override
           public void onCreate(){ // I don't remember the correct signature
      
                // Create LoginFragment
                mLoginFragmet = LoginFragment.newInstance(prop1,prop2)
                // Use FragmentManager to inflate your fragment
           }
      
           public void serviceInvoke(){ // I don't remember the correct signature
      
                // Invoke your login service. I'd use an AsyncTask and an interface implementation that allows the usage of callbacks
                // When the service is complete take the result value and pass it to the proper Fragment method
                mLoginFragment.changeProp1(theResultOfTheService);
           }
      }
      

      【讨论】:

      • 我可能是你并不真正需要的相当大的代码复制/粘贴。我会用一些示例编辑答案,但你会看到与 AndroidStudio 提供的相差不远当你让它创建一个新的 Fragment 类文件时。
      • 只要看看 AsyncTask 的正确实现来处理你的连接,FragmentManager 在 Activity 中膨胀你的 Fragment,你就大功告成了
      【解决方案4】:

      这对我有用。

       public class YOUR_CLASS extends AppCompatActivity{
      
          public void changeFragments(Context context, Fragment fragment, String putStringName, String putStringDescription) {
      
               AppCompatActivity activity = (AppCompatActivity) context;
               // Pasar datos de un fragment a otro
               Bundle datosAEnviar = new Bundle();
               datosAEnviar.putString(putStringName, putStringDescription);
               fragment.setArguments(datosAEnviar);
      
      
              activity.getSupportFragmentManager().beginTransaction().addToBackStack(null).
                  replace(R.id.nav_host_fragment, fragment).commit();
          }
      
      
      }
      

      【讨论】:

        猜你喜欢
        • 2014-09-01
        • 2013-10-28
        • 2012-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多