美文网首页安卓Fragment
最佳实践探索之Fragment实现不可滑动的主页卡

最佳实践探索之Fragment实现不可滑动的主页卡

作者: 小鱼爱记录 | 来源:发表于2017-03-13 17:49 被阅读242次

在我自己做的几个app中,几乎每个主页都是长这样。对于可以滑动的主页,可以用ViewPager+Fragment来实现。对于不可滑动的,可以用FrameLayout+Fragment实现,这里又分两种情况,用replace来实现,则会频繁的创建和销毁Fragment,效率有点低;但是用hide/show来实现时,又会碰到状态保存和视图重叠的问题。怎样才算是最好的实践呢?

这里呢,我还是使用hide/show来实现Fragment的切换的,不过,这里做了一下当内存重启时Fragment状态的缓存,同时,又给每一个Fragment都设置了tag来防止重叠。

/**
 * 主页卡基类-不可滑动
 * <p>
 * 作者:余天然 on 2017/3/13 下午4:09
 */
public abstract class TabActivity extends AppCompatActivity {

    private static String CUR_TAB = "CUR_TAB";
    private int curTab;//当前的tab的位置
    private int tabNum;//tab的个数

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putInt(CUR_TAB, curTab);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getContentViewId());
        if (savedInstanceState != null) {
            curTab = savedInstanceState.getInt(CUR_TAB, 0);
        }
        tabNum = getFragmentSize();
        initButton();
        switchTab(curTab);
    }

    protected abstract void initButton();

    protected void switchTab(int pos) {
        switchButton(pos);
        switchFragment(pos);
        curTab = pos;
    }

    protected abstract void switchButton(int pos);

    private void switchFragment(int index) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        for (int i = 0; i < tabNum; i++) {
            Fragment fragment = getFragmentWithCache(i);
            if (i == index) {
                if (fragment.isAdded()) {
                    transaction = transaction.show(fragment);
                } else {
                    transaction = transaction.add(getFragmentViewId(), fragment, String.valueOf(i));
                }
            } else {
                if (fragment.isAdded()) {
                    transaction = transaction.hide(fragment);
                }
            }
        }
        transaction.commit();
    }

    private Fragment getFragmentWithCache(int pos) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment fragment = fragmentManager.findFragmentByTag(String.valueOf(pos));
        return fragment == null ? getFragment(pos) : fragment;
    }

    protected abstract int getContentViewId();

    protected abstract int getFragmentViewId();

    protected abstract int getFragmentSize();

    protected abstract Fragment getFragment(int pos);

}

这样,当我们要使用时,就无需再关注Fragment之间切换和状态保存的具体逻辑了,只需要继承TabActivity即可:

public class MainActivity extends TabActivity {

    private TextView[] tabs;

    @Override
    protected int getContentViewId() {
        return R.layout.activity_main;
    }

    @Override
    protected int getFragmentViewId() {
        return R.id.fr_fragment;
    }

    @Override
    protected int getFragmentSize() {
        return 4;
    }

    @Override
    protected Fragment getFragment(int pos) {
        switch (pos) {
            case 0:
                return new HomeFragment();
            case 1:
                return new ChatFragment();
            case 2:
                return new FindFragment();
            case 3:
                return new MineFragment();
        }
        return null;
    }

    @Override
    protected void initButton() {
        TextView tvHome = (TextView) findViewById(R.id.tv_home);
        TextView tvChat = (TextView) findViewById(R.id.tv_chat);
        TextView tvFind = (TextView) findViewById(R.id.tv_find);
        TextView tvMine = (TextView) findViewById(R.id.tv_mine);
        tabs = new TextView[]{tvHome, tvChat, tvFind, tvMine};

        for (int i = 0; i < tabs.length; i++) {
            final int finalI = i;
            tabs[i].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    switchTab(finalI);
                }
            });
        }
    }

    @Override
    protected void switchButton(int pos) {
        for (int i = 0; i < tabs.length; i++) {
            if (i == pos) {
                tabs[i].setSelected(true);
            } else {
                tabs[i].setSelected(false);
            }
        }
    }

}

简单测试了一下,当手机开启“不保留活动”时,状态保存正常,并且没有出现重叠的问题。

最后,奉上Github地址:Best-Fragment

相关文章

网友评论

    本文标题:最佳实践探索之Fragment实现不可滑动的主页卡

    本文链接:https://www.haomeiwen.com/subject/uycqnttx.html