【问题标题】:Stop function calling in tabs在选项卡中停止函数调用
【发布时间】:2016-01-15 03:49:08
【问题描述】:

我的 android 中有 3 个滑动标签(A、B、C)。说到标签 c,我有一个函数 RetrieveData(),用于从 MySQL 检索数据并加载到 listView

假设在 MySQL 中我只有一行数据,当谈到 c 时,数据将被加载到 listView 中(只有一个列表)。当我滑动到 Tab A 并再次滑动到 C 时,列表现在变为 2。 有没有办法让RetrieveData() 只调用一次?谢谢。

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View edit_details = inflater.inflate(R.layout.edit_work_details, container, false);
       // EditDetails = new ArrayList<HashMap<String, String>>();
        listViewUpdate = (ListView) edit_details.findViewById(R.id.listViewEdit);
        totalHours=(TextView)edit_details.findViewById(R.id.hour);
        setHasOptionsMenu(true);
        Bundle bundle = this.getArguments();
        if (getArguments() != null) {
            ID = bundle.getString("ID");
           RetrieveData(ID); // retrieve data from MySQL
        }
        Toast.makeText(getActivity(), "Details" + ID, Toast.LENGTH_LONG).show();
      }

TabAdapter

public class TabsFragmentPagerAdapter extends FragmentPagerAdapter {

    public TabsFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
        // TODO Auto-generated constructor stub
    }

    @Override
    public Fragment getItem(int index) {
        // TODO Auto-generated method stub

        if(index == 0) {

            Fragment fragment=new A();
            Bundle bundle = new Bundle();
            bundle.putString("ID", Edit.ID);
            fragment.setArguments(bundle);
            return fragment;

        }
        if(index == 1) {
            Fragment fragment = new B();
            Bundle bundle = new Bundle();
            bundle.putString("ID", Edit.ID);
            fragment.setArguments(bundle);
            return fragment;
        }

        if(index == 2) {
            Fragment fragment = new C();
            Bundle bundle = new Bundle();
            bundle.putString("ID", Edit.ID);
            fragment.setArguments(bundle);
            return fragment;
        }

        return null;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return 3;
    }

}

ViewPager 代码

public class ActivityB extends ActionBarActivity implements ActionBar.TabListener {

    private ViewPager viewPager;
    private ActionBar actionBar;
    private TabsFragmentPagerAdapter tabsAdapter;
    private String[] item = new String[]{"Information","Work Force","Work Details"};
    private String id;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);
//        id=getIntent().getExtras().getString("ID");
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        tabsAdapter = new TabsFragmentPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(tabsAdapter);
        actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        for(int i=0; i<4; i++){
            actionBar.addTab(actionBar.newTab().setText(item[i]).setTabListener(this));
        }
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg) {
                // TODO Auto-generated method stub
                actionBar.setSelectedNavigationItem(arg);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub

            }
        });

    }



    @Override
    public void onTabReselected(ActionBar.Tab arg0, FragmentTransaction arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction arg1) {
        // TODO Auto-generated method stub
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab arg0, FragmentTransaction arg1) {
        // TODO Auto-generated method stub

    }

}

这是我的标签 c

再次滑动到 A 和 C 后

好像又在调用RetrieveData

【问题讨论】:

  • @playmaker420 再次检查
  • retrieveData() 函数的代码?顺便说一句,函数名称以小写开头是一种常见的做法。只有类名应该以 Big 开头。
  • 如何从活动中调用这个片段
  • @playmaker420 我使用滑动标签
  • 你能把那个代码贴出来

标签: android json listview tabs


【解决方案1】:

您应该使用setOffscreenPageLimitViewPager。它将设置您首先要加载多少页寻呼机。

setOffScreeenPageLimit 的默认值为 1,因此它将加载当前页面和下一页。在您的情况下,它将加载AB,当您从B 移动到C 时,它将破坏A 的实例。

尝试使用

`pager.setOffscreenPageLimit(2)`

它将加载当前页面和另外 2 个页面,因此 A、B 和 C 将被加载一次。

编辑

设置应保留到两侧的页数 视图层次结构中的当前页面处于空闲状态。超出此范围的页面 将在需要时从适配器重新创建限制。

这是作为优化提供的。如果你事先知道号码 您需要支持或具有延迟加载机制的页面 放置在您的页面上,调整此设置可以在以下方面受益 分页动画和交互的感知平滑度。如果你有 您可以一次保持活动的少量页面(3-4), 更少的时间将花费在新创建的视图子树的布局上 用户页面来回切换。

Source

这显然意味着您可以在初始级别设置要加载的页面数,如果您想在第一次运行时加载 5 个页面,请将其值设置为 4。

现在,如果您从 5 个页面中的任何一个页面移动,Fragment 中的 onCreateView() 将不会被调用,因为它在初始阶段已经加载。

【讨论】:

    【解决方案2】:

    您可以通过将 OffscreenPageLimit 设置为 2 到您的 ViewPager 实例来防止这种情况。 这是文档 -

    /**
         * Set the number of pages that should be retained to either side of the
         * current page in the view hierarchy in an idle state. Pages beyond this
         * limit will be recreated from the adapter when needed.
         *
         * <p>This is offered as an optimization. If you know in advance the number
         * of pages you will need to support or have lazy-loading mechanisms in place
         * on your pages, tweaking this setting can have benefits in perceived smoothness
         * of paging animations and interaction. If you have a small number of pages (3-4)
         * that you can keep active all at once, less time will be spent in layout for
         * newly created view subtrees as the user pages back and forth.</p>
         *
         * <p>You should keep this limit low, especially if your pages have complex layouts.
         * This setting defaults to 1.</p>
         *
         * @param limit How many pages will be kept offscreen in an idle state.
         */
        public void setOffscreenPageLimit(int limit) {
            if (limit < DEFAULT_OFFSCREEN_PAGES) {
                Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " +
                        DEFAULT_OFFSCREEN_PAGES);
                limit = DEFAULT_OFFSCREEN_PAGES;
            }
            if (limit != mOffscreenPageLimit) {
                mOffscreenPageLimit = limit;
                populate();
            }
        }
    

    【讨论】:

      【解决方案3】:

      如果您每次滑动到C 时都从数据库中检索,那么您需要事先清除列表,或者在您输入片段时在onResume 方法中,或者在onPause 方法中当你离开片段时。

      这意味着要么清除您的ArrayList,并确保它不是static,否则意味着您必须使用listView.setAdapter(null); 清除您的ListView。然后不要忘记在适配器上使用notififyDatasetChanged()

      【讨论】:

      • 你能解释更多吗?谢谢
      • RetrieveData(ID) 中,您正在设置某种List 并将其传递给您的ListView adapter。只需清楚 listRetrieveData(ID) 的开头,它应该可以工作,无论您的 setOffscreenPageLimit 是什么大小。
      【解决方案4】:

      由于您尚未粘贴 RetrieveData() 代码,我假设您将数据读入 ArrayList 或遍历光标。此外,除了 onCreateVie() 之外,没有其他地方可以调用此方法。一些可能的解决方案可能是:

      1. 如果您明确设置 viewPager.setOffscreenPageLimit(x),其中 x>1,请删除该代码。默认情况下,该值为 1,并且 view Pager 每次都会调用 createView。
      2. 当您使用 FragmentPagerAdapter 时,一旦您理想地加载了您的 C 片段,就不应再次创建它,因为它应该存在于内存中并且 ViewPager 将使用它。检查您的 onCreateView() 是否每次都被调用用于 C 片段。
      3. 请确保每次将数据检索到列表中时,您没有追加到列表中,而是清除列表然后添加它。

      请在上面尝试。

      【讨论】:

        【解决方案5】:

        许多答案建议使用 setOffscreenPageLimit,但我不推荐它,原因有两个。

        1) viewpager 中的片段资源即使在屏幕外也不会被垃圾回收。如果您的对象像位图一样占用内存,这将导致内存问题。

        2)当应用程序进入后台并再次进入前台时,这种方法是不够的。

        我建议将您的数据保存在 ViewPager 中每个片段的 onSaveInstanceState 中,并检查 onCreate 中是否保存了数据。如果有数据,请显示。否则,查询数据。

        【讨论】:

          【解决方案6】:

          我曾经遇到过类似的问题,问题出在我的代码上,在从数据库中获取日期时,我正在填充列表,并且每当页面刷新时它都不会创建新列表,而是直接将相同的数据添加到已包含数据并显示具有相同条目的两行的列表。 为了解决这个问题,我在填充数据之前清除了我的列表。

          【讨论】:

          • 用户列表.clear();或者您可以重新初始化列表,它将清除所有数据
          猜你喜欢
          • 2014-02-19
          • 1970-01-01
          • 1970-01-01
          • 2016-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多