문제

내가 찾은 코드를 사용하고 있습니다. 여기.

public class ActionBarTabs extends SherlockFragmentActivity {
CustomViewPager mViewPager;
TabsAdapter mTabsAdapter;
TextView tabCenter;
TextView tabText;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    mViewPager = new CustomViewPager(this);
    mViewPager.setId(R.id.pager);

    setContentView(mViewPager);
    ActionBar bar = getSupportActionBar();
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

    mTabsAdapter = new TabsAdapter(this, mViewPager);

    mTabsAdapter.addTab(bar.newTab().setText("Home"),
            ToolKitFragment.class, null);
    mTabsAdapter.addTab(bar.newTab().setText("FujiSan"),
            FujiFragment.class, null);
}

public static class TabsAdapter extends FragmentPagerAdapter implements
        ActionBar.TabListener, ViewPager.OnPageChangeListener {
    private final Context mContext;
    private final ActionBar mActionBar;
    private final ViewPager mViewPager;
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

    static final class TabInfo {
        private final Class<?> clss;
        private final Bundle args;

        TabInfo(Class<?> _class, Bundle _args) {
            clss = _class;
            args = _args;
        }
    }

    public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
        super(activity.getSupportFragmentManager());
        mContext = activity;
        mActionBar = activity.getSupportActionBar();
        mViewPager = pager;
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    }

    public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
        TabInfo info = new TabInfo(clss, args);
        tab.setTag(info);
        tab.setTabListener(this);
        mTabs.add(info);
        mActionBar.addTab(tab);
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return mTabs.size();
    }

    @Override
    public Fragment getItem(int position) {
        TabInfo info = mTabs.get(position);
        return Fragment.instantiate(mContext, info.clss.getName(),
                info.args);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset,
            int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        mActionBar.setSelectedNavigationItem(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        Object tag = tab.getTag();
        for (int i = 0; i < mTabs.size(); i++) {
            if (mTabs.get(i) == tag) {
                mViewPager.setCurrentItem(i);
            }
        }
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }
}
}

탭을 동적으로 삭제할 수 있도록 수정하려고 합니다.나는 간단히 이 함수를 만들어 보았습니다.

    public void removeTab(ActionBar.Tab tab) {
        mTabs.remove(tab);
        mActionBar.removeTab(tab);
        notifyDataSetChanged();
    }

하지만 항상 indexoutofboundsException이 발생합니다.누구든지 이 작업을 수행하는 좋은 방법을 알고 있습니까?

편집하다

내 방법을 다음으로 변경하여:

    public void removeTab(ActionBar.Tab tab) {
        mTabs.remove(tab.getTag());
        mActionBar.removeTab(tab);
        notifyDataSetChanged();
    }

탭을 성공적으로 제거할 수 있었습니다.그러나 맨 오른쪽에 있는 탭이 아닌 탭을 삭제하면 해당 탭과 연결된 보기(또는 조각?)가 사라지지 않습니다.대신, 다음으로 높은 탭과 연결되는 것 같습니다.예를 들어 탭 0을 삭제하면 탭 0의 보기가 탭 1로 이동합니다.ID가 가장 높은 탭을 삭제하면 탭과 보기가 올바르게 사라지지만 새 탭을 추가하면 다시 돌아옵니다.

마치 탭과 연결된 어딘가에 조각 목록이 있고 탭을 삭제해도 조각이 삭제되지 않는 것과 같습니다.이 문제의 원인이 무엇인지 아는 사람이 있나요?

편집2

다음을 사용하여 조각을 삭제하려고했습니다.

            Fragment fragmentToRemove = getItem(tab.getPosition());
            destroyItem(mViewPager, tab.getPosition(), fragmentToRemove);

그리고 또한

        Fragment fragmentToRemove = getItem(tab.getPosition());
        FragmentTransaction fragmentTransaction = mActivity
                .getSupportFragmentManager().beginTransaction();
        fragmentTransaction.remove(fragmentToRemove);
        fragmentTransaction.commit();

그러나 둘 다 지금까지 효과가 없었습니다.

도움이 되었습니까?

해결책

알았습니다!

public void removeTab(ActionBar.Tab tab) {
    mTabs.remove(tab.getTag());
    mActionBar.removeTab(tab);
    notifyDataSetChanged();
}
.

및 override destroyeM

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        // TODO Auto-generated method stub
        super.destroyItem(container, position, object);
        FragmentManager manager = ((Fragment) object).getFragmentManager();
        FragmentTransaction trans = manager.beginTransaction();
        trans.remove((Fragment) object);
        trans.commit();
    }
.

완벽하게 작동합니다 !!!

다른 팁

탭 삽입 또는 제거를 지원하는 실제 비결은 탭을 재정의하는 것임을 오늘 방금 발견했습니다. FragmentPagerAdapter.getItemPosition():

@Override
public int getItemPosition(Object object) {
    Fragment fragment = (Fragment) object;
    for (int i = 0; i < tabInfos.size(); i++) {
        if (tabInfos.get(i).clss == fragment.getClass()) {
            return i;
        }
    }
    // The tab must have been removed
    return POSITION_NONE;
}

getItemPosition() 에 의해 호출됩니다 ViewPager 당신이 전화한 후에 notifyDataSetChanged() (탭 추가/제거 후)그만큼 ViewPager 이 어댑터와 캐시를 다시 동기화하려고 합니다.그것은 전화한다 getItemPosition() 각 '객체'(조각)에 대해 보유하고 있으며 조각이 어떤 위치에 있는지 알려줍니다.일치하는 항목이 없으면 해당 탭을 삭제했기 때문에 반환하세요. POSITION_NONE.

또한 재정의하는 것이 중요하다는 것을 알았습니다. FragmentPagerAdapter.getItemId() 탭을 삽입하거나 제거하면 조각의 위치가 왼쪽과 오른쪽으로 이동하기 때문입니다.이 메소드는 다음에 의해 호출됩니다. FragmentPagerAdapter.instantiateItem() 항목의 이름(문자열)에 추가됩니다.이 이름을 사용하여 일치하는 이름(있는 경우)이 있는 기존 조각을 조회하고 그렇지 않으면 새 조각을 인스턴스화합니다.다음은 몇 가지 코드입니다.

@Override
public long getItemId(int position) {
    TabInfo info = tabInfos.get(position);
    // The default hashCode() implementation is based on memory address, which will be unique
    int hash = info.clss.hashCode();
    return hash;
}

확인 -이 하나는 2 주 동안 점심을 먹었습니다.나는 위의 것들이 보여주었습니다.중요한 경우 Android Studio 3.5.1을 사용하고 있습니다.

다음은 그 전체가 내 FragmentPagerAdapter 코드입니다.그것은 당신이 필요로하는 대부분의 모든 것을 포함합니다.조각 코드는 각각의 조각이 포함되어 있지 않도록 상당히 간단합니다.그러나 더 많은 것이 필요한지 또는 질문이 있으시면 알려주십시오.

또한 의견이 있거나 오류를 찾으면 주석을 게시하십시오.나는 이것이 다른 사람들을 돕기를 바랍니다.

import android.content.Context;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.tabs.TabLayout;

import java.util.ArrayList;

public class ChecklistPagerAdapter extends FragmentPagerAdapter {

    private final Context mContext;
    private int currentTabPosition = -1;
    ArrayList<String> tabNames = new ArrayList<>();
    ArrayList<Fragment> fragments = new ArrayList<>();

    public ChecklistPagerAdapter(Context context, FragmentManager fm) {
        super(fm);
        mContext = context;
    }

    public void add(Fragment fragment, String title) {
        tabNames.add(title);
        fragments.add(fragment);
    }

    public int getCurrentTabPosition() {
        return currentTabPosition;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getItemPosition(@NonNull Object object) {
        ChecklistFragment fragment = (ChecklistFragment) object;
        for (int i = 0; i < fragments.size(); i++) {
            if (fragments.get(i).equals(fragment)) {
                return i;
            }
        }
        return POSITION_NONE;
    }

    @Override
    public long getItemId(int position) {
        return fragments.get(position).hashCode();
    }

    @Override
    public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        super.setPrimaryItem(container, position, object);
        currentTabPosition = position;
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return tabNames.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }

    public void removeTab(TabLayout tabLayout, ViewPager viewPager, DBHelper dbHelper) {
        // Get current tab position as it changes below
        int position = currentTabPosition;

        // Get current fragment representing curTab
        ChecklistFragment fragment = (ChecklistFragment) fragments.get(position);

        // Remove Tab
        tabLayout.removeTabAt(position);

        // Remove from ArrayLists
        fragments.remove(position);
        tabNames.remove(position);

        // Remove fragment
        FragmentManager fragmentManager = fragment.getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.remove(fragment);
        fragmentTransaction.commit();

        // Refresh
        tabLayout.invalidate();
        notifyDataSetChanged();

        // Remove all records from ChecklistTab table
        dbHelper.clearChecklistTab(fragment.getOutingId(), fragment.getChecklistId());
    }
}
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top