1

我遇到了片段的内存问题,我可以使用一些帮助来确定适当的路径。我不能使用简单的 backstack,因为应用程序需要保留用户在应用程序中采用的多个路径(并且用户可以来回跳转)。导航以这种方式处理片段:

transaction.hide(currentFragment).show(newFragment).commit();

我认为对我的情况有帮助的是暂时销毁片段的视图,然后在将片段放回视图时重新创建(而不是简单地从用户的视图中隐藏 UI)。从阅读 API 来看,这听起来不像是 hide 方法。有谁知道 FragmentTransaction/FragmentManager/Fragment 类是否有一些内置方法可以让我这样做?

我正在考虑的另一个选择是为每个片段创建自己的生命周期。我也探索过使用 tabhost,但它似乎不会解决内存问题。如果您有其他想法,我愿意接受。

谢谢大家,我很感激你的帮助。

4

1 回答 1

0

我想出了一个解决方案来实现更好的内存管理解决方案(基于适配器),以便同时保存多个用户旅程(带有代表 backstacks 的东西的独立选项卡)。我放弃了使用 FragmentManager,因为它不利于这种行为。我会在这里留下我的答案,以防其他人遇到类似的问题,即需要使用带有 FragmentStatePagerAdapter 的 ViewPagers 的多个 backstacks 的这种想法——他们的应用程序中的每个选项卡都有一个 viewpager(这仍然可以清理更多,但你可以得到 jist) :

主要活动:

public class MultiTabbedActivity extends FragmentActivity implements NavigationFragment.OnNavigationSelectedListener
{

    private Page1Fragment mPage1;
    private Page2Fragment mPage2;


    private CustomFragment mCurrent;
    private String mNav;

    private List<CustomFragment> mPage1BackStack;
    private List<CustomFragment> mPage2BackStack;

    private CustomViewPager mPagerPage1;
    private CustomViewPager mPagerPage2;

    private boolean mUpdating = false;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        // initialize the backstacks
        mPage1BackStack = new ArrayList<CustomFragment>();
        mPage2BackStack = new ArrayList<CustomFragment>();

        mPage1 = new Page1Fragment();
        mPage2 = new Page2Fragment();

        mPage1BackStack.add(mPage1);
        mPage2BackStack.add(mPage2);

        mPagerPage1 = (CustomViewPager) findViewById(R.id.page1_fragment);
        mPagerPage2 = (CustomViewPager) findViewById(R.id.page2_fragment);

        mPagerPage1.setOffscreenPageLimit(3); //Customizable to determine how many 
        mPagerPage2.setOffscreenPageLimit(3); //fragments you want to hold in memory

        mPagerPage1.setAdapter(new CustomFragmentAdapter(getSupportFragmentManager(), mPage1BackStack));
        mPagerPage2.setAdapter(new CustomFragmentAdapter(getSupportFragmentManager(), mPage2BackStack));

        displayPager(mPagerPage1);
        mCurrent = mPage1;
        mNav = GlobalConstants.PAGE_PAGE1;

    }

    private void displayPager(ViewPager pager)
    {
        mPagerPage1.setVisibility(ViewPager.GONE);
        mPagerPage2.setVisibility(ViewPager.GONE);

        pager.setCurrentItem(pager.getAdapter().getCount() - 1);
        pager.getAdapter().notifyDataSetChanged();
        pager.setVisibility(ViewPager.VISIBLE);
    }

    @Override
    public void onNavSelected(String page)
    {
        if (page != null && page != "" && !mUpdating)
        {
            // Determine the Fragment selected
            if (page.equalsIgnoreCase(GlobalConstants.PAGE_PAGE1))
            {
                mNav = GlobalConstants.PAGE_PAGE1;
                displayPager(mPagerPage1);
                mCurrent = mPage1BackStack.get(mPage1BackStack.size() - 1);
            }
            else if (page.equalsIgnoreCase(GlobalConstants.PAGE_PAGE2))
            {
                mNav = GlobalConstants.PAGE_PAGE2;
                displayPager(mPagerPage2);
                mCurrent = mPage2BackStack.get(mPage2BackStack.size() - 1);
            }
        }
    }


    @Override
    public void onBackPressed()
    {
        PageFragment navFrag = null;
        // Update the Navigation Menu to indicate the currently visible
        // Fragment
        try
        {
            mUpdating = true;

            if (mPage1BackStack.size() > 1 && mNav.equalsIgnoreCase(GlobalConstants.PAGE_PAGE1))
            {
                mPagerPage1.setCurrentItem(mPage1BackStack.size() - 2);
                mPage1BackStack.remove(mPage1BackStack.size() - 1);
                navFrag = mPage1BackStack.get(mPage1BackStack.size() - 1);
                mPagerPage1.setAdapter(new CustomFragmentAdapter(getSupportFragmentManager(), mPage1BackStack));
            }
            else if (mPage2BackStack.size() > 1 && mNav.equalsIgnoreCase(GlobalConstants.PAGE_PAGE2))
            {
                mPagerPage2.setCurrentItem(mPage2BackStack.size() - 2);
                mPage2BackStack.remove(mPage2BackStack.size() - 1);
                navFrag = mPage2BackStack.get(mPage2BackStack.size() - 1);
                mPagerPage2.setAdapter(new CustomFragmentAdapter(getSupportFragmentManager(), mPage2BackStack));
            }
            else
            {
                super.onBackPressed();
            }

            if (navFrag != null)
                mCurrent = navFrag;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            mUpdating = false;
        }
    }

    public void updateFragment(PageFragment newFragment)
    {
        if (mNav.equalsIgnoreCase(GlobalConstants.PAGE_PAGE1))
        {
            mPage1BackStack.add(newFragment);
            displayPager(mPagerPage1);
        }
        else if (mNav.equalsIgnoreCase(GlobalConstants.PAGE_PAGE2))
        {
            mPage2BackStack.add(newFragment);
            displayPager(mPagerPage2);
        }
        mCurrent = newFragment;
    }
}

自定义视图页面:

public class CustomViewPager extends ViewPager {

    private boolean enabled;

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onTouchEvent(event);
        }

        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onInterceptTouchEvent(event);
        }

        return false;
    }

    public void setPagingEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}

自定义适配器:

public class CustomFragmentAdapter extends FragmentStatePagerAdapter
{
    List<CustomFragment> mFragments;

    public CustomFragmentAdapter(FragmentManager fm, List<CustomFragment> fragments)
    {
        super(fm);
        mFragments = fragments;
    }

    public List<PageFragment> getmFragments()
    {
        return mFragments;
    }

    public void setmFragments(List<CustomFragment> mFragments)
    {
        this.mFragments = mFragments;
    }

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

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

UI(包裹在线性布局中):

    <fragment
        android:id="@+id/navigation_fragment"
        android:name="your.package.here.NavigationFragment"
        android:layout_width="70dp"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@+id/page_fragment"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="2" >

        <your.package.here.CustomViewPager
            android:id="@+id/page1_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />
        <your.package.here.CustomViewPager
            android:id="@+id/page2_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />
    </FrameLayout>
于 2013-09-11T14:37:51.150 回答