ViewPager를 동적으로 업데이트 하시겠습니까?
ViewPager에서 컨텐츠를 업데이트 할 수 없습니다.
FragmentPagerAdapter 클래스에서 instantiateItem () 및 getItem () 메소드의 올바른 사용법은 무엇입니까?
getItem () 만 사용하여 조각을 인스턴스화하고 반환했습니다.
@Override
public Fragment getItem(int position) {
return new MyFragment(context, paramters);
}
이것은 잘 작동했습니다. 내용을 변경할 수 없다는 점만 빼면
그래서 이것을 찾았습니다 : ViewPager PagerAdapter가 View를 업데이트하지 않습니다
"제 접근법은 instantiateItem () 메소드의 인스턴스화 된보기에 setTag () 메소드를 사용하는 것입니다"
이제 instantiateItem ()을 구현하고 싶습니다. 그러나 무엇을 반환 해야하는지 (유형은 Object) 모르겠으며 getItem (int position)과의 관계는 무엇입니까?
나는 참조를 읽었다 :
공개 추상 조각 getItem (int position)
지정된 위치와 관련된 조각을 반환합니다.
공용 객체 instantiateItem (ViewGroup 컨테이너, int 위치)
주어진 위치에 대한 페이지를 작성하십시오. 어댑터는 여기에 제공된 컨테이너에보기를 추가해야하지만 finishUpdate (ViewGroup)에서 리턴 될 때만 수행해야합니다. 매개 변수
컨테이너 페이지가 표시 될 포함보기입니다. position 인스턴스화 할 페이지 위치.
보고
새 페이지를 나타내는 Object를 리턴합니다. 이것은 뷰일 필요는 없지만 페이지의 다른 컨테이너 일 수 있습니다.
그러나 나는 여전히 그것을 얻지 못한다.
여기 내 코드가 있습니다. 지원 패키지 v4를 사용하고 있습니다.
ViewPagerTest
public class ViewPagerTest extends FragmentActivity {
private ViewPager pager;
private MyFragmentAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pager1);
pager = (ViewPager)findViewById(R.id.slider);
String[] data = {"page1", "page2", "page3", "page4", "page5", "page6"};
adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
pager.setAdapter(adapter);
((Button)findViewById(R.id.button)).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
reload();
}
});
}
private void reload() {
String[] data = {"changed1", "changed2", "changed3", "changed4", "changed5", "changed6"};
//adapter = new MyFragmentAdapter(getSupportFragmentManager(), 6, this, data);
adapter.setData(data);
adapter.notifyDataSetChanged();
pager.invalidate();
//pager.setCurrentItem(0);
}
}
MyFragmentAdapter
class MyFragmentAdapter extends FragmentPagerAdapter {
private int slideCount;
private Context context;
private String[] data;
public MyFragmentAdapter(FragmentManager fm, int slideCount, Context context, String[] data) {
super(fm);
this.slideCount = slideCount;
this.context = context;
this.data = data;
}
@Override
public Fragment getItem(int position) {
return new MyFragment(data[position], context);
}
@Override
public int getCount() {
return slideCount;
}
public void setData(String[] data) {
this.data = data;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
MyFragment
public final class MyFragment extends Fragment {
private String text;
public MyFragment(String text, Context context) {
this.text = text;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.slide, null);
((TextView)view.findViewById(R.id.text)).setText(text);
return view;
}
}
비슷한 문제가있는 사람도 있습니다. 답변 없음 http://www.mail-archive.com/android-developers@googlegroups.com/msg200477.html
FragmentPagerAdapter 또는 FragmentStatePagerAdapter를 사용할 때는 전적으로 getItem()
만지거나 전혀 손대지 않는 것이 가장 좋습니다 instantiateItem()
. instantiateItem()
- destroyItem()
- isViewFromObject()
PagerAdapter에 대한 인터페이스는 FragmentPagerAdapter의 사용이 훨씬 간단 구현하는 낮은 수준의 인터페이스 getItem()
인터페이스를.
이것에 들어가기 전에, 나는 명확히해야합니다
표시되는 실제 조각을 끄려면 FragmentPagerAdapter를 피하고 FragmentStatePagerAdapter를 사용해야합니다.
이 답변의 이전 버전은 FragmentPagerAdapter를 사용하는 실수를 예로 들었습니다. FragmentPagerAdapter는 처음 표시 된 후에는 FragmentPagerAdapter가 조각을 파괴하지 않기 때문에 작동하지 않습니다.
귀하가 링크 한 게시물에 제공된 setTag()
및 findViewWithTag()
해결 방법을 권장하지 않습니다 . 발견했듯이 조각을 사용 setTag()
하고 findViewWithTag()
작동하지 않으므로 일치하지 않습니다.
올바른 해결책은 재정의하는 것 getItemPosition()
입니다. 경우 notifyDataSetChanged()
라고, ViewPager 통화 getItemPosition()
가 다른 위치로 이동하거나 제거 할 필요가 있는지 여부를 확인하기 위해 어댑터에있는 모든 항목에.
기본적 getItemPosition()
으로을 반환합니다 POSITION_UNCHANGED
. 즉, "이 개체는 아무 곳에 나 있으면 파괴하거나 제거하지 마십시오." 반환 POSITION_NONE
대신에, 말을하지 않습니다에 의해 수정에게 문제를 "이 개체는 더 이상 내가 그것을 제거, 표시하고있어 항목입니다." 따라서 어댑터의 모든 단일 항목을 제거하고 다시 만드는 효과가 있습니다.
이것은 완전히 합법적 인 수정입니다! 이 수정 사항은 notifyDataSetChanged가보기 재활용없이 일반 어댑터처럼 작동하도록합니다. 이 수정 프로그램을 구현하고 성능이 만족 스럽다면 경쟁을 시작한 것입니다. 작업이 완료되었습니다.
더 나은 성능이 필요하면 더 멋진 getItemPosition()
구현을 사용할 수 있습니다 . 다음은 문자열 목록에서 조각을 만드는 호출기의 예입니다.
ViewPager pager = /* get my ViewPager */;
// assume this actually has stuff in it
final ArrayList<String> titles = new ArrayList<String>();
FragmentManager fm = getSupportFragmentManager();
pager.setAdapter(new FragmentStatePagerAdapter(fm) {
public int getCount() {
return titles.size();
}
public Fragment getItem(int position) {
MyFragment fragment = new MyFragment();
fragment.setTitle(titles.get(position));
return fragment;
}
public int getItemPosition(Object item) {
MyFragment fragment = (MyFragment)item;
String title = fragment.getTitle();
int position = titles.indexOf(title);
if (position >= 0) {
return position;
} else {
return POSITION_NONE;
}
}
});
이 구현에서는 새 제목을 표시하는 조각 만 표시됩니다. 여전히 목록에있는 제목을 표시하는 조각은 대신 목록에서 새 위치로 이동하고 더 이상 목록에없는 제목을 가진 조각은 삭제됩니다.
프래그먼트를 다시 만들지 않았지만 업데이트해야 할 경우 어떻게해야합니까? 살아있는 조각에 대한 업데이트는 조각 자체에 의해 가장 잘 처리됩니다. 그것은 결국 조각을 갖는 이점입니다. 그것은 자체 컨트롤러입니다. 조각은의 다른 객체에 리스너 또는 관찰자를 추가 한 onCreate()
다음에서 제거 onDestroy()
하여 업데이트 자체를 관리 할 수 있습니다. getItem()
ListView 또는 다른 AdapterView 유형의 어댑터에서와 같이 모든 업데이트 코드를 안에 넣을 필요는 없습니다 .
마지막으로 FragmentPagerAdapter가 프래그먼트를 파괴하지 않는다고해서 getItemPosition이 FragmentPagerAdapter에서 완전히 쓸모 없다는 것을 의미하지는 않습니다. 이 콜백을 사용하여 ViewPager에서 프래그먼트를 재정렬 할 수 있습니다. 그러나 FragmentManager에서 완전히 제거하지는 않습니다.
전체보기 재생 POSITION_NONE
에서 돌아와서 재생하는 대신 다음을 getItemPosition()
수행하십시오.
//call this method to update fragments in ViewPager dynamically
public void update(UpdateData xyzData) {
this.updateData = xyzData;
notifyDataSetChanged();
}
@Override
public int getItemPosition(Object object) {
if (object instanceof UpdateableFragment) {
((UpdateableFragment) object).update(updateData);
}
//don't return POSITION_NONE, avoid fragment recreation.
return super.getItemPosition(object);
}
조각은 UpdateableFragment
인터페이스 를 구현해야합니다 .
public class SomeFragment extends Fragment implements
UpdateableFragment{
@Override
public void update(UpdateData xyzData) {
// this method will be called for every fragment in viewpager
// so check if update is for this fragment
if(forMe(xyzData)) {
// do whatever you want to update your UI
}
}
}
그리고 인터페이스 :
public interface UpdateableFragment {
public void update(UpdateData xyzData);
}
귀하의 데이터 클래스 :
public class UpdateData {
//whatever you want here
}
7 조각이있는 ViewPager가있을 때 이전에 직면했던 것과 동일한 문제에 여전히 직면하는 사람들을 위해. 이 조각의 기본값은 api 서비스에서 영어 내용을로드하는 문제이지만 설정 활동에서 언어를 변경하고 설정 활동을 마친 후에 문제는 기본 활동의 ViewPager가 사용자의 언어 선택과 일치하도록 조각을 새로 고치기를 원합니다. 사용자가 아랍어를 선택한 경우 처음부터 작업 한 내용을 아랍어로로드
1- 위에서 언급 한대로 FragmentStatePagerAdapter를 사용해야합니다.
2-on mainActivity i는 onResume을 무시하고 다음을 수행했습니다.
if (!(mPagerAdapter == null)) {
mPagerAdapter.notifyDataSetChanged();
}
3-i는 mPagerAdapter의 getItemPosition ()을 재정 의하여 POSITION_NONE을 반환하도록했습니다.
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
매력처럼 작동합니다
나는이 문제에 직면하여 오늘 그것을 마침내 해결 했으므로 배운 것을 적어두고 Android에 익숙하지 않은 사람에게 도움이되기를 바랍니다 ViewPager
. FragmentStatePagerAdapter
API 레벨 17에서 사용 중이며 현재 2 개의 조각 만 있습니다. 정확하지 않은 것이 있어야한다고 생각합니다. 감사합니다.
직렬화 된 데이터는 메모리에로드되어야합니다. 이것은
CursorLoader
/AsyncTask
/를 사용하여 수행 할 수 있습니다Thread
. 자동로드 여부는 코드에 따라 다릅니다. 를 사용하는 경우CursorLoader
등록 된 데이터 관찰자가 있으므로 자동으로로드됩니다.을 호출 한 후에
viewpager.setAdapter(pageradapter)
는 어댑터getCount()
가 지속적으로 호출되어 프래그먼트를 빌드합니다. 따라서 데이터가로드되는 경우getCount()
0을 반환 할 수 있으므로 데이터가 표시되지 않도록 더미 조각을 만들 필요가 없습니다.데이터가로드 된
getCount()
후에도 여전히 0이므로 어댑터가 프래그먼트를 자동으로 빌드하지 않으므로 실제로로드 된 데이터 번호를로 설정getCount()
하여 어댑터의를 호출 할 수 있습니다notifyDataSetChanged()
.ViewPager
메모리의 데이터로 조각 (처음 두 조각 만)을 만들기 시작하십시오.notifyDataSetChanged()
반환 되기 전에 완료되었습니다 . 그런 다음ViewPager
필요한 조각이 있습니다.데이터베이스와 메모리의 데이터가 모두 업데이트 (쓰기)하거나 메모리의 데이터 만 업데이트 (다시 쓰기)되거나 데이터베이스의 데이터 만 업데이트되는 경우 마지막 두 경우에 데이터가 데이터베이스에서 메모리로 자동로드되지 않는 경우 (위에서 언급 한 바와 같이).
ViewPager
및 호출기 어댑터는 메모리에 데이터를 처리.따라서 메모리의 데이터가 업데이트되면 어댑터를 호출하기 만하면됩니다
notifyDataSetChanged()
. 프래그먼트가 이미 작성되었으므로 어댑터가 리턴onItemPosition()
되기 전에 호출됩니다notifyDataSetChanged()
. 에서 수행 할 작업이 없습니다getItemPosition()
. 그런 다음 데이터가 업데이트됩니다.
코드 destroyDrawingCache()
에서 ViewPager를 사용해보십시오 notifyDataSetChanged()
.
좌절의 시간이 문제를 극복하기 위해 위의 모든 솔루션을 시도 또한 같은 다른 유사한 문제에 많은 솔루션을하는 동안 후 이 , 이 그리고 이 모두가이 문제를 해결하고 만들기 위해 나와 함께 실패하는 ViewPager
기존의 파괴 Fragment
와 채우기 pager
로 새로운 Fragment
S. 다음과 같이 문제를 해결했습니다.
1) 만들기 기능 ViewPager
확장에 클래스를 FragmentPagerAdapter
다음과 같은 :
public class myPagerAdapter extends FragmentPagerAdapter {
2) 에 대한 항목을 작성 ViewPager
가게가 title
와를 fragment
다음과 같은 :
public class PagerItem {
private String mTitle;
private Fragment mFragment;
public PagerItem(String mTitle, Fragment mFragment) {
this.mTitle = mTitle;
this.mFragment = mFragment;
}
public String getTitle() {
return mTitle;
}
public Fragment getFragment() {
return mFragment;
}
public void setTitle(String mTitle) {
this.mTitle = mTitle;
}
public void setFragment(Fragment mFragment) {
this.mFragment = mFragment;
}
}
3) 인스턴스 생성자 를 다음과 같이 ViewPager
내 FragmentManager
인스턴스에 저장하십시오 class
.
private FragmentManager mFragmentManager;
private ArrayList<PagerItem> mPagerItems;
public MyPagerAdapter(FragmentManager fragmentManager, ArrayList<PagerItem> pagerItems) {
super(fragmentManager);
mFragmentManager = fragmentManager;
mPagerItems = pagerItems;
}
4) 다음과 같이 새 목록에서 새 항목을 다시 설정 하기 위해 직접 adapter
이전 항목 fragment
을 모두 삭제하여 새 데이터로 데이터 를 재설정하는 방법을 작성하십시오 .fragmentManager
adapter
fragment
public void setPagerItems(ArrayList<PagerItem> pagerItems) {
if (mPagerItems != null)
for (int i = 0; i < mPagerItems.size(); i++) {
mFragmentManager.beginTransaction().remove(mPagerItems.get(i).getFragment()).commit();
}
mPagerItems = pagerItems;
}
5) 컨테이너에서 Activity
또는 Fragment
새 데이터로 어댑터를 다시 초기화하지 마십시오. setPagerItems
다음과 같이 새 데이터로 메소드 를 통해 새 데이터를 설정하십시오 .
ArrayList<PagerItem> pagerItems = new ArrayList<PagerItem>();
pagerItems.add(new PagerItem("Fragment1", new MyFragment1()));
pagerItems.add(new PagerItem("Fragment2", new MyFragment2()));
mPagerAdapter.setPagerItems(pagerItems);
mPagerAdapter.notifyDataSetChanged();
도움이 되길 바랍니다.
어떤 이유로 든 대답이 나를 위해 일하지 않았으므로 fragmentStatePagerAdapter에서 super를 호출하지 않고 restoreState 메서드를 재정의해야했습니다. 암호:
private class MyAdapter extends FragmentStatePagerAdapter {
// [Rest of implementation]
@Override
public void restoreState(Parcelable state, ClassLoader loader) {}
}
Bill Phillips가 제공 한 솔루션을 필요에 맞게 약간 수정했습니다.
private class PagerAdapter extends FragmentStatePagerAdapter{
Bundle oBundle;
FragmentManager oFragmentManager;
ArrayList<Fragment> oPooledFragments;
public PagerAdapter(FragmentManager fm) {
super(fm);
oFragmentManager=fm;
}
@Override
public int getItemPosition(Object object) {
Fragment oFragment=(Fragment)object;
oPooledFragments=new ArrayList<>(oFragmentManager.getFragments());
if(oPooledFragments.contains(oFragment))
return POSITION_NONE;
else
return POSITION_UNCHANGED;
}
}
따라서 현재 시점 에있는 단편에 대해서만 getItemPosition()
리턴 이 호출됩니다. (이것 과 그 와 관련된 것은 활동이 아닌 조각에 포함되어 있습니다)POSITION_NONE
FragmentManager
getItemPosition
FragmentStatePager
ViewPager
비슷한 문제가 있었지만 기존 솔루션 (하드 코딩 된 태그 이름 등)을 신뢰하고 싶지 않아 M-WaJeEh의 솔루션을 작동시킬 수 없었습니다. 내 해결책은 다음과 같습니다.
getItem에서 생성 된 조각에 대한 참조를 배열로 유지합니다. configurationChange 또는 메모리 부족 또는 활동으로 돌아올 때 (-> 활동으로 돌아올 때 조각이 'getItem'을 다시 호출하지 않고 배열을 업데이트하지 않고 마지막 상태로 돌아갑니다. ).
이 문제를 피하기 위해 instantiateItem (ViewGroup, int)을 구현하고 다음과 같이 배열을 업데이트했습니다.
@Override
public Object instantiateItem(ViewGroup container, int position) {
Object o = super.instantiateItem(container, position);
if(o instanceof FragmentX){
myFragments[0] = (FragmentX)o;
}else if(o instanceof FragmentY){
myFragments[1] = (FragmentY)o;
}else if(o instanceof FragmentZ){
myFragments[2] = (FragmentZ)o;
}
return o;
}
따라서 한편으로는 저에게 맞는 솔루션을 찾아서 공유하고 싶었지만 다른 누군가가 비슷한 것을 시도했는지, 왜 내가하지 말아야 할 이유가 있는지 묻고 싶었습니다. 그렇게합니까? 지금까지 그것은 나를 위해 아주 잘 작동합니다 ...
EventBus 라이브러리를 사용 하여의 Fragment
콘텐츠 를 업데이트 합니다 ViewPager
. 로직은 EventBus 문서 와 마찬가지로 간단 합니다 . FragmentPagerAdapter
인스턴스 를 제어 할 필요가 없습니다 . 코드는 다음과 같습니다.
1 : 이벤트 정의
업데이트해야 할 메시지를 정의하십시오.
public class UpdateCountEvent {
public final int count;
public UpdateCountEvent(int count) {
this.count = count;
}
}
2. 구독자 준비
업데이트가 필요한 조각에 아래 코드를 작성하십시오.
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
public void onEvent(UpdateCountEvent event) {//get update message
Toast.makeText(getActivity(), event.count, Toast.LENGTH_SHORT).show();
}
3. 포스트 이벤트
매개 변수를 업데이트 해야하는 다른 코드 Activity
또는 다른 코드로 아래 코드를 작성하십시오.Fragment
//input update message
EventBus.getDefault().post(new UpdateCountEvent(count));
FragmentStatePagerAdapter를 사용하려면 https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary% 를 참조하십시오. 20Stars & groupby = & sort = & id = 37990 . FragmentStatePagerAdapter에 사용 사례에 문제가 있거나 없을 수있는 문제가 있습니다.
또한 링크에는 솔루션이 거의 없습니다. 요구 사항에 거의 맞지 않을 수 있습니다.
나는 같은 문제를 겪었고 너무 많은 시간을 검색했습니다. stackoverflow 또는 Google을 통해 주어진 답변은 내 문제에 대한 해결책이 아닙니다. 내 문제는 쉬웠다. 목록이 있는데 viewpager와 함께이 목록을 보여줍니다. 목록 헤드에 새 요소를 추가하고 뷰 페이지를 새로 고치면 아무것도 변경되지 않습니다. 내 최종 솔루션은 누구나 쉽게 사용할 수 있습니다. 새 요소가 목록에 추가되고 목록을 새로 고치려고 할 때 먼저 viewpager adapter를 null로 설정 한 다음 어댑터를 다시 작성하고 i를 viewpager로 설정하십시오.
myVPager.setAdapter(null);
myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(),newList);
myVPager.setAdapter(myFragmentAdapter);
어댑터가 FragmentStatePagerAdapter를 확장해야합니다
나는 많은 다른 접근법을 시도했지만 아무도 내 문제를 해결하지 못했습니다. 다음은 모두가 제공하는 다양한 솔루션으로 해결하는 방법입니다. 모두 감사합니다.
class PagerAdapter extends FragmentPagerAdapter {
public boolean flag_refresh=false;
public PagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int page) {
FragmentsMain f;
f=new FragmentsMain();
f.page=page;
return f;
}
@Override
public int getCount() {
return 4;
}
@Override
public int getItemPosition(Object item) {
int page= ((FragmentsMain)item).page;
if (page == 0 && flag_refresh) {
flag_refresh=false;
return POSITION_NONE;
} else {
return super.getItemPosition(item);
}
}
@Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
}
onResume () 후에 페이지 0 만 새로 고치고 싶습니다.
adapter=new PagerAdapter(getSupportFragmentManager());
pager.setAdapter(adapter);
@Override
protected void onResume() {
super.onResume();
if (adapter!=null) {
adapter.flag_refresh=true;
adapter.notifyDataSetChanged();
}
}
내 FragmentsMain에는 공용 정수 "page"가 있는데, 이는 새로 고칠 페이지인지 여부를 알려줍니다.
public class FragmentsMain extends Fragment {
private Cursor cursor;
private static Context context;
public int page=-1;
나는 당에 늦었다는 것을 안다. TabLayout#setupWithViewPager(myViewPager);
방금 전화를 걸어 문제를 해결했습니다.FragmentPagerAdapter#notifyDataSetChanged();
이 솔루션은 모든 사람에게 적용되지는 않지만 제 경우에는 ViewPager의 모든 조각이 다른 클래스이며 한 번에 하나만 존재합니다.
이 제약 조건으로 인해이 솔루션은 안전하며 프로덕션 환경에서 안전하게 사용해야합니다.
private void updateFragment(Item item) {
List<Fragment> fragments = getSupportFragmentManager().getFragments();
for (Fragment fragment : fragments) {
if (fragment instanceof MyItemFragment && fragment.isVisible()) {
((MyItemFragment) fragment).update(item);
}
}
}
동일한 프래그먼트의 여러 버전이있는 경우이 동일한 전략을 사용하여 해당 프래그먼트에서 메소드를 호출하여 업데이트하려는 프래그먼트인지 판별 할 수 있습니다.
이것은 누군가에게 도움이 될 수 있습니다-제 경우에는 뷰 페이저가 기존 조각의 위치를 두 번 요구했지만 새 항목의 위치를 요구하지 않아 잘못된 동작과 데이터가 표시되지 않습니다.
FragmentStatePagerAdapter의 소스를 복사하십시오 (연령이 업데이트되지 않은 것으로 보임).
notifyDataSetChanged () 재정의
@Override public void notifyDataSetChanged() { mFragments.clear(); super.notifyDataSetChanged(); }
충돌을 방지하기 위해 destroyItem ()에 위생 검사를 추가하십시오.
if (position < mFragments.size()) { mFragments.set(position, null); }
위의 모든 답변과 여러 다른 게시물을 살펴 보았지만 여전히 다른 조각 유형과 함께 동적으로 탭을 추가 및 제거하는 기능을 찾을 수 없었습니다. FWIW 다음 접근법은 나를 위해 일한 것입니다 (다른 사람이 같은 문제가있는 경우).
public class MyFragmentStatePageAdapter extends FragmentStatePagerAdapter {
private static final String TAB1_TITLE = "Tab 1";
private static final String TAB2_TITLE = "Tab 2";
private static final String TAB3_TITLE = "Tab 3";
private ArrayList<String> titles = new ArrayList<>();
private Map<Fragment, Integer> fragmentPositions = new HashMap<>();
public MyFragmentStatePageAdapter(FragmentManager fm) {
super(fm);
}
public void update(boolean showTab1, boolean showTab2, boolean showTab3) {
titles.clear();
if (showTab1) {
titles.add(TAB1_TITLE);
}
if (showTab2) {
titles.add(TAB2_TITLE);
}
if (showTab3) {
titles.add(TAB3_TITLE);
}
notifyDataSetChanged();
}
@Override
public int getCount() {
return titles.size();
}
@Override
public Fragment getItem(int position) {
Fragment fragment = null;
String tabName = titles.get(position);
if (tabName.equals(TAB1_TITLE)) {
fragment = Tab1Fragment.newInstance();
} else if (tabName.equals(TAB2_TITLE)) {
fragment = Tab2Fragment.newInstance();
} else if (tabName.equals(TAB3_TITLE)) {
fragment = Tab3Fragmen.newInstance();
}
((BaseFragment)fragment).setTitle(tabName);
fragmentPositions.put(fragment, position);
return fragment;
}
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
@Override
public int getItemPosition(Object item) {
BaseFragment fragment = (BaseFragment)item;
String title = fragment.getTitle();
int position = titles.indexOf(title);
Integer fragmentPosition = fragmentPositions.get(item);
if (fragmentPosition != null && position == fragmentPosition) {
return POSITION_UNCHANGED;
} else {
return POSITION_NONE;
}
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
fragmentPositions.remove(object);
}
}
인덱스 기반으로 프래그먼트를 다시 작성하거나 다시로드하려면 FragmentPagerAdapter 대신 FragmentStatePagerAdapter를 사용하십시오. 예를 들어 FirstFragment 이외의 프래그먼트를 다시로드하려는 경우 인스턴스를 확인하고 다음과 같이 위치를 리턴 할 수 있습니다.
public int getItemPosition(Object item) {
if(item instanceof FirstFragment){
return 0;
}
return POSITION_NONE;
}
다음은 @Bill Phillips One의 정보를 통합 한 구현으로, 데이터가 변경된 경우를 제외하고 대부분 조각 캐싱을 가져옵니다. 간단하고 잘 작동하는 것 같습니다.
MyFragmentStatePagerAdapter.java
private boolean mIsUpdating = false;
public void setIsUpdating(boolean mIsUpdating) {
this.mIsUpdating = mIsUpdating;
}
@Override
public int getItemPosition(@NonNull Object object) {
if (mIsUpdating) {
return POSITION_NONE;
}
else {
return super.getItemPosition(object);
}
}
MyActivity.java
mAdapter.setIsUpdating(true);
mAdapter.notifyDataSetChanged();
mAdapter.setIsUpdating(false);
참고 URL : https://stackoverflow.com/questions/10849552/update-viewpager-dynamically
'development' 카테고리의 다른 글
Windows 10에서 Linux Bash 경고음을 비활성화합니다. (0) | 2020.03.15 |
---|---|
정규식 : 첫 문자 발생까지 일치 (0) | 2020.03.15 |
힘내-현재 분기 바로 가기를 밀어 (0) | 2020.03.15 |
CSS에서만 위첨자? (0) | 2020.03.15 |
NSLog에서 부울 플래그를 인쇄하는 방법? (0) | 2020.03.15 |