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