0

我有一个片段,它有一个TextView,一个EditText和一个Button。我还有2个活动,其中一个活动中包含此按钮fragmentonClick,另一个活动已启动。通过intentedittext中的text被传递,其变成其他activitytextviewtext在Android中重新使用片段

我有两个设计决策可供选择

  1. 创建与构建适当的意图适当的方法,两个这样的片段类。访问相应片段对象内的UI元素并开始活动。
  2. 只创建一个片段类。的onClick的,事件被传递到一个特定的方法在活动(包括活动具有此方法)和活动必须建立的意图,并开始其他活动

考虑一下,如果有会发生什么逻辑100个这样的活动。第一种方法会让我们用自定义方法编写100个不同的片段类,但在第二种方法中,它是一个单独的类,并且这些活动具有特定命名方法中的自定义逻辑。

因此,我选择了第二种选择,我意识到UI元素无法在onCreate活动方法中实例化,因为片段的布局尚未充实。作为解决方法,我正在做onStart的实例化。

这是不好的做法还是有更好的design pattern

回答

1

推荐的模式是创建一个持有者接口,任何想要实例化片段的活动都必须实现。还要为您的新片段中的视图设置数据,然后在您的片段上创建一个newInstance()工厂方法。

我倾向于像这样接近它;

class FooFragment implements Fragment { 

    private static final String TEXT_FOR_TEXTVIEW = "textForTextView"; 

    private FooFragmentHolder mHolder; 

    /* 
    * Rather than creating your fragment in your layout directly 
    * you should instead instantiate it using this class in your 
    * activity. 
    */ 
    public static FooFragment newInstance(String text) { 
     Bundle data = new Bundle(); 
     data.putString(TEXT_FOR_TEXTVIEW, text); 
     FooFragment fooFragment = new FooFragment(); 
     fooFragment.setArguments(data); 
     return fooFragment; 
    } 

    public interface FooFragmentHolder { 
     public void buttonPressed(String editTextContent); 
    } 

    /* 
    * When we create the fragment with the activity we use onAttach to get 
    * our holder implementation (the activity) 
    */ 
    @Override 
    public void onAttach(Activity activity) { 
     if (activity instanceof FooFragmentHolder) { 
      mHolder = (FooFragmentHolder) activity; 
     } else { 
      throw new IllegalStateException("Containing activity must implement FooFragmentHolder"); 
     } 
    } 

    @Override 
    public void onCreateView(Inflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_foo, container, false); 

     final EditText editText = (EditText) view.findViewById(R.id.edit_text); 
     Button button = (Button) view.findViewById(R.id.button); 
     button.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(Button button) { 
       mHolder.buttonPressed(editText.getText()); 
      } 

     })}; 
     TextView textView = (TextView) view.findViewById(R.id.text_view); 

     Bundle args = getArguments(); 
     if (args != null) { 
      textView.setText(args.getString(TEXT_FOR_TEXTVIEW)); 
     } 

     return view; 
    } 

} 

现在在你的活动,你只需要实现FooFragmentHolder界面,并使用我们所创建的newInstance方法;

class FooActivity extends Activity implements FooFragment.FooFragmentHolder { 

    private static final String TEXT_FOR_TEXTVIEW = "textForTextView"; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentLayout(R.layout.activity_foo); 

     // Instead of creating your fragment in your layout, create a holder 
     // layout and attach a new instance of your fragment using a fragment 
     // transaction. 
     FooFragment fooFragment = FooFragment.newInstance(getIntent().getStringExtra(TEXT_FOR_TEXTVIEW)); 
     getFragmentManager().beginTransaction() 
      .replace(R.id.content, fooFragment) 
      .commit(); 
    } 

    @Override 
    public void buttonPressed(String editTextContent) { 
     // In this case just starting the next FooActivity, but logic could be 
     // applied for any other activity. 
     Intent intent = new Intent(this, FooActivity.class) 
      .putExtra(TEXT_FOR_TEXTVIEW, editTextContent); 
     startActivity(intent); 
    } 

} 
+0

发布问题后不久,我决定遵循一个模式(请参阅下面的答案)。我们的模式看起来几乎相同,除了在我的UI元素完全通过活动来控制。我相信这可以帮助我完全分解UI和逻辑(片段 - 可插拔的UI和活动逻辑) –

0

我决定用下面的图案来解决 -

的任何活动,其中包括该片段应实施像

public interface ViewsCreatedListener { 
    public void onViewsCreated(); 
} 

的接口,则该活动将看起来像

public class ExampleActivity extends Activity implements ViewsCreatedListener { 
    . 
    . 
    . 
    . 
    @Override 
    public void onViewsCreated() { 
      //Initiate the views here and do what gotta be done 
    } 
} 

片段应检查是否包含此片段的任何活动d使用onAttach方法和onActivityCreated实现该接口,活动通知

public class ExampleFragment extends Fragment { 

    ViewsCreatedListener listener = null; 
    . 
    . 
    . 
    . 
    @Override 
    public onAttach(Activity activity) { 
     super.onAttach(activity); 
     try { 
      listener = (ViewsCreatedListener) activity; 
     } catch (ClassCastException e) { 
     throw new ClassCastException(activity.toString() 
       + " must implement ViewsCreatedListener"); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     listener.onViewsCreated(); 
    } 

} 

这样做的方式,该片段只是提供了UI和包括活动的决定,以什么应该通过包括UI元素来完成分段。这最大限度地提高了可重用性。DRY ...:-D

+0

“片段具有单独的布局XML文件.Fragment封装了功能,以便在活动和布局中重复使用。片段是可以包含视图,事件和逻辑的独立组件。在面向片段的体系结构中,应用程序成为导航容器,主要负责导航到其他活动,呈现片段和传递数据“ – Radu