Android如何在标签更改时停止刷新片段

我有以下代码:

MainActivity.java

package com.erc.library; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.FragmentTransaction; import android.content.SharedPreferences; import android.content.res.Resources; import android.graphics.Color; import android.os.Bundle; import android.os.Environment; import android.os.StrictMode; import android.support.v4.app.FragmentActivity; import android.support.v4.view.ViewPager; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.TextView; import android.widget.Toast; import com.erc.sayeghlibrary.adapter.TabsPagerAdapter; public class MainActivity extends FragmentActivity implements ActionBar.TabListener { private ViewPager viewPager; private TabsPagerAdapter mAdapter; private ActionBar actionBar; // Tab titles private String[] tabs = { "Stories", "Dictionaries", "eBooks"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); int actionBarTitleId = Resources.getSystem().getIdentifier("action_bar_title", "id", "android"); if (actionBarTitleId > 0) { TextView title = (TextView) findViewById(actionBarTitleId); if (title != null) { title.setTextColor(Color.WHITE); } } // Initilization viewPager = (ViewPager) findViewById(R.id.pager); actionBar = getActionBar(); mAdapter = new TabsPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(mAdapter); actionBar.setHomeButtonEnabled(false); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Adding Tabs for (String tab_name : tabs) { actionBar.addTab(actionBar.newTab().setText(tab_name) .setTabListener(this)); } /** * on swiping the viewpager make respective tab selected * */ viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { // on changing the page // make respected tab selected actionBar.setSelectedNavigationItem(position); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { // on tab selected // show respected fragment view viewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // action with ID action_refresh was selected case R.id.Favorites: Toast.makeText(this, "Favorites selected", Toast.LENGTH_SHORT) .show(); break; // action with ID action_settings was selected default: break; } return true; } } 

TabsPagerAdapter.java

 package com.erc.library.adapter; import com.erc.library.Dictionaries; import com.erc.library.Ebooks; import com.erc.library.Stories; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; public class TabsPagerAdapter extends FragmentPagerAdapter { public TabsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int index) { switch (index) { case 0: return new Stories(); case 1: return new Dictionaries(); case 2: // Movies fragment activity return new Ebooks(); } return null; } @Override public int getCount() { // get item count - equal to number of tabs return 3; } } 

我正在制作一个库应用程序,其中导航是通过选项卡,问题是每次我从第三个选项卡转到第一个或第一个到第三个,选项卡内容是刷新的,我想阻止刷新,任何请帮助 ?

默认情况下, ViewPager在您滑动页面时重新创建片段。 为了防止这种情况,您可以尝试以下两种方法之一:

1.在片段的onCreate()中,调用setRetainInstance(true)

2.如果片段数量固定且相对较小,则在onCreate()添加以下代码:

 mViewPager = (ViewPager)findViewById(R.id.pager); mViewPager.setOffscreenPageLimit(limit); /* limit is a fixed integer*/ 

如果我没记错的话,第二种选择更有希望。 但我敦促你们两个都试试,看看哪个有效。

一个必须首先实例化FragmentPagerAdapter ,然后.getCount()将返回一个值 –

.getCount() - 1应设置为默认的屏幕外限制:

 TabsPagerAdapter adapter = new TabsPagerAdapter(getSupportFragmentManager()); /* the ViewPager requires a minimum of 1 as OffscreenPageLimit */ int limit = (adapter.getCount() > 1 ? adapter.getCount() - 1 : 1); ViewPager viewPager = (ViewPager) findViewById(R.id.pager); viewPager.setAdapter(adapter); viewPager.setOffscreenPageLimit(limit); 

您可以通过检查视图是否为null来处理视图重新创建

 public class FragmentExample extends Fragment { private View rootView; public FragmentExample() {} @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { if (rootView == null) { rootView = inflater.inflate(R.layout.fragment_example_layout, container, false); // Initialise your layout here } else { ((ViewGroup) rootView.getParent()).removeView(rootView); } return rootView; } } 

在片段的onCreate()中,调用setRetainInstance(true)

由于活动实现了ActionBar.TabListener,因此一次又一次地调用活动的onCreate()。 所以将以下代码放在onResume()方法中:

  // Initilization viewPager = (ViewPager) findViewById(R.id.pager); actionBar = getActionBar(); mAdapter = new TabsPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(mAdapter); actionBar.setHomeButtonEnabled(false); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Adding Tabs for (String tab_name : tabs) { actionBar.addTab(actionBar.newTab().setText(tab_name) .setTabListener(this)); } /** * on swiping the viewpager make respective tab selected * */ viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { // on changing the page // make respected tab selected actionBar.setSelectedNavigationItem(position); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }); 

这个问题有点晚了,但多亏了YS,了解了ViewPager的工作原理。 我正在构建一个带有4个选项卡的应用程序,并且在任何时候都注意到只刷新了两个选项卡,我认为这是默认行为。 经过几个小时的调查,我了解Android刷新了多个标签,为用户带来了平滑的滑动性能 – 您可能会注意到您已经点击了tab2,但是android会为tab3引入数据并保持准备就绪。

虽然这种行为很好,但它有其优点和缺点。 优点 – 您可以获得平滑的滑动体验,当您在该选项卡中登陆时,无需从外部服务器加载数据。 缺点 – 标签中的backstack实现可能会有所收获。 当您单击选项卡时,视图寻呼机实际上会调用更平滑的选项卡,如果您的方法是根据单击选项卡中的Backstack中的内容在左上角设置backarrow(home),则最终会遇到大麻烦。

setOffscreenPageLimit就是答案。 如果希望自定义backstack框架起作用,并且在单击tab2时不希望调用tab3,则只需将值设置为选项卡数。 例如,如果您有4个选项卡,请设置setOffScreePageLimit(4)。 这意味着Android最初会刷新所有4个片段,这是一个性能开销(你应该妥善管理)。 但是,您的背板和标签切换保持不变。 希望这可以帮助。

在我的情况下,上述建议不起作用。

为了限制片段的重新创建,我做了什么:

onCreateView您可以将膨胀的视图存储在全局variables中,并仅在它为null时对其进行初始化,如下面的代码所示:

  var root:View?=null var apiDataReceived=false override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { // Inflate the layout for this fragment if (root==null) root=inflater!!.inflate(R.layout.fragment_layout, container, false) return root } 

现在,如果您正在解析某些数据并将其填充到RecyclerView或任何其他View

  1. 像上面的代码apiDataReceived一样创建一个全局variables

  2. 如果成功解析数据,请将其设置为true。

  3. 在apiCalls之前设置这样的条件:

    if(!apiDataReceived){apiCalls()}

因此,如果仅在未解析数据时调用apiCalls()。

onCreateView类的onStart类的方法中,您是否进行http调用和解析或其他任何事情

上面的代码在kotlin中,如果您遇到任何问题,请在评论中告诉我。