【问题标题】:How can I avoid using instanceof in this case?在这种情况下如何避免使用 instanceof ?
【发布时间】:2014-07-03 12:36:47
【问题描述】:

我不得不在这里多次使用instanceof,同时检查Fragment 是什么子类,我觉得我在某个地方出错了:

@Override
public void onBackPressed() {

    Fragment frag = mManager.findFragmentByTag("Fragment");

    if(frag instanceof CustFragmentOne || 
       frag instanceof CustFragmentTwo || 
       frag instanceof CustFragmentThree || 
       frag instanceof CustFragmentFour) {

            //This method displays an instance of "CustFragmentFive"
            displayView(0);
    }
    else if(frag instanceof CustFragmentFive)
         super.onBackPressed();

    else if(mManager.getBackStackEntryCount() > 0)
        getFragmentManager().popBackStack();

    else
       super.onBackPressed();

}

有什么办法可以在这里使用它吗?我还能如何识别片段的类型并相应地调用正确的方法?

【问题讨论】:

  • 绕过instanceof操作符的典型方法是Visitor pattern

标签: java android fragment instanceof


【解决方案1】:

最简单的方法是让 CustFragmentOne、CustFragmentTwo 等实现一个通用接口。这样,您只需要对该接口进行一次 instanceof 检查,而不需要单独检查每个具体类。

另一种方式类似于以下内容:How to implement onBackPressed() in Fragments?

【讨论】:

  • 知道了...我之前也看过那个链接,但我觉得它很混乱,你知道有什么更简单的解释吗?
【解决方案2】:

使用接口。例如:

public interface ICustomFragment {

      public boolean shouldNavigateBack();

然后你可以这样做:

@Override
public void onBackPressed() {

CustomFragment frag = (CustomFragment)mManager.findFragmentByTag("Fragment");

    if(frag.shouldNavigateBack()) {

            //This method displays an instance of "CustFragmentFive"
            displayView(0);
    }
    else {
         super.onBackPressed();
}

【讨论】:

    【解决方案3】:

    if(frag.getClass() == CustFragmentOne.class)不确定哪种方法更好

    【讨论】:

      【解决方案4】:

      为什么不将 Fragment 对象保留在 Activity 中?

      CustFragmentOne fragment1 = (FragmentOne)getFragmentManager().findFragmentById(R.id.fragment1);  
       CustFragmentTwo fragment2 = (FragmentOne)getFragmentManager().findFragmentById(R.id.fragment2);
      

      在你的布局 xml 文件中,你会有这样的东西:

      <FrameLayout
          ...>
          <fragment
              android:id="@+id/fragment1"
              android:name="com.smartmirror.FragmentOne"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"/>
          <fragment
              android:id="@+id/fragment2"
              android:name="com.smartmirror.FragmentTwo"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"/>
      </FrameLayout>
      

      【讨论】:

        【解决方案5】:

        我建议你使用这样的东西来控制片段上的后退按钮:

        1. 创建一个基本片段抽象类:

          public abstract class BaseFragment extends Fragment {
          
              public void onBackPressed() {
          
              }
          
          }
          
        2. 从 BaseFragment 扩展所有片段

          公共类 CustFragmentOne 扩展 BaseFragment { ... }

        3. 改变你的活动

          @Override
          public void onBackPressed() {
          
              Fragment frag = mManager.findFragmentByTag("Fragment");
          
              if(frag instanceof BaseFragment)
                  frag.onBackPressed();
              else if(mManager.getBackStackEntryCount() > 0)
                  getFragmentManager().popBackStack();
              else
                 super.onBackPressed();
          
          }
          
        4. 在您的片段中使用您想要的逻辑覆盖 onBackPressed() 方法。

        【讨论】:

          【解决方案6】:

          您总是可以创建一个扩展 Fragment 的 BaseFragment 以由所有 Fragment 扩展。然后你可以让每个片段根据需要处理它,使它更干净一些。例如

          public class BaseFragment extends Fragment { public void onBackPressed() { // Override this function in your fragment classes as needed } }

          或者您可以执行类似 (Android Fragment handle back button press) 的操作

          【讨论】:

            猜你喜欢
            • 2020-07-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多