2016-01-15 9 views
6

私はアンドロイドに3つのスワイプタブ(A、B、C)を持っています。タブCに来るとき、私はMySQLからデータを検索し、listViewにロードするために使用される関数RetrieveData()を持っています。機能の停止タブの呼び出し

MySQLでは1行のデータのみを持ちます.cに来ると、データはlistView(1つのリストのみ)にロードされます。タブAにスワイプしてCにもう一度スワイプすると、リストは2になります。 RetrieveData()を1回だけ呼び出す方法はありますか?ありがとう。

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を呼び出すように思えます。

+0

コードを共有する – playmaker420

+0

@ playmaker420もう一度確認してください –

+0

retrieveData()関数のコードはありますか?関数名が小文字で始まるのが普通です。クラス名のみBigを開始する必要があります。 – Jiyeh

答えて

1

あなたはViewPagersetOffscreenPageLimitを使用する必要があります。最初にロードするページャのページ数を設定します。

デフォルトでは、setOffScreeenPageLimitのデフォルト値は1であるため、現在のページと次のページが読み込まれます。あなたのケースではABをロードします。CからBに移動すると、Aのインスタンスが破棄されます。

は、それが現在のページと2ページ以上A、BおよびCが一度ロードされますので、をロードします

`pager.setOffscreenPageLimit(2)` 

を使用してみてください。アイドル状態でのビュー階層に 現在のページのいずれかの側に保持すべきページ数を設定し

EDIT

。この を超えるページは、必要に応じてアダプタから再作成されます。

これは最適化として提供されています。ページ数が の場合は、 ページで遅延ロードメカニズムをサポートする必要があります。この設定を調整すると、 ではページングアニメーションと相互作用の滑らかさが向上します。 少数のページ(3-4)を一度に有効にしておくと、 は、新しく作成されたビューサブツリーのレイアウトに費やされる時間が であり、ユーザーページが前後に移動します。

Source

それは明らかに、あなたが最初の実行で、5ページをロードする場合、初期レベルでロードするページ数を設定することができることを意味し、今4

にその値を設定5ページのうちのいずれかのページから移動する場合、onCreateView()Fragmentは、初期段階ですでに読み込まれているので、呼び出されません。あなたがDBからあなたがCにスワイプするたびに取得している場合は、フラグメントを入力したとき、または方法であなたがフラグメントを離れるとき

1

これを防ぐには、OffscreenPageLimitViewPagerインスタンスに2を設定します。ここ はドキュメントである -

/** 
    * 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

は、その後、あなたはどちらかonResume方法では、手の前にリストをクリアする必要があります。

これは、どちらかの意味例えば、あなたのArrayListをクリアし、そのはないstaticことを確認し、またはそうでなければ、あなたがlistView.setAdapter(null);を使用してListViewをクリアしなければならないことを意味。次に、アダプターでnotififyDatasetChanged()を使用することを忘れないでください。

+0

あなたはもっと説明できますか?ありがとう –

+1

'RetrieveData(ID)'では、何らかの 'List'を設定し、それをあなたの' ListView adapter'に渡しています。 'RetrieveData(ID)'の先頭で 'list'をクリアするだけで、' setOffscreenPageLimit'のサイズに関係なく動作します。 – eoinzy

1

あなたはRetrieveData()コードを貼り付けていないので、データをArrayList <>に読み込んだり、カーソルを使って反復したりすると思います。また、onCreateVie() 。可能な解決策の一部であってもよい:

  1. あなたが明示的にそのコードを削除し、X> 1 viewPager.setOffscreenPageLimit(X)を、設定している場合。デフォルトでは、この値は1で、ビューページャは毎回createViewを呼び出します。
  2. FragmentPagerAdapterを使用しているときは、Cフラグメントを理想的に読み込んだら、メモリに存在し、ViewPagerがそれを使用するため、再度作成しないでください。onCreateView()が毎回呼び出されているかどうか確認してくださいC断片の場合。
  3. リストを消去して追加するのではなく、毎回リストにデータを取り込みながら、リストに追加していないことを確認してください。

上記を試してください。

1

多くの回答はsetOffscreenPageLimitを示唆していますが、私は2つの理由でこれをお勧めしません。

1)ビューページ内のフラグメントのリソースは、画面外であってもガベージコレクションされません。これは、ビットマップのようなメモリを取るオブジェクトがある場合にメモリの問題を引き起こします。

2)このアプローチは、アプリがバックグラウンドに移行して再度フォアグランドに戻るときには不十分です。

あなたのViewPagerの各フラグメントのデータをonSaveInstanceStateに保存し、onCreateに保存されているデータがあるかどうかを確認することをお勧めします。データがある場合は、それを表示します。それ以外の場合は、データを照会します。

1

DBから日付を取得する際に問題が発生し、リストを作成していたときにページがリフレッシュされるたびに新しいリストが作成されず、同じデータが直接追加されていました。すでにデータが入っているリストにあり、同じエントリの2つの行が表示されます。 この問題を解決するために、データを入力する前にリストをクリアしました。

+0

リストをクリアするには? –

+1

ユーザlist.clear(); または新しいリストを初期化するとすべてのデータが消去されます – Arshad

関連する問題