프로그래밍 방식으로 작성된 컨텐츠 뷰를 사용하여 활동에 프래그먼트를 추가하는 방법
프로그래밍 방식으로 레이아웃을 구현하는 활동에 Fragment를 추가하고 싶습니다. Fragment 문서를 살펴 보았지만 필요한 것을 설명하는 예제는 많지 않습니다. 작성하려고 시도한 코드 유형은 다음과 같습니다.
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;
}
}
이 코드는 컴파일되지만 시작시 충돌합니다. 아마도 내 FragmentTransaction.add()
것이 올바르지 않기 때문일 것 입니다. 이를 수행하는 올바른 방법은 무엇입니까?
해당 코드에 하나 이상의 문제가 있음이 밝혀졌습니다. 액티비티와 동일한 Java 파일 내에서는 공개 내부 클래스가 아닌 프래그먼트를 선언 할 수 없습니다. 프레임 워크는 조각의 생성자 (매개 변수 없음)가 공개되고 표시 될 것으로 예상합니다. 프래그먼트를 내부 클래스로 Activity로 이동하거나 프래그먼트에 대한 새 Java 파일을 작성하면 문제가 해결됩니다.
두 번째 문제는이 방법으로 조각을 추가 할 때 조각의 포함보기에 대한 참조를 전달해야하며 해당보기에는 사용자 정의 ID가 있어야한다는 것입니다. 기본 ID를 사용하면 앱이 중단됩니다. 업데이트 된 코드는 다음과 같습니다.
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;
}
}
}
Tony Wong의 의견을 읽은 후에 생각해 낸 내용은 다음과 같습니다 .
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을 사용하는 경우 Google 의 Kotlin 확장 프로그램 이 제공하는 기능을 보거나 직접 작성하십시오.
public class Example1 extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DemoFragment fragmentDemo = (DemoFragment)
getSupportFragmentManager().findFragmentById(R.id.frame_container);
//above part is to determine which fragment is in your frame_container
setFragment(fragmentDemo);
(OR)
setFragment(new TestFragment1());
}
// This could be moved into an abstract BaseActivity
// class for being re-used by several instances
protected void setFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, fragment);
fragmentTransaction.commit();
}
}
활동 또는 FramentActivity에 조각을 추가하려면 컨테이너가 필요합니다. 해당 컨테이너는 "
Framelayout
" 이어야하며 이는 XML에 포함될 수 있으며 그렇지 않으면 "android.R.id.content
" 와 같은 기본 컨테이너를 사용하여 활동에서 단편을 제거하거나 바꿀 수 있습니다.
main.xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="@+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/imagenext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_margin="16dp"
android:src="@drawable/next" />
</RelativeLayout>
모든 답변을 읽은 후 나는 우아한 방법을 생각해 냈습니다.
public class MyActivity extends ActionBarActivity {
Fragment fragment ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = getSupportFragmentManager();
fragment = fm.findFragmentByTag("myFragmentTag");
if (fragment == null) {
FragmentTransaction ft = fm.beginTransaction();
fragment =new MyFragment();
ft.add(android.R.id.content,fragment,"myFragmentTag");
ft.commit();
}
}
기본적으로 프래그먼트의 컨테이너로 frameLayout을 추가 할 필요가 없습니다 대신 안드로이드 루트 뷰 컨테이너에 프래그먼트를 똑바로 추가 할 수 있습니다
중요 : onrecreation 프로세스 중에 프래그먼트 변수 인스턴스 상태를 잃어 버리지 않는 한 여기에 표시된 대부분의 접근 방식으로 replace 프래그먼트 를 사용 하지 마십시오 .
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;
}
}
사용하다
public class ViewCatalogItemActivity extends SingleFragmentActivity {
@Override
public Fragment onCreateFragment() {
return new FragmentWorkShops();
}
}
대한 API 레벨 17 이상, View.generateViewId()
이 문제를 해결합니다. 유틸리티 메소드는 빌드 시간에 사용되지 않는 고유 ID를 제공합니다.
'Programing' 카테고리의 다른 글
express.Router와 app.get의 차이점은 무엇입니까? (0) | 2020.04.23 |
---|---|
람다 이벤트 핸들러를 제거하는 방법 (0) | 2020.04.23 |
리스트 (0) | 2020.04.23 |
모든 JavaScript 오류를 잡아서 서버로 전송 (0) | 2020.04.23 |
v4 이전에 MongoDB가 ACID를 준수하지 않는 것은 실제로 무엇을 의미 했습니까? (0) | 2020.04.23 |