ViewPager에 동적으로 페이지 추가 / 삭제
뷰 페이저에서 동적으로 페이지를 추가하거나 삭제하고 싶습니다. 가능합니까?
예, ViewPager는 PagerAdapter에서 하위 뷰를 가져 오므로 새 페이지를 추가하거나 페이지를 삭제하고 .notifyDataSetChanged ()를 호출하여 다시로드 할 수 있습니다.
예. ViewPager에 뷰를 제공하는 PagerAdapter에 뷰를 동적으로 추가하거나 삭제할 수 있으며 PagerAdapter notifyDataSetChanged()
에서 호출 하여 변경 사항에 대해 영향을받는 ViewPager에 경고 할 수 있습니다. 그러나 그렇게 할 때 getItemPosition(Object)
현재 표시되는 항목의 위치가 변경되었는지 여부를 알려주는 PagerAdapter 의 를 재정의해야합니다 . 기본적으로이 함수는로 설정되어 POSITION_UNCHANGED
있으므로이 메서드를 재정의하지 않으면 ViewPager가 즉시 새로 고쳐지지 않습니다. 예를 들면
public class mAdapter extends PagerAdapter {
List<View> mList;
public void addView(View view, int index) {
mList.add(index, view);
notifyDataSetChanged();
}
public void removeView(int index) {
mList.remove(index);
notifyDataSetChanged();
}
@Override
public int getItemPosition(Object object)) {
if (mList.contains(object) {
return mList.indexOf(object);
} else {
return POSITION_NONE;
}
}
}
그러나 PagerAdapter의 데이터 세트가 아닌 디스플레이에서 일시적으로보기를 추가하거나 제거하려는 경우 setPrimaryItem(ViewGroup, int, Object)
PagerAdapter의 데이터에서 특정보기로 이동하고 destroyItem(ViewGroup, int, Object)
표시에서보기를 제거하기 위해 를 사용해보십시오 .
예, 코드는 다음과 같아야합니다.
public int addPage(View view, int position) {
if ((position >= 0) && (position < getSize())) {
myPagerAdapter.mListViews.add(position, view);
myPagerAdapter.notifyDataSetChanged();
return position;
} else {
return -1;
}
}
public View removePage(int position) {
if ((position < 0) || (position >= getSize()) || (getSize()<=1)) {
return null;
} else {
if (position == mPager.getCurrentItem()) {
if(position == (getSize()-1)) {
mPager.setCurrentItem(position-1);
} else if (position == 0){
mPager.setCurrentItem(1);
}
}
View tempView = myPagerAdapter.mListViews.remove(position);
myPagerAdapter.notifyDataSetChanged();
return tempView;
}
}
하지만 버그가 있습니다. 현재 항목이 0이고 페이지 0을 제거하면 화면이 즉시 새로 고쳐지지 않으며 이에 대한 해결책을 찾지 못했습니다.
이 질문에 대한 대안이 있습니다. 내 어댑터 :
private class PagerAdapter extends FragmentPagerAdapter implements
ViewPager.OnPageChangeListener, TabListener {
private List<Fragment> mFragments = new ArrayList<Fragment>();
private ViewPager mPager;
private ActionBar mActionBar;
private Fragment mPrimaryItem;
public PagerAdapter(FragmentManager fm, ViewPager vp, ActionBar ab) {
super(fm);
mPager = vp;
mPager.setAdapter(this);
mPager.setOnPageChangeListener(this);
mActionBar = ab;
}
public void addTab(PartListFragment frag) {
mFragments.add(frag);
mActionBar.addTab(mActionBar.newTab().setTabListener(this).
setText(frag.getPartCategory()));
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
/** (non-Javadoc)
* @see android.support.v4.app.FragmentStatePagerAdapter#setPrimaryItem(android.view.ViewGroup, int, java.lang.Object)
*/
@Override
public void setPrimaryItem(ViewGroup container, int position,
Object object) {
super.setPrimaryItem(container, position, object);
mPrimaryItem = (Fragment) object;
}
/** (non-Javadoc)
* @see android.support.v4.view.PagerAdapter#getItemPosition(java.lang.Object)
*/
@Override
public int getItemPosition(Object object) {
if (object == mPrimaryItem) {
return POSITION_UNCHANGED;
}
return POSITION_NONE;
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) { }
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) { }
@Override
public void onPageScrollStateChanged(int arg0) { }
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) { }
@Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
/**
* This method removes the pages from ViewPager
*/
public void removePages() {
mActionBar.removeAllTabs();
//call to ViewPage to remove the pages
vp.removeAllViews();
mFragments.clear();
//make this to update the pager
vp.setAdapter(null);
vp.setAdapter(pagerAdapter);
}
}
동적으로 제거하고 추가하는 코드
//remove the pages. basically call to method removeAllViews from ViewPager
pagerAdapter.removePages();
pagerAdapter.addPage(pass your fragment);
Peri Hartman 의 조언에 null
따라 ViewPager 어댑터로 설정 하고 뷰가 제거 된 후 어댑터를 다시 넣은 후 작동하기 시작했습니다 . 이 전에 페이지 0은 목록 내용을 표시하지 않습니다.
PageAdapter를 확장하여 어댑터를 만들었을 것이므로 한 가지 방법이 있습니다.
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
}
이에 대한 자세한 예를 보려면 이 예를 참조하십시오 .
첫째 : pagerAdapter 메소드 "getItemPosition"을 재정의합니다.
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
둘째 : 어댑터로 데이터 바인딩을 제거하고 adapter.notifydatachanged를 호출합니다.
@Bind(R.id.pager)
ViewPager pager;
int pos = pager.getCurrentItem();
pager.removeViewAt(pos);
이 솔루션은 지금까지 잘 작동합니다.
public class CustomPagerAdapter extends PagerAdapter {
private final List<Item> objects = new ArrayList<>();
public CustomPagerAdapter(List<Item> objects) {
if (objects != null) {
this.objects.add(objects);
}
}
@Override
public int getCount() {
return objects.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
Item item = (Item) object;
ItemView itemView = (ItemView) view;
return Objects.equals(itemView.getItem(), item);
}
@Override
public int getItemPosition(Object object) {
Item item = (Item) object;
int idx = objects.indexOf(item);
return idx == -1 ? POSITION_NONE : idx;
}
@Override
public Item instantiateItem(ViewGroup container, int position) {
Item item = objects.get(position);
final int id = generateViewIdForItem(item);
ItemView itemView = new ItemView(container.getContext());
itemView.setId(id);
container.addView(itemView);
itemView.setItem(item);
return item;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
Item item = (Item) object;
final int id = generateViewIdForItem(item);
View view = container.findViewById(id);
if (view != null) {
container.removeView(view);
}
}
public void update(@Nullable List<Item> objects) {
this.objects.clear();
if (objects != null) {
this.objects.addAll(objects);
}
notifyDataSetChanged();
}
public void clear() {
update(null);
}
/* add remove/update/add methods if you need, don't forget to call notifyDataSetChanged */
private static int generateViewIdForItem(Item item) {
return Math.abs(item.hashCode());
}
}
참고 :
- 당신의
Item
클래스에 해당 구현이 포함되어야합니다equals
및hashCode
방법을 - 귀하의
ItemView
클래스는 대한 getter와 setter 있어야합니다Item
개체를.
다른 답변 및 기타 리소스를 기반으로이 코드로 끝났습니다.
CustomPagerAdapter :
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CustomPagerAdapter extends PagerAdapter {
private List<Fragment> pages = new ArrayList<>();
private Map<Fragment, Integer> fragmentsPosition = new HashMap<>();
private Fragment currentPrimaryItem;
private FragmentManager fragmentManager;
private FragmentTransaction currentTransaction;
public CustomPagerAdapter(FragmentManager fragmentManager) {
this.fragmentManager = fragmentManager;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
Fragment pageFragment = pages.get(position);
String tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG);
Fragment fragment = fragmentManager.findFragmentByTag(tag);
if (fragment != null) {
if (fragment.getId() == container.getId()) {
currentTransaction.attach(fragment);
}
else {
fragmentManager.beginTransaction().remove(fragment).commit();
fragmentManager.executePendingTransactions();
currentTransaction.add(container.getId(), fragment, tag);
}
}
else {
fragment = pageFragment;
currentTransaction.add(container.getId(), fragment, tag);
}
if (fragment != currentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
}
return fragment;
}
@Override
public int getCount() {
return pages.size();
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (currentTransaction == null) {
currentTransaction = fragmentManager.beginTransaction();
}
currentTransaction.detach((Fragment) object);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment) object;
if (fragment != currentPrimaryItem) {
if (currentPrimaryItem != null) {
currentPrimaryItem.setMenuVisibility(false);
currentPrimaryItem.setUserVisibleHint(false);
}
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
}
currentPrimaryItem = fragment;
}
}
@Override
public void finishUpdate(ViewGroup container) {
if (currentTransaction != null) {
currentTransaction.commitAllowingStateLoss();
currentTransaction = null;
fragmentManager.executePendingTransactions();
}
}
@Override
public boolean isViewFromObject(View view, Object object) {
return ((Fragment) object).getView() == view;
}
@Override
public int getItemPosition(Object o) {
Integer result = fragmentsPosition.get(o);
if (result == null) {
return PagerAdapter.POSITION_UNCHANGED;
}
return result;
}
// ---------------------------------- Page actions ----------------------------------
public void addPage(Fragment fragment) {
fragmentsPosition.clear();
pages.add(fragment);
notifyDataSetChanged();
}
public void removePage(int position) {
fragmentsPosition.clear();
Fragment pageFragment = pages.get(position);
String tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG);
Fragment fragment = fragmentManager.findFragmentByTag(tag);
if (fragment != null) {
fragmentsPosition.put(fragment, PagerAdapter.POSITION_NONE);
}
for (int i = position + 1; i < pages.size(); i++) {
pageFragment = pages.get(i);
tag = pageFragment.getArguments().getString(MainActivity.FRAGMENT_TAG_ARG);
fragment = fragmentManager.findFragmentByTag(tag);
if (fragment != null) {
fragmentsPosition.put(fragment, i - 1);
}
}
pages.remove(position);
notifyDataSetChanged();
}
}
MainActivity :
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
public static final String FRAGMENT_TAG_ARG = "tag";
private CustomPagerAdapter mCustomPagerAdapter;
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCustomPagerAdapter = new CustomPagerAdapter(getSupportFragmentManager());
mCustomPagerAdapter.addPage(MainFragment.newInstance("Main_Title"));
mCustomPagerAdapter.addPage(SecondaryFragment.newInstance("Secondary_Title"));
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mCustomPagerAdapter);
}
}
페이지를 제거하려면 :
mCustomPagerAdapter.removePage(1);
MainFragment :
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainFragment extends Fragment {
public static final String FRAGMENT_TAG = "MainFragment";
public static MainFragment newInstance(String text) {
return newInstance(text, FRAGMENT_TAG);
}
public static MainFragment newInstance(String text, String tag) {
MainFragment fragment = new MainFragment();
Bundle args = new Bundle();
args.putString("text", text);
args.putString(MainActivity.FRAGMENT_TAG_ARG, tag + "_" + fragment.hashCode());
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getArguments().getString("text"));
return rootView;
}
}
SecondaryFragment 에는 동일한 코드가 있습니다.
The layouts are simple ViewPager/Fragment layouts with android.support.v4.view.ViewPager
with id container
and Fragment TextView
with id section_label
.
Resources:
- dynamically add and remove view to viewpager
- How to Remove Fragment from FragmentPagerAdapter?
- https://github.com/takaaki7/ArrayPagerAdapter
- https://github.com/commonsguy/cwac-pager
ReferenceURL : https://stackoverflow.com/questions/8060904/add-delete-pages-to-viewpager-dynamically
'code' 카테고리의 다른 글
'\ 0'은 거짓,“\ 0”은 참 (0) | 2021.01.05 |
---|---|
C #에서 double을 가장 잘 나타내는 SQL Server 데이터 형식은 무엇입니까? (0) | 2021.01.05 |
"식 SFINAE"는 무엇입니까? (0) | 2020.12.31 |
어떤 Boost 라이브러리가 헤더 전용입니까? (0) | 2020.12.31 |
Constexpr 수학 함수 (0) | 2020.12.31 |