0

這應該是一個簡單的問題,但由於某種原因,我遇到了麻煩。假設我有一個FragmentOne和FragmentTwo。 FragmentOne看起來是這樣的:Android:模板模式與片段

private static final String PATH_KEY = "path_key"; 

private Asset asset; 

public FragmentOne() { 
    // Required empty public constructor 
} 


public static FragmentOne newInstance(Asset asset) { 
    FragmentOne fragment = new FragmentOne(); 
    Bundle args = new Bundle(); 
    args.putSerializable(PATH_KEY, asset); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (getArguments() != null) { 
     asset = (Asset) getArguments().getSerializable(PATH_KEY); 
    } 
} 

@Override 
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, 
     final Bundle savedInstanceState) { 
    final FragmentOneBinding binding = DataBindingUtil 
      .inflate(inflater, R.layout.fragment_video, container, false); 
    bindAsset(binding, asset); 
    return binding.getRoot(); 
} 

public void bindAsset(FragmentOneBinding binding, Asset asset) { 
    binding.textView.setText("FragOne displays asset like this " + asset.text); 
    //this is the only method which differs from FragmentTwo 

} 

而FragmentTwo看起來是這樣的:

private static final String PATH_KEY = "path_key"; 

private Asset asset; 

public FragmentTwo() { 
    // Required empty public constructor 
} 


public static FragmentTwo newInstance(Asset asset) { 
    FragmentTwo fragment = new FragmentTwo(); 
    Bundle args = new Bundle(); 
    args.putSerializable(PATH_KEY, asset); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (getArguments() != null) { 
     asset = (Asset) getArguments().getSerializable(PATH_KEY); 
    } 
} 

@Override 
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, 
     final Bundle savedInstanceState) { 
    final FragmentTwoBinding binding = DataBindingUtil 
      .inflate(inflater, R.layout.fragment_video, container, false); 
    bindAsset(binding, asset); 
    return binding.getRoot(); 
} 

public void bindAsset(FragmentOneBinding binding, Asset asset) { 
    binding.textView.setText("But FragTwo, which is very different, displays asset like this " + asset.image.getName()); 
    //this is the only method which differs from FragmentOne 

} 

正如你可以看到,在兩個片段,中的newInstance,的onCreate和onCreateView方法在結構上相同。唯一真正的區別是從兩個片段的onCreateView中調用的bindView方法是不一樣的。

使用泛型,抽象類,接口或某些組合可以將事物簡化爲模板設計模式嗎?那麼下一次我想用完全相同的結構製作一個片段時,我可以做一些這樣的事情?

class FragmentThree extends TemplateFragment { 

    @Override 
    public void bindAsset(FragmentThreeBinding binding, Asset asset){ 
     binding.textView.setText(asset.name); 
    } 

} 

我試圖使一個抽象類了,但你不能有一個抽象類的靜態方法,所以的newInstance()停止我在這裏。我嘗試了一些實現接口的方法,但沒有任何運氣。

回答

1

我認爲您嘗試的抽象類是正確的路要走。您仍然需要在每個具體子類中放置newInstance(),這不僅因爲它是靜態的,而且還因爲它需要知道要實例化的具體類型。

+0

你好。你是對的,採取你的方法確實有點簡化了代碼,儘管沒有我希望的那麼多。我會接受你的回答。但是,如果我需要將newInstance部分分解出來,那麼您推薦什麼?某種工廠類? (在我的情況下,FragmentOne,FragmentTwo和Fragment Three都在不同的FragmentSwitcher類中實例化,除了要切換到的片段類型外,它們在功能上都是相同的,將它們減少到單個通用切換器類會更好)。 – ike

+0

此FragmentSwitcher類是否創建相同片段類的多個實例,或者它是否可以在單個實例中運行? –

+0

@ike理想情況下,你應該發佈一個新的問題與這個鏈接。 –

-1

抽象方法不能使用靜態。 工廠模式爲了創建類實例化。 片段使用Factory Mode,本身添加靜態方法。