当使用tablayout切换片段时,所有片段都会重新创建

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当使用tablayout切换片段时,所有片段都会重新创建相关的知识,希望对你有一定的参考价值。

我正在使用tablayout创建一个基于Tabs的应用程序。我没有使用viewpager。我的逻辑是用户可以创建片段(Tabs),例如在chrome中添加标签,这样每当用户点击添加按钮时,就会创建一个带有片段的新标签。现在我需要在共享首选项中保存每个片段创建时间的唯一时间戳,这样每当我移动到一个片段时,我可以使用该共享参考时间戳值来执行针对该特定片段的唯一函数。

但我不知道在哪里保存那个时间戳。我试图在片段的Oncreate函数中以毫秒为单位获得时间,但每当我在onCreate调用时每次在标签之间切换时,每当我在标签之间切换时,共享偏好值会随着我在片段中的onCreate中添加而改变。

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

每当我切换到另一个片段时,它只是初始化所有视图和onCreate in called。所以我无法在oncreate中设置时间戳..

请帮我

我的活动代码是:

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类:

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);
        }
    }
}

按照@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$3.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$1.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)

删除TAB功能

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);

        }
    }
答案

您应该维护已创建的Fragment实例。 (使用FragmentManager或只保留变量可能会完成工作)

每次用户单击选项卡时,都会调用Activity中创建新Fragment的方法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()切换片段,如果片段之前没有添加到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();
    }
}
另一答案

要在timeStampshared 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..
    }
}

或者您可以尝试: -

更新fragmentChild的onCreate

   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();

        }

以上是关于当使用tablayout切换片段时,所有片段都会重新创建的主要内容,如果未能解决你的问题,请参考以下文章

TabLayout - 如何仅在选项卡上加载片段

片段中的Tablayout + viewpager,需要清除viewpager中的edittext数据

使用 BaseAdapter 时片段 TabLayout 中的 NullPointerException

如何从片段更改 Tablayout 的背景颜色?

在tablayout片段之间进行通信[重复]

当我从 TabFragment 使用 LoaderManager 启动片段时,为啥 Tablayout 和 Viewpager 会因 NullpointerException 而崩溃?