停止在标签中调用函数

时间:2016-01-15 03:49:08

标签: android json listview tabs

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

假设在MySQL中我只有一行数据,当来到c时,数据将被加载到listView(仅一个列表)。当我滑动到选项卡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

enter image description here

再次滑动到A和C之后

enter image description here

似乎再次呼叫RetrieveData

6 个答案:

答案 0 :(得分:1)

您可以通过将OffscreenPageLimit设置为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();
        }
    }

答案 1 :(得分:1)

您应该使用<div ui-view="table"></div>的{​​{1}}。它将首先设置您要加载的寻呼机页数。

setOffScreeenPageLimit的默认值为1,因此它将加载当前页面和下一页。在您的情况下,它会加载setOffscreenPageLimitViewPager,当您从A移至B时,它将销毁C的实例。

尝试使用

B

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

修改

  

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

     

这是作为优化提供的。如果您事先知道这个号码   您将需要支持或具有延迟加载机制的页面   放在你的页面上,调整这个设置可以带来好处   感知到的分页动画和交互的平滑性。如果你有   少量页面(3-4),您可以一次保持活动状态,   在新创建的视图子树的布局中花费的时间会减少   用户来回翻页。

Source

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

现在,如果您要从5个页面中的任何页面移动,A的{​​{1}}将不会被调用,因为它已在初始阶段加载。

答案 2 :(得分:1)

如果您每次滑动到C时都要从数据库中检索,那么您需要事先清除列表,无论是在输入片段时使用onResume方法,还是在离开片段时的onPause方法。

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

许多答案都提示setOffscreenPageLimit但我不推荐它有两个原因。

1)viewpager中片段的资源即使在屏幕外也不会被垃圾收集。这会导致内存问题,以防你的对象占用内存,如位图。

2)当应用程序转到后台并再次出现时,这种方法是不够的。

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

答案 5 :(得分:1)

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