使用 tablayout 切换片段时重新创建所有片段

all Fragment recreating when a switching through fragments using tablayout

我正在创建一个基于使用 tablayout 的选项卡的应用程序。我没有使用viewpager。我的逻辑是,用户可以创建片段(选项卡),例如在 chrome 中添加选项卡,以便每当用户单击添加按钮时,都会创建一个带有片段的新选项卡。现在我需要在共享首选项中保存每个片段创建时间的唯一时间戳,以便每当我移动到一个片段时,我都可以使用该共享参考时间戳值来执行用于该特定片段的独特功能。

但我不知道将时间戳保存在哪里。我试图在 Fragment 的 Oncreate 函数中获取以毫秒为单位的时间,但是每当我每次调用 onCreate 时在选项卡之间切换,这样每次我在选项卡之间切换时,共享偏好值都会随着我在 Fragments 的 onCreate 中添加它而改变。

我的逻辑是,它应该只在用户单击添加时创建片段后创建,并且必须能够在片段中使用它。

每次我切换到其他碎片时,它都会重新初始化所有视图并调用 onCreate。所以我无法在 oncreate 中设置时间戳..

请帮帮我

我的Activity代码是:

public class TabActivity extends AppCompatActivity{
    public static TabActivity instance;
    private FragmentChild fragmentOne;

    private TabLayout allTabs;
    ImageView add;
    ImageView imageButtonAdd2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tab_activity);

        getAllWidgets();
        bindWidgetsWithAnEvent();
        setupTabLayout();

    }
    public static TabActivity getInstance() {
        return instance;
    }
    private void getAllWidgets() {
        allTabs = (TabLayout) findViewById(R.id.simpleTabLayout);
        add = findViewById(R.id.addButton);
        imageButtonAdd2 = findViewById(R.id.imageButtonAdd2);
    }
    private void setupTabLayout() {
        allTabs.addTab(allTabs.newTab().setText("ONE"),true);
        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                allTabs.addTab(allTabs.newTab().setText("NEW_TAB"),true);
                bindWidgetsWithAnEvent();
            }
        });
        imageButtonAdd2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*Bundle bundle = new Bundle();
                bundle.putString("data", String.valueOf(0));
                fragmentSecond = new SecondFragment();
                fragmentSecond.setArguments(bundle);
                replaceFragment(fragmentSecond,"SecondFragment");*/
            }
        });
    }
    private void bindWidgetsWithAnEvent()
    {
        allTabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                setCurrentTabFragment(tab.getPosition());
            }
            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }
            @Override
            public void onTabReselected(TabLayout.Tab tab) {
            }
        });
    }
    private void setCurrentTabFragment(int tabPosition)
    {
        Bundle bundle = new Bundle();
        bundle.putString("data", String.valueOf(tabPosition));
        fragmentOne = new FragmentChild();
        fragmentOne.setArguments(bundle);
        replaceFragment(fragmentOne,"FirstFragment");
    }
    public void replaceFragment(Fragment fragment, String fragmentName) {
        long time= System.currentTimeMillis();
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.simpleFrameLayout, fragment,fragmentName);
        //ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();
    }
    public void backStackFragment(Fragment fragment, String fragmentName) {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.simpleFrameLayout, fragment,fragmentName);
        ft.addToBackStack(null);
        //ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();
    }
    @Override
    public void onBackPressed(){
        FragmentManager fm = getSupportFragmentManager();
        if (fm.getBackStackEntryCount() > 0) {
            Log.i("MainActivity", "popping backstack");
            fm.popBackStack();
        } else {
            Log.i("MainActivity", "nothing on backstack, calling super");
            super.onBackPressed();
        }
    }
} 

FragmentChild class:

public class FragmentChild extends Fragment {
    String childname;
    TextView textViewChildName;
    EditText editText;
    private GridView mGridView;
    private ListItem mListItem;
    private ListView mListview;
    private ProgressBar mProgressBar;
    private ProductViewAdapter mGridAdapter;
    private ListViewAdapter mListAdapter = null;
    private ArrayList<GridItem> mGridData;
    private ArrayList<ListItem> mListData = null;
    ListView listView;
    CheckInterNetConnection check ;
    Boolean isInternetPresent = false;
    PreferenceHelper prefs;
    private TabLayout tabLayout;
    private ViewPagerAdapter adapter;
    public static ViewPager viewPager;
    String posid = "";
    int page =0;
    String title  = "";
    TabLayout allTabs;
    int tab_position = 0;
    long time=0;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        //GlobalBus.getBus().register(this);
        View view = inflater.inflate(R.layout.fragment_child, container, false);
        Bundle bundle = getArguments();
        childname = bundle.getString("data");
        Log.e("onCreateView","onCreateView");
        getIDs(view);
        setEvents();
        return view;
    }


    // Store instance variables based on arguments passed
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
         time= System.currentTimeMillis();
        page = getArguments().getInt("someInt", 0);
        title = getArguments().getString("someTitle");
        Log.e("onCreate","onCreate");
    }
    private void getIDs(View view) {
        //textViewChildName = (TextView) view.findViewById(R.id.textViewChild);
        //textViewChildName.setText(childname);
        //editText = (EditText) view.findViewById(R.id.editText);
        //editText.setText("");
    }

    private void setEvents() {

    }
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Log.e("onViewCreated","onViewCreated");

    }
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        // Unregister the registered event.
        EventBus.getDefault().unregister(this);
    }
    public static FragmentChild newInstance(int page, String title) {
        FragmentChild fragmentFirst = new FragmentChild();
        Bundle args = new Bundle();
        args.putInt("someInt", page);
        args.putString("someTitle", title);
        fragmentFirst.setArguments(args);
        return fragmentFirst;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.e("onActivityCreated","onActivityCreated");
        allTabs = (TabLayout) getActivity().findViewById(R.id.simpleTabLayout);
        mGridView = (GridView) getView().findViewById(R.id.gridView);
        prefs = new PreferenceHelper(getActivity());
        mGridData = new ArrayList<>();
        mGridAdapter = new ProductViewAdapter(getActivity(), R.layout.grid_product_layout, mGridData);
        mGridView.setAdapter(mGridAdapter);

        mListview = (ListView) getView().findViewById(R.id.list);
        mListData = new ArrayList<>();
        mListAdapter = new ListViewAdapter(getActivity(), R.layout.list_row, mListData);
        mListview.setAdapter(mListAdapter);
        adapter = new ViewPagerAdapter(getFragmentManager(), getActivity(), viewPager, tabLayout);
    }
    @Override
    public void onStart() {
        super.onStart();
        Log.e("onStart","onStart");
        EventBus.getDefault().register(this);
        tab_position=allTabs.getSelectedTabPosition();
        //Log.e("TAB ID",String.valueOf(tab_position));
        prefs.save(String.valueOf(tab_position),"tab-"+time);
        check = new CheckInterNetConnection(getActivity());
        isInternetPresent = check.isConnectingToInternet();
        if (isInternetPresent) {
            fetchProducts(tab_position);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.e("onResume","onResume");
    }

    @Override
    public void onPause() {
        EventBus.getDefault().unregister(this);
        Log.e("onPause","onPause");
        super.onPause();
    }

    @Subscribe
    public void onEvent(GlobalBus event){
        posid = event.getMessage();
        //Toast.makeText(getActivity(), event.getMessage(), Toast.LENGTH_SHORT).show();
    }

    public void fetchProducts(int tabPosition){
        String tabid = prefs.getString(String.valueOf(tabPosition),"0");
        Fragment fragment = getFragmentManager().findFragmentById(R.id.simpleFrameLayout);
        String tag = (String) fragment.getTag();
        //Log.e("URL","http://35.184.41.163/phpmyadmin/app/demo/products.php?tabid="+tabid+"&tab_position="+tabPosition);
        RestClientHelper.getInstance().get("http://35.184.41.163/phpmyadmin/app/demo/products.php", new RestClientHelper.RestClientListener() {
            @Override
            public void onSuccess(String response) {
                parseResult(response);
                mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                        try {
                            ListItem items;
                            GridItem item = (GridItem) parent.getItemAtPosition(position);
                            items = new ListItem();
                            items.setName(item.getTitle());
                            items.setType(item.getDescription());
                            mListData.add(items);
                        }
                        catch(Exception e){

                        }
                        finally {
                            mListAdapter.setGridData(mListData);
                        }
                    }
                });
            }

            @Override
            public void onError(String error) {

            }
        });
    }

    private void parseResult(String result) {
        try {
            JSONObject response = new JSONObject(result);
            JSONArray posts = response.optJSONArray("products");
            GridItem item;
            if(posts.length() <= 0){
                RelativeLayout ly = (RelativeLayout) getView().findViewById(R.id.noOps);
                ly.setVisibility(View.VISIBLE);
            }
            else {
               // RelativeLayout ly = (RelativeLayout)  getView().findViewById(R.id.noOps);
                //ly.setVisibility(View.INVISIBLE);
                mGridData.clear();
                mGridAdapter.setGridData(mGridData);
                for (int i = 0; i < posts.length(); i++) {
                    JSONObject post = posts.optJSONObject(i);
                    String id = post.optString("id");
                    String title = post.optString("name");
                    String description = post.optString("description");
                    String image = post.optString("image");
                    String qty = post.optString("qty");
                    String quantityin = post.optString("quantityin");
                    String price = post.optString("price");

                    item = new GridItem();
                    item.setId(id);
                    item.setTitle(title);
                    item.setDescription(description);
                    item.setImage(image);
                    item.setQuantity(qty);
                    item.setQuantityIn(quantityin);
                    item.setUnitprice(price);
                    mGridData.add(item);
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        finally {
            mGridAdapter.setGridData(mGridData);
        }
    }
}

UPDATE 根据@Larry Hsiao

的建议
public class TabActivity extends AppCompatActivity{
    public static TabActivity instance;
    private FragmentChild fragmentOne;
    PreferenceHelper prefs;
    private TabLayout allTabs;
    ImageView add;
    ImageView imageButtonAdd2;
    private final List<Fragment> fragments = new ArrayList<>(); // maintain the instance for switching
    private int currentIndex = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tab_activity);
        prefs = new PreferenceHelper(TabActivity.this);
        getAllWidgets();
        //bindWidgetsWithAnEvent();
        setupTabLayout();
        bindWidgetsWithAnEvent();

    }
    public static TabActivity getInstance() {
        return instance;
    }
    private void getAllWidgets() {
        allTabs = (TabLayout) findViewById(R.id.simpleTabLayout);
        add = findViewById(R.id.addButton);
        add.performClick();
        imageButtonAdd2 = findViewById(R.id.imageButtonAdd2);
    }
    private void setupTabLayout() {
        int locfirst = allTabs.getSelectedTabPosition();
        locfirst = locfirst+1;
        allTabs.addTab(allTabs.newTab().setText("TAB"+locfirst),true);
        /*long time= System.currentTimeMillis();
        prefs.save("tab_"+locfirst,"tab_"+time);*/
        fragments.add(newFragment(0));
        addFragment(fragments.get(0));
        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int loc = allTabs.getSelectedTabPosition();
                loc = loc+1;
                allTabs.addTab(allTabs.newTab().setText("TAB"+loc),true);
                fragments.add(newFragment(loc));
                addFragment(fragments.get(loc));
                /*bindWidgetsWithAnEvent();
                long time= System.currentTimeMillis();
                prefs.save("tab_"+loc,"tab_"+time);*/
            }
        });
        imageButtonAdd2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*Bundle bundle = new Bundle();
                bundle.putString("data", String.valueOf(0));
                fragmentSecond = new SecondFragment();
                fragmentSecond.setArguments(bundle);
                replaceFragment(fragmentSecond,"SecondFragment");*/
            }
        });
    }

    private Fragment newFragment(int position) {
        Fragment fragment = new FragmentChild();
        Bundle bundle = new Bundle();
        bundle.putString("position", String.valueOf(position));
        fragment.setArguments(bundle);
        return fragment;
    }


    private void addFragment(Fragment fragment) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.simpleFrameLayout, fragment);
        transaction.commit();
    }

    private void changingTab(Fragment fragment) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.hide(fragments.get(currentIndex));
        if (manager.getFragments().contains(fragment)) {
            transaction.show(fragment);
        }else {
            transaction.add(R.id.simpleFrameLayout,fragment);
        }
        transaction.commit();
    }

    private void bindWidgetsWithAnEvent()
    {
        allTabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int nextPageIndex = (currentIndex + 1) % 2; // only two fragment switching
                changingTab(fragments.get(nextPageIndex));
                currentIndex = nextPageIndex;
                //setCurrentTabFragment(tab.getPosition());
            }
            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }
            @Override
            public void onTabReselected(TabLayout.Tab tab) {
            }
        });
    }
    \
    @Override
    public void onBackPressed(){
        FragmentManager fm = getSupportFragmentManager();
        if (fm.getBackStackEntryCount() > 0) {
            Log.i("MainActivity", "popping backstack");
            fm.popBackStack();
        } else {
            Log.i("MainActivity", "nothing on backstack, calling super");
            super.onBackPressed();
        }
    }
}

此强制关闭并出现此错误:

FATAL EXCEPTION: main
                                                                 Process: com.eazypos.app, PID: 13624
                                                                 java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
                                                                     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
                                                                     at java.util.ArrayList.get(ArrayList.java:308)
                                                                     at com.eazypos.app.TabActivity.onTabSelected(TabActivity.java:115)
                                                                     at android.support.design.widget.TabLayout.dispatchTabSelected(TabLayout.java:1165)
                                                                     at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1158)
                                                                     at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1128)
                                                                     at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1427)
                                                                     at android.support.design.widget.TabLayout.addTab(TabLayout.java:483)
                                                                     at android.support.design.widget.TabLayout.addTab(TabLayout.java:465)
                                                                     at com.eazypos.app.TabActivity.onClick(TabActivity.java:62)
                                                                     at android.view.View.performClick(View.java:4780)
                                                                     at android.view.View$PerformClick.run(View.java:19866)
                                                                     at android.os.Handler.handleCallback(Handler.java:739)
                                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                     at android.os.Looper.loop(Looper.java:135)

删除标签功能

public void removeTab(int position) {
        Toast.makeText(getActivity(), "REMOVING --> "+position, Toast.LENGTH_SHORT).show();
        prefs.remove("tab_"+position);
        if (allTabs.getChildCount() > 0) {
            allTabs.removeTabAt(position);

        }
    }

要仅保存一次值..在timeStamp中在shared prefs中只需在每个片段中使用它..

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (getActivity() == null)
    {

        // generate time stamp in miliseconds as you are doing 
        // and save it in shared prefs 
        // this will be called only once..
    }
}

或者你可以试试 :-

UPDATE onCreate 的 fragmentChild

   time= System.currentTimeMillis();
   SharedPreferences sharedPreferences = getActivity().getSharedPreferences("My_prefs_name",Context.MODE_PRIVATE);
        String timeStamp = sharedPreferences.getString("timeStamp","");

        if ( timeStamp.isEmpty())
        {
            // SAVE TIME IN SHAREPREFS
            sharedPreferences.edit().putString("timeStamp",time).apply();

        }

您应该维护您已经创建的 Fragment 实例。 (使用 FragmentManager 或仅将其与变量一起保存可能会完成这项工作)

Activity 中的方法 setCurrentTabFragment() 每次用户单击选项卡时都会调用创建新片段的方法。结果,片段总是 运行 通过 onCreate()

// this method invoke every time user click the tab
private void setCurrentTabFragment(int tabPosition){
    Bundle bundle = new Bundle();
    bundle.putString("data", String.valueOf(tabPosition));
    fragmentOne = new FragmentChild(); // creating new Fragment
    fragmentOne.setArguments(bundle);
    replaceFragment(fragmentOne,"FirstFragment");
}

已编辑:

  • 使用List来维护我们已经创建的Fragment实例。
  • 使用 FragmentManager 提供的 hide()/show() 切换 Fragment,如果 Fragment 之前未添加到 FragmentManager,则使用 add()。

示例代码:

public class MainActivity extends AppCompatActivity {
    private final List<Fragment> fragments = new ArrayList<>();
    private int currentIndex = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TabLayout tabLayout = findViewById(R.id.tabLayout);

        // initial with one page
        Fragment firstFragment = newFragment(0);
        fragments.add(firstFragment);
        addFragment(firstFragment);
        tabLayout.addTab(tabLayout.newTab().setText("Initial tab"));

        // user events
        findViewById(R.id.main_createTab).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                fragments.add(newFragment(tabLayout.getTabCount()));
                tabLayout.addTab(tabLayout.newTab().setText("Pages " + tabLayout.getTabCount()));
            }
        });

        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int nextPageIndex = tab.getPosition();
                if (currentIndex == nextPageIndex){
                    return;
                }
                changingTab(fragments.get(nextPageIndex));
                currentIndex = nextPageIndex;
            }
            @Override public void onTabUnselected(TabLayout.Tab tab) {}
            @Override public void onTabReselected(TabLayout.Tab tab) {}
        });
    }

    private Fragment newFragment(int position) {
        Fragment fragment = new FragmentWithLog();
        Bundle bundle = new Bundle();
        bundle.putString("position", String.valueOf(position));
        fragment.setArguments(bundle);
        return fragment;
    }

    private void addFragment(Fragment fragment) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.main_fragmentFrame, fragment);
        transaction.commit();
    }

    private void changingTab(Fragment fragment) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        transaction.hide(fragments.get(currentIndex));
        if (manager.getFragments().contains(fragment)) {
            transaction.show(fragment);
        } else {
            transaction.add(R.id.main_fragmentFrame, fragment);
        }
        transaction.commit();
    }
}