bestsource

프로그래밍 방식으로 작성된 내용 보기를 사용하여 활동에 조각을 추가하는 방법

bestsource 2023. 10. 11. 20:50
반응형

프로그래밍 방식으로 작성된 내용 보기를 사용하여 활동에 조각을 추가하는 방법

레이아웃을 프로그래밍 방식으로 구현하는 액티비티에 프래그먼트를 추가합니다.프래그먼트 문서를 검토해 보았지만 필요한 것을 설명하는 예시가 많지 않습니다.다음은 제가 작성하려고 한 코드 유형입니다.

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 파일을 작성하면 수정됩니다.

두 번째 문제는 이런 방식으로 조각을 추가할 때 조각의 포함된 보기에 대한 참조를 전달해야 하고, 해당 보기에는 사용자 지정 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;
        }
    }
}

토니 웡의 코멘트를 읽고 생각해낸 것은 다음과 같습니다.

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";

    // ...

}

코틀린

만약 당신이 코틀린을 사용하고 있다면 구글의 코틀린 확장자가 제공하는 것을 꼭 살펴보거나 당신의 것을 써보세요.

    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();
        }
    }

Activity 또는 Frame Activity에 조각을 추가하려면 Container가 필요합니다.그 컨테이너는 ""이어야 합니다.Framelayout", xml에 포함될 수 있거나 그렇지 않으면 "와 같은 기본 컨테이너를 사용할 수 있습니다.android.R.id.content" Activity에서 조각을 제거하거나 바꿉니다.

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을 fragment의 컨테이너로 추가할 필요가 없습니다. 대신 fragment를 Android root View 컨테이너에 직선으로 추가할 수 있습니다.

중요: 재생성 프로세스 중에 fragment 변수 인스턴스 상태가 손실되는 것을 개의치 않는 한, 여기에 표시된 대부분의 접근 방식으로 fragment 교체를 사용하지 마십시오.

Kotlin에서 프로그래밍 방식으로 액티비티에 프래그먼트를 첨부하는 경우 다음 코드를 확인할 수 있습니다.

주 활동 .kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

            // create fragment instance
            val fragment : FragmentName = FragmentName.newInstance()

            // for passing data to fragment
            val bundle = Bundle()
            bundle.putString("data_to_be_passed", DATA)
            fragment.arguments = bundle

            // check is important to prevent activity from attaching the fragment if already its attached
            if (savedInstanceState == null) {
                supportFragmentManager
                    .beginTransaction()
                    .add(R.id.fragment_container, fragment, "fragment_name")
                    .commit()
            }
        }

    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.MainActivity">

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

FragmentName.kt

class FragmentName : Fragment() {

    companion object {
        fun newInstance() = FragmentName()
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        // receiving the data passed from activity here
        val data = arguments!!.getString("data_to_be_passed")
        return view
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
    }

}

만약 당신이 Kotlin의 Extensions에 대해 잘 알고 있다면, 당신은 이 기사를 따라 이 코드를 더욱 개선할 수 있습니다.

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 이상의 경우, 는 이 문제를 해결해 줄 것입니다.유틸리티 메서드는 빌드 시간에 사용되지 않는 고유 ID를 제공합니다.

이것은 당신에게 도움이 될 것입니다.

조각 정의

조각 보기 fragment_abc.xml에 대한 xml 파일 생성

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="TextView" />

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button" />

</LinearLayout>

조각 ABCFragment.java를 만듭니다.

import androidx.fragment.app.Fragment;

public class FooFragment extends Fragment {
// The onCreateView method is called when Fragment should create its View object hierarchy,
// either dynamically or via XML layout inflation. 

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle 
savedInstanceState) {
    // Defines the xml file for the fragment
    return inflater.inflate(R.layout.fragment_abc, parent, false);
}

// This event is triggered soon after onCreateView().
// Any view setup should occur here.  E.g., view lookups and attaching view listeners.
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    // Setup any handles to view objects here
    // EditText etFoo = (EditText) view.findViewById(R.id.etFoo);
}
}

활동에 frameLayout 추가

<FrameLayout
   android:id="@+id/your_placeholder"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

지금 활동중, 다음 메소드를 추가합니다.

protected void setFragment() {
    // Begin the transaction
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    // Replace the contents of the container with the new fragment
    ft.replace(R.id.fragment_container, new ABCFragment());
    // or ft.add(R.id.your_placeholder, new ABCFragment());
    // Complete the changes added above
    ft.commit();
}

참조 : https://guides.codepath.com/android/creating-and-using-fragments#defining-a-fragment

언급URL : https://stackoverflow.com/questions/5159982/how-do-i-add-a-fragment-to-an-activity-with-a-programmatically-created-content-v

반응형