Nested Fragment (Android 4.2)를 사용하여 ViewPager 내에 Fragment를 추가하는 방법
나는 ViewPager
세 개를 가지고 있으며 Fragments
, 각각은 List
(또는 Grid
)을 보여줍니다 .
새로운 Android API level 17
(Jelly Bean 4.2)에서 기능 중 하나는 Nested Fragments 입니다. 새로운 기능 설명은 다음과 같습니다.
ViewPager를 사용하여 왼쪽과 오른쪽으로 스 와이프하고 화면 공간의 대부분을 차지하는 조각을 만드는 경우 이제 각 조각 페이지에 조각을 삽입 할 수 있습니다.
그래서 내가 이해한다면, 이제 내부에 (예를 들어 버튼이 있는) ViewPager
with를 만들 수 있으며 Fragments
, 사용자가 버튼을 누르면 이 새로운 기능을 사용하여 Fragment
느슨하게 다른 것을 보여줄 수 ViewPager
있습니다.
저는 아침에 이것을 여러 가지 방법으로 구현하려고 노력했지만 작동하지 않습니다. 누군가 이것을 구현하는 방법에 대한 간단한 예제를 추가 할 수 있습니까?
추신 : 저는 이런 식으로하는 일에만 관심이 getChildFragmentManager
있습니다.
올바른 xml 레이아웃을 만들었다 고 가정합니다. 이제 다른 Fragment에서 호스팅하는 ViewPager에 조각을 표시하는 것은 매우 간단합니다.
다음은 자식 조각을 표시하는 부모 조각입니다.
class ParentViewPagerFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val root = inflater.inflate(R.layout.fragment_parent_viewpager, container, false)
val viewPager = root.findViewById(R.id.viewPager) as ViewPager
// Important: Must use the child FragmentManager or you will see side effects.
viewPager.adapter = MyAdapter(childFragmentManager)
val tabStrip = root.findViewById<TabLayout>(R.id.pagerTabStrip)
tabStrip.setupWithViewPager(viewPager)
return root
}
class MyAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm) {
override fun getCount(): Int = 4
override fun getItem(position: Int): Fragment {
val args = Bundle().apply { putInt(ChildFragment.POSITION_KEY, position) }
return ChildFragment.newInstance(args)
}
override fun getPageTitle(position: Int): CharSequence = "Tab $position"
}
companion object {
val TAG: String = ParentViewPagerFragment::class.java.name
}
}
FragmentPagerAdapter 를 인스턴스화 할 때 Fragment.getChildFragmentManager () 를 사용하는 것이 중요합니다 . 또한 자식 조각에 Fragment.setRetainInstance () 를 사용할 수 없으며 예외가 발생합니다. 간결성을 위해 수입품은 생략되었습니다.
소스 코드는 https://github.com/marcoRS/nested-fragments 에서 찾을 수 있습니다.
편집 : 페이지의 모든 내용을 바꾸려면 ViewPager
중첩 된 조각을 사용할 수 있지만 일부 변경이 필요합니다. 아래 샘플을 확인하십시오 ( FragmentActivity
, 설정 ViewPager
및 설정 PagerAdapter
은 이전 코드 스 니펫과 동일 함).
// this will act as a fragment container, representing one page in the ViewPager
public static class WrapperFragment extends Fragment implements
ReplaceListener {
public static WrapperFragment newInstance(int position) {
WrapperFragment wp = new WrapperFragment();
Bundle args = new Bundle();
args.putInt("position", position);
wp.setArguments(args);
return wp;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FrameLayout fl = new FrameLayout(getActivity());
fl.setId(10000);
if (getChildFragmentManager().findFragmentByTag("initialTag") == null) {
InitialInnerFragment iif = new InitialInnerFragment();
Bundle args = new Bundle();
args.putInt("position", getArguments().getInt("position"));
iif.setArguments(args);
getChildFragmentManager().beginTransaction()
.add(10000, iif, "initialTag").commit();
}
return fl;
}
// required because it seems the getChildFragmentManager only "sees"
// containers in the View of the parent Fragment.
@Override
public void onReplace(Bundle args) {
if (getChildFragmentManager().findFragmentByTag("afterTag") == null) {
InnerFragment iif = new InnerFragment();
iif.setArguments(args);
getChildFragmentManager().beginTransaction()
.replace(10000, iif, "afterTag").addToBackStack(null)
.commit();
}
}
}
// the fragment that would initially be in the wrapper fragment
public static class InitialInnerFragment extends Fragment {
private ReplaceListener mListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mListener = (ReplaceListener) this.getParentFragment();
LinearLayout ll = new LinearLayout(getActivity());
Button b = new Button(getActivity());
b.setGravity(Gravity.CENTER_HORIZONTAL);
b.setText("Frame " + getArguments().getInt("position"));
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Bundle args = new Bundle();
args.putInt("positionInner",
getArguments().getInt("position"));
if (mListener != null) {
mListener.onReplace(args);
}
}
});
ll.setOrientation(LinearLayout.VERTICAL);
ll.addView(b, new LinearLayout.LayoutParams(250,
LinearLayout.LayoutParams.WRAP_CONTENT));
return ll;
}
}
public static class InnerFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView tv = new TextView(getActivity());
tv.setText("InnerFragment in the outher Fragment with position "
+ getArguments().getInt("positionInner"));
return tv;
}
}
public interface ReplaceListener {
void onReplace(Bundle args);
}
빠르게 살펴보면 작동하지만 많이 테스트하지 않았기 때문에 문제가 나타날 수 있습니다.
누군가 이것을 수행하는 방법에 대한 간단한 예를 보여줄 수 있습니까?
Commonsware가 더 정교한 샘플을 제공하기 전까지는 중첩 된 조각을 사용하는 것이 매우 쉬워 보입니다. 아래 코드를 시도해 볼 수 있습니다.
public class NestedFragments extends FragmentActivity {
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
ViewPager vp = new ViewPager(this);
vp.setId(5000);
vp.setAdapter(new MyAdapter(getSupportFragmentManager()));
setContentView(vp);
}
private static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return WrapperFragment.newInstance(position);
}
@Override
public int getCount() {
return 8;
}
}
public static class WrapperFragment extends Fragment {
public static WrapperFragment newInstance(int position) {
WrapperFragment wp = new WrapperFragment();
Bundle args = new Bundle();
args.putInt("position", position);
wp.setArguments(args);
return wp;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout ll = new LinearLayout(getActivity());
FrameLayout innerFragContainer = new FrameLayout(getActivity());
innerFragContainer.setId(1111);
Button b = new Button(getActivity());
b.setText("Frame " + getArguments().getInt("position"));
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
InnerFragment innerFragment = new InnerFragment();
Bundle args = new Bundle();
args.putInt("positionInner",
getArguments().getInt("position"));
innerFragment.setArguments(args);
FragmentTransaction transaction = getChildFragmentManager()
.beginTransaction();
transaction.add(1111, innerFragment).commit();
}
});
ll.setOrientation(LinearLayout.VERTICAL);
ll.addView(b, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
ll.addView(innerFragContainer, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
return ll;
}
}
public static class InnerFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView tv = new TextView(getActivity());
tv.setText("InnerFragment in the outher Fragment with position "
+ getArguments().getInt("positionInner"));
return tv;
}
}
}
나는 게으르고 모든 것을 코드로 만들었지 만 팽창 된 xml 레이아웃과 함께 작동 할 수 있다고 확신합니다.
인덱스 2와 3에 대해 3 개의 요소와 2 개의 하위 요소가있는 ViewPager를 만들었습니다.
I have implemented this with the help from previous questions and answers from StackOverFlow and here is the link.
ReferenceURL : https://stackoverflow.com/questions/13379194/how-to-add-a-fragment-inside-a-viewpager-using-nested-fragment-android-4-2
'IT story' 카테고리의 다른 글
JSON 문자 인코딩 (0) | 2021.01.06 |
---|---|
래퍼 내 두 범위 중 하나의 텍스트 오버플로 줄임표 (0) | 2021.01.06 |
통합 테스트 전체 객체를 Spring MVC 컨트롤러에 게시 (0) | 2021.01.06 |
고 루틴에서 반환 값 잡기 (0) | 2021.01.06 |
enum에서 내부 인터페이스를 구현할 때 순환 상속 (0) | 2021.01.06 |