利用Factory模式实现Fragment切换优化

3 篇文章 0 订阅
2 篇文章 0 订阅

GIithub源码
准备用 Fragment 实现页面切换的效果,就去 Github 看了下别人的源码,发现他利用 Factory 模式进行了优化。下面我就把这种方法介绍给大家。

这里写图片描述

开始

下面我们就用边学边练的方式进行学习,首先打开你的 Android Studio,并新建一个 FactoryFragment 项目。

创建三个 fragment,分别是 OneFragment,TwoFragment,ThreeFragment,代码如下所示:

public class OneFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_one, container, false);
        ButterKnife.bind(this, view);
        return view;
    }
}
public class ThreeFragment extends Fragment{

    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_three, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

}
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_two, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

上面的代码引入三个 fragment 布局,当我们点击相应的按钮时,会出现指定的布局, 布局文件就不再这里粘贴了,可以去上面的 Github 下载源码。

工厂类

创建工厂类 FragmentFactory,这也是我们的重点。代码如下:

public class FragmentFactory {
    public static final String ONE_TAG = "one";
    public static final String TWO_TAG = "two";
    public static final String THREE_TAG = "three";

    private OneFragment oneFragment;
    private TwoFragment twoFragment;
    private ThreeFragment threeFragment;


    private static FragmentFactory mFactory;
    private HashMap<String, Fragment> mHashMap = new HashMap<>();

    private FragmentFactory() {

    }

    public static FragmentFactory getInstance() {
        if (mFactory == null) {
            synchronized (FragmentFactory.class) {
                if (mFactory == null) {
                    mFactory = new FragmentFactory();
                }
            }
        }
        return mFactory;
    }

    public Fragment getFragmentByTag(String tag) {
        if (tag.equals(ONE_TAG) && oneFragment == null) {
            oneFragment = new OneFragment();
            mHashMap.put(ONE_TAG, oneFragment);
        }
        if (tag.equals(TWO_TAG) && twoFragment == null) {
            twoFragment = new TwoFragment();
            mHashMap.put(TWO_TAG, twoFragment);
        }

        if (tag.equals(THREE_TAG) && threeFragment == null) {
            threeFragment = new ThreeFragment();
            mHashMap.put(THREE_TAG, threeFragment);
        }
        return mHashMap.get(tag);
    }

可以看到,我们定义了三个标记,用来判断我们点击的 fragment ,后面的代码会做详细介绍。

接着用 getInstance() 获得工厂类实例, 在这个方法里面,使用 synchronized 关键字,避免点击多次,多次创建实例,浪费资源。

获取工厂实例后,就要调用工厂类,帮我们获取每个 fragment 实例。接下来我们创建 getFragmentByTag () 方法, 用我们上面定义的标记来判断我们点击的哪个 fragment,并判断该 fragment 是否实例化,避免浪费资源。然后添加到 mHashMap 中。

最后通过 mHashMap.get() 获取点击的 fragment 实例并返回。

实现Frament切换

修改 MainActivity 中的代码,如下所示:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    @BindView(R.id.one)
    RadioButton one;
    @BindView(R.id.two)
    RadioButton two;
    @BindView(R.id.three)
    RadioButton three;

    private FragmentFactory mFactory;
    private String mCurrentTag;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);

        mFactory = FragmentFactory.getInstance();
        one.setOnClickListener(this);
        two.setOnClickListener(this);
        three.setOnClickListener(this);

        initFragment(FragmentFactory.ONE_TAG);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.one:
                initFragment(FragmentFactory.ONE_TAG);
                break;
            case R.id.two:
                initFragment(FragmentFactory.TWO_TAG);
                break;
            case R.id.three:
                initFragment(FragmentFactory.THREE_TAG);
                break;
        }

    }

    private void initFragment(String tag) {
        Fragment baseFragment = mFactory.getFragmentByTag(tag);
        if (baseFragment == null) {
            throw new IllegalAccessError("tag is error!");
        }
        if (tag.equals(mCurrentTag)) {
            return;
        } else {

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            if (!TextUtils.isEmpty(mCurrentTag)) {
                transaction.hide(mFactory.getFragmentByTag(mCurrentTag));
            }
            if (!baseFragment.isAdded()) {
                transaction.add(R.id.fragment_tab, baseFragment);
            } else {
                transaction.show(baseFragment);
            }
            transaction.commitAllowingStateLoss();
        }
        mCurrentTag = tag;
    }
}

首先对三个按钮创建点击事件,点击不同的按钮,显示相应的fragment,比较简单。

接下来就重点介绍下 initFragment() 方法 ,首先调用工厂类获取相应的 fragment 实例,然后创建 fragment 容器。
后面跟着 if 判断,当 mCurrentTag 不为空时, 隐藏这个 fragment (就当你点击第一次后,点击第二次的时候,就隐藏第一次的)。
当 baseFragment 没有在容器中时,transaction.add() 添加这个 fragment并显示。
当 baseFragment 在容器中时, transaction.show() 直接显示 这个 fragment.

最终程序效果在最上面,以及 Github 源码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值