Activity+Fragment基本框架(主要解决重启后,出现重叠的问题)

之前写过,这里记载一个完整的

MainActivity

package com.example.apple.quickdemo.activity;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.example.apple.quickdemo.R;
import com.example.apple.quickdemo.fragment.Fragment1;
import com.example.apple.quickdemo.fragment.Fragment2;
import com.example.apple.quickdemo.fragment.Fragment3;
import com.example.apple.quickdemo.fragment.Fragment4;
import com.example.apple.quickdemo.fragment.FragmentFactory;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

import static com.example.apple.quickdemo.fragment.FragmentFactory.F1;

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.tv_bottom_nav_1)
    TextView tvBottomNav1;
    @BindView(R.id.tv_bottom_nav_2)
    TextView tvBottomNav2;
    @BindView(R.id.tv_bottom_nav_3)
    TextView tvBottomNav3;
    @BindView(R.id.tv_bottom_nav_4)
    TextView tvBottomNav4;
    private FragmentManager mFragmentManager;
    private Fragment mFragment1;
    private Fragment mFragment2;
    private Fragment mFragment3;
    private Fragment mFragment4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        mFragmentManager = getSupportFragmentManager();

        preventOverlap(savedInstanceState);
    }

    /**
     * 防止Fragment重叠的问题,切换横竖屏或者内存不够,重走了Activity的生命周期
     * 第一次要createFragment
     * 重启以后,要通过tag来找到对应的Fragment
     *
     * 重启的标准是savedInstanceState是否为null
     * 因为重启之前savedInstanceState=null
     * 重启之后savedInstanceState!=null
     *
     * @param savedInstanceState
     */
    private void preventOverlap(Bundle savedInstanceState) {
//        如果savedInstanceState为空,证明没有发生重走Activity的生命周期的情况,这时候要创建createFragment
        if (savedInstanceState == null) {
            mFragment1 = FragmentFactory.createFragment(F1);
            selectFragment(mFragment1);
            Log.e("ccc","savedInstanceState is  null");
        } else {
            Log.e("ccc","savedInstanceState is not null");

//            使用mFragmentManager通过Tag来取得,只要他add过,就给他添加了Tag
//            否则直接重写创建一个Fragment的话,会导致重叠
            mFragment1 = mFragmentManager.findFragmentByTag(Fragment1.class.getName());


            mFragment2 = mFragmentManager.findFragmentByTag(Fragment2.class.getName());


            mFragment3 = mFragmentManager.findFragmentByTag(Fragment3.class.getName());


            mFragment4 = mFragmentManager.findFragmentByTag(Fragment4.class.getName());

//=======================以下代码,不要系统也会自动识别,上次死亡位置,但是除了死亡位置,savedInstanceState还可以传递其他数据============
//            获得上次死亡重启的位置
            position = savedInstanceState.getInt("position");
            Log.e("cccccc",position+"=======");
            switch (position) {
                case 1:
                    selectFragment(mFragment1);
                    break;

                case 2:
                    selectFragment(mFragment2);
                    break;

                case 3:
                    selectFragment(mFragment3);
                    break;
                case 4:
                    selectFragment(mFragment4);
                    break;
            }
//===================以上代码需要配合onSaveInstanceState()方法里面记录数据================

        }
    }

    @OnClick({R.id.tv_bottom_nav_1, R.id.tv_bottom_nav_2, R.id.tv_bottom_nav_3, R.id.tv_bottom_nav_4})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.tv_bottom_nav_1:
                if (mFragment1 == null) {
                    mFragment1 = FragmentFactory.createFragment(F1);
                }
                selectFragment(mFragment1);
                position=1;
                break;
            case R.id.tv_bottom_nav_2:
                if (mFragment2 == null) {
                    mFragment2 = FragmentFactory.createFragment(FragmentFactory.F2);
                }
                selectFragment(mFragment2);
                position=2;

                break;
            case R.id.tv_bottom_nav_3:
                if (mFragment3 == null) {
                    mFragment3 = FragmentFactory.createFragment(FragmentFactory.F3);
                }
                selectFragment(mFragment3);
                position=3;

                break;
            case R.id.tv_bottom_nav_4:
                if (mFragment4 == null) {
                    mFragment4 = FragmentFactory.createFragment(FragmentFactory.F4);
                }
                selectFragment(mFragment4);
                position=4;

                break;
        }
    }

    /**
     * 选择显示某一个Fragment
     * @param fragment
     */
    private void selectFragment(Fragment fragment) {
        FragmentTransaction transaction = mFragmentManager.beginTransaction();
        hideAll(transaction);

        if (!fragment.isAdded()) {
            transaction.add(R.id.fl_content, fragment, fragment.getClass().getName());//tag
//            transaction.addToBackStack(null);//加入回退栈

        }

        transaction.show(fragment).commit();

    }


    private void hideAll(FragmentTransaction transaction) {
        if (mFragment1 != null) {
//            必须使用同一个transaction,跟add/show时候一样
//            同一个事物进行了所有的add/hide/show,之后统一commit就行了
//            中间不能commit事物,因为一个事物只能是提交一次,重复提交会报错
//            即:每一次点击,生成一个事务,操作完后,提交这个事务
            transaction.hide(mFragment1);
        }

        if (mFragment2 != null) {
            transaction.hide(mFragment2);
        }

        if (mFragment3 != null) {
            transaction.hide(mFragment3);
        }

        if (mFragment4 != null) {
            transaction.hide(mFragment4);
        }
    }

    //记录Fragment的位置
    private int position ;


    /**
     * 这个方法会在activity重启前调用,用来保存一些数据
     * @param outState
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        //记录当前的position
        outState.putInt("position", position);
        Log.e("Ccc", position + "dfssf");
//        ★★★★★★★★别忘了下下面的super.onSave,否则会报错
        super.onSaveInstanceState(outState);
    }
}

BaseFragment

package com.example.apple.quickdemo.base;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * Created by apple on 2017/7/3.
 */

public abstract  class BaseFragment extends Fragment {
    Unbinder unbinder;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(provieResourceID(), container, false);
        unbinder = ButterKnife.bind(this, view);
        init();
        return view;
    }

    protected abstract void init();


    protected abstract int provieResourceID();
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }
}

Fragment1

package com.example.apple.quickdemo.fragment;

import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import com.example.apple.quickdemo.R;
import com.example.apple.quickdemo.base.BaseFragment;

import butterknife.BindView;

/**
 * Created by apple on 2017/7/3.
 */

public class Fragment1 extends BaseFragment {
    @BindView(R.id.textView)
    TextView tv;


    private static final String ARG = "arg";

    public Fragment1() {
        Log.i("INFO", "TestFragment non-parameter constructor");
    }
    public static Fragment1 newInstance(String arg) {
        Bundle bundle = new Bundle();
        bundle.putString(ARG, arg);

        Fragment1 fragment = new Fragment1();
        fragment.setArguments(bundle);

        return fragment;
    }
    @Override
    protected int provieResourceID() {
        return R.layout.fragment1;
   }

    @Override
    protected void init() {
        tv.setText(getArguments().getString(ARG));
    }
}

FragmentFactory

package com.example.apple.quickdemo.fragment;

import android.support.v4.app.Fragment;

import java.util.HashMap;

/**
 * Created by a on 2017/4/5.
 */
public class FragmentFactory {
    public final static int F1 = 1;
    public final static int F2 = 2;
    public final static int F3 = 3;
    public final static int F4 = 4;

    private static HashMap<Integer, Fragment> mFragments = new HashMap<>();


    public static Fragment createFragment(int fragmentName) {
        // 从缓存中取出
        Fragment fragment = mFragments.get(fragmentName);
        if (fragment == null) {
            switch (fragmentName) {

                case F1:
                     fragment = Fragment1.newInstance("100");
                    break;

                case F2:
                    fragment = Fragment2.newInstance("200");
                    break;

                case F3:
                    fragment = Fragment3.newInstance("300");
                    break;

                case F4:
                    fragment = Fragment4.newInstance("400");
                    break;
            }
            // 把frament加入到缓存中
            mFragments.put(fragmentName,fragment);
        }

        return fragment;
    }
}

activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.apple.quickdemo.activity.MainActivity">

    <FrameLayout
        android:id="@+id/fl_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/ll_bottom_navigation"
        android:background="@color/colorAccent">
    </FrameLayout>

    <android.support.v7.widget.LinearLayoutCompat
        android:id="@+id/ll_bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:background="@color/white_bg"
        android:orientation="horizontal"
        app:divider="@drawable/divider_line"
        app:dividerPadding="3dp"
        app:showDividers="middle">

        <TextView
            android:id="@+id/tv_bottom_nav_1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="导航一"
            />


        <TextView
            android:id="@+id/tv_bottom_nav_2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="导航二"/>


        <TextView
            android:id="@+id/tv_bottom_nav_3"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="导航三"/>

        <TextView
            android:id="@+id/tv_bottom_nav_4"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="导航四"/>

    </android.support.v7.widget.LinearLayoutCompat>
</RelativeLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值