1. 程式人生 > >Activity+Fragment基本框架(主要解決重啟後,出現重疊的問題)

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>