私は次のコードを持っています:
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;
}
}
私は、ナビゲーションがタブによるライブラリアプリケーションを作成しています。問題は、3番目のタブから1番目または1番目から3番目のタブに移動するたびに、タブのコンテンツが更新され、更新を防ぎたい、助けてください ?
デフォルトでは、ViewPager
は、ページをスワイプするとフラグメントを再作成します。これを防ぐには、次の3つのいずれかを試してください。
1。フラグメントのonCreate()
で、setRetainInstance(true)
を呼び出します。
2。フラグメントの数が固定されていて比較的小さい場合、onCreate()
に次のコードを追加します。
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(limit); /* limit is a fixed integer*/
3。FragmentPagerAdapter
の一部として ViewPager
を使用します。
私の記憶が正しければ、2番目のオプションはより有望です。ただし、3つすべてを試して、どれが機能するかを確認することをお勧めします。
最初に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)を呼び出します
この質問に少し遅れましたが、Y.S。のおかげで、ViewPagerの仕組みを知ることができました。私は4つのタブを持つアプリを作成していましたが、いつでも2つのタブしか更新されていないことに気付きました。これはデフォルトの動作であると思われます。数時間の調査の後、Androidが複数のタブを更新して、ユーザーにスムーズなスワイプパフォーマンスをもたらすことを理解しました-tab2をクリックしたことに気付くかもしれませんが、Android tab3のデータを取り込み、準備を整えます。
この動作は優れていますが、長所と短所があります。長所-そのタブに到達したときに外部サーバーからデータがロードされることなく、スムーズなスワイプエクスペリエンスが得られます。短所-タブでのバックスタックの実装は投げに行く可能性があります。タブをクリックすると、ビューページャーは実際にはよりスムーズなタブを呼び出すため、クリックしたタブのバックスタックの内容に基づいてメソッドが左上にバックアロー(ホーム)を設定している場合、大きな問題が発生します。
setOffscreenPageLimitはこれに対する答えです。カスタムバックスタックフレームワークを機能させ、tab2がクリックされたときにtab3が呼び出されないようにするには、値をタブの数に設定するだけです。たとえば、4つのタブがある場合は、setOffScreePageLimit(4)を設定します。これは、Androidが最初に4つのフラグメントすべてをリフレッシュすることを意味します。これはパフォーマンスのオーバーヘッドです(適切に管理する必要があります)。ただし、バックスタックとタブの切り替えはそのままです。役立ちます。
アクティビティは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) {
}
});
上記の私の場合、提案は機能しません。
フラグメントの再作成を制限するために、私がしたこと:
onCreateView
では、次のコードのように、膨張したビューをグローバル変数に格納し、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
に入力する場合
上記のコードapiDataReceived
のようなグローバル変数を作成します
データを正常に解析した場合は、trueに設定します。
ApiCallsが次のような条件を設定する前に:
if(!apiDataReceived){apiCalls()}
したがって、データが解析されない場合にのみapiCalls()が呼び出される場合。
Http呼び出しと解析、またはonCreateView
のようなonStart
の後に呼び出されたメソッド内のその他のことを行います。
上記のコードはkotlinにあります。問題に直面している場合は、コメントでお知らせください。