Düzenini programlı olarak uygulayan bir Activity'ye bir Fragment eklemek istiyorum. Fragment belgelerine baktım ama ihtiyacım olan şeyi açıklayan çok fazla örnek yok. İşte yazmaya çalıştığım kod türü:
public class DebugExampleTwo extends Activity {
private ExampleTwoFragment mFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout frame = new FrameLayout(this);
if (savedInstanceState == null) {
mFragment = new ExampleTwoFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(frame.getId(), mFragment).commit();
}
setContentView(frame);
}
}
...
public class ExampleTwoFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
Button button = new Button(getActivity());
button.setText("Hello There");
return button;
}
}
Bu kod derleniyor ancak başlangıçta çöküyor, bunun nedeni muhtemelen FragmentTransaction.add()
kodumun yanlış olması. Bunu yapmanın doğru yolu nedir?
Bu kodla ilgili birden fazla sorun olduğu ortaya çıktı. Bir fragman bu şekilde, aktivite ile aynı java dosyası içinde ancak genel bir iç sınıf olarak bildirilemez. Çerçeve, parçanın kurucusunun (parametresiz) public ve görünür olmasını bekler. Parçayı Activity'nin içine bir iç sınıf olarak taşımak veya parça için yeni bir java dosyası oluşturmak bunu düzeltir.
İkinci sorun, bu şekilde bir fragman eklediğinizde, fragmanı içeren görünüme bir referans geçmeniz ve bu görünümün özel bir kimliğe sahip olması gerektiğidir. Varsayılan kimliği kullanmak uygulamayı çökertecektir. İşte güncellenmiş kod:
public class DebugExampleTwo extends Activity {
private static final int CONTENT_VIEW_ID = 10101010;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout frame = new FrameLayout(this);
frame.setId(CONTENT_VIEW_ID);
setContentView(frame, new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
if (savedInstanceState == null) {
Fragment newFragment = new DebugExampleTwoFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(CONTENT_VIEW_ID, newFragment).commit();
}
}
public static class DebugExampleTwoFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
EditText v = new EditText(getActivity());
v.setText("Hello Fragment!");
return v;
}
}
}
İşte Tony Wong'un yorumunu okuduktan sonra bulduğum şey:
public class DebugExampleTwo extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addFragment(android.R.id.content,
new DebugExampleTwoFragment(),
DebugExampleTwoFragment.FRAGMENT_TAG);
}
}
...
public abstract class BaseActivity extends Activity {
protected void addFragment(@IdRes int containerViewId,
@NonNull Fragment fragment,
@NonNull String fragmentTag) {
getSupportFragmentManager()
.beginTransaction()
.add(containerViewId, fragment, fragmentTag)
.disallowAddToBackStack()
.commit();
}
protected void replaceFragment(@IdRes int containerViewId,
@NonNull Fragment fragment,
@NonNull String fragmentTag,
@Nullable String backStackStateName) {
getSupportFragmentManager()
.beginTransaction()
.replace(containerViewId, fragment, fragmentTag)
.addToBackStack(backStackStateName)
.commit();
}
}
...
public class DebugExampleTwoFragment extends Fragment {
public static final String FRAGMENT_TAG =
BuildConfig.APPLICATION_ID + ".DEBUG_EXAMPLE_TWO_FRAGMENT_TAG";
// ...
}
Kotlin kullanıyorsanız, Google tarafından sağlanan Kotlin uzantılarına bir göz attığınızdan emin olun veya sadece kendiniz yazın.
public abstract class SingleFragmentActivity extends Activity {
public static final String FRAGMENT_TAG = "single";
private Fragment fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
fragment = onCreateFragment();
getFragmentManager().beginTransaction()
.add(android.R.id.content, fragment, FRAGMENT_TAG)
.commit();
} else {
fragment = getFragmentManager().findFragmentByTag(FRAGMENT_TAG);
}
}
public abstract Fragment onCreateFragment();
public Fragment getFragment() {
return fragment;
}
}
kullanım
public class ViewCatalogItemActivity extends SingleFragmentActivity {
@Override
public Fragment onCreateFragment() {
return new FragmentWorkShops();
}
}