我的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
再次滑动到A和C之后
似乎再次呼叫RetrieveData
。
答案 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,因此它将加载当前页面和下一页。在您的情况下,它会加载setOffscreenPageLimit
和ViewPager
,当您从A
移至B
时,它将销毁C
的实例。
尝试使用
B
它将加载当前页面和另外2页,因此A,B和C将被加载一次。
修改强>
设置应保留在页面两侧的页数 处于空闲状态的视图层次结构中的当前页面。页面超出此范围 在需要时,将从适配器重新创建限制。
这是作为优化提供的。如果您事先知道这个号码 您将需要支持或具有延迟加载机制的页面 放在你的页面上,调整这个设置可以带来好处 感知到的分页动画和交互的平滑性。如果你有 少量页面(3-4),您可以一次保持活动状态, 在新创建的视图子树的布局中花费的时间会减少 用户来回翻页。
这显然意味着您可以设置要在初始级别加载的页数,如果要在首次运行时加载5页,请将其值设置为4.
现在,如果您要从5个页面中的任何页面移动,A
的{{1}}将不会被调用,因为它已在初始阶段加载。
答案 2 :(得分:1)
如果您每次滑动到C
时都要从数据库中检索,那么您需要事先清除列表,无论是在输入片段时使用onResume
方法,还是在离开片段时的onPause
方法。
这意味着要么清除您的ArrayList
,要确保其不是static
,否则就意味着您必须使用ListView
清除listView.setAdapter(null);
。然后不要忘记在适配器上使用notififyDatasetChanged()
。
答案 3 :(得分:1)
由于您还没有粘贴RetrieveData()代码,我假设您将数据读入ArrayList&lt;&gt;或迭代光标。除了onCreateVie()之外,没有其他地方可以调用此方法。一些可能的解决方案可能是:
请尝试以上。
答案 4 :(得分:1)
许多答案都提示setOffscreenPageLimit但我不推荐它有两个原因。
1)viewpager中片段的资源即使在屏幕外也不会被垃圾收集。这会导致内存问题,以防你的对象占用内存,如位图。
2)当应用程序转到后台并再次出现时,这种方法是不够的。
我建议将您的数据保存在ViewPager中每个片段的onSaveInstanceState中,并检查onCreate中是否保存了数据。如果有数据,请显示。否则,查询数据。
答案 5 :(得分:1)
我在某个时候遇到了类似的问题,问题出在我的代码上,从DB获取日期,我填充了列表,每当页面刷新时都不会创建新列表,它直接添加相同的数据已包含数据的列表,并显示具有相同条目的两行。 为了解决这个问题,我在填充数据之前清除了我的列表。