2017-01-03 23 views
1

私はアンドロイドアプリケーションのSmartTabLayoutライブラリを介してタブ機能を実装しています。現在私はfragmentを私のtabsの両方のためのviewpagerとして使っています。唯一の違いは、リスト項目の並べ替えということです。以下は私のHomeActivityコードです:異なるタブで使用されている同じフラグメント内のリストビューデータを更新できません

HomeActivity.java

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_home); 

    final ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager); 
    final SmartTabLayout viewPagerTab = (SmartTabLayout) findViewById(R.id.viewpagertab); 
    viewPagerTab.setCustomTabView(this); 

    FragmentPagerItems pages = new FragmentPagerItems(this); 
    pages.add(FragmentPagerItem.of("Test1", SampleFragment.class)); 
    pages.add(FragmentPagerItem.of("Test2", SampleFragment.class)); 

    FragmentStatePagerItemAdapter adapter = new FragmentStatePagerItemAdapter(
      getSupportFragmentManager(), pages); 

    viewPager.setAdapter(adapter); 
    viewPager.setCurrentItem(0); 
    viewPagerTab.setViewPager(viewPager); 
} 

@Override 
public View createTabView(ViewGroup container, int position, PagerAdapter adapter) { 
    LayoutInflater inflater = LayoutInflater.from(container.getContext()); 
    View tab = inflater.inflate(R.layout.custom_tab_icon_and_notification_mark, container, false); 
    TextView txtTab=(TextView)tab.findViewById(R.id.txtTitle); 
    switch (position){ 
     case 0:txtTab.setText("Test1");break; 
     case 1:txtTab.setText("Test2");break; 
     default:throw new IllegalStateException("Invalid pos - "+ position); 
    } 
    return tab; 
} 

私SampleFragment.javaは、私は、データのためのいくつかのサーバ要求を行うとlistviewアダプタを更新ここ下記の通​​りです。

SampleFragment.java

List<Items> lstItems=new ArrayList<>(); 
static ItemListAdapter mAdapter; 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View view= inflater.inflate(R.layout.fragment_sample, container, false); 
    ListView lstviewItems = (ListView) view.findViewById(R.id.lstItems); 
    int position = FragmentPagerItem.getPosition(getArguments()); 
    View emptyView=view.findViewById(R.id.emptyList); 
    lstviewItems.setEmptyView(emptyView); 
    mAdapter = new ItemsListAdapter(getActivity(),lstItems); 
    lstviewItems.setAdapter(mAdapter); 
    switch (position){ 
     case 0: 
      //JsonObjectRequest 
      loadItems(); 
      break; 
     case 1: 
      //sort the loaded items 
      break; 
    } 
    return view; 
} 

private void loadItems(){ 
    try { 
     JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET,url, null, 
       new Response.Listener<JSONArray>() { 
        @Override 
        public void onResponse(JSONArray response) { 
         lstItems.clear(); 
         for (int i = 0; i < response.length(); i++) { 
          //Add item to lstItems 
         } 
         mAdapter.notifyDataSetChanged(); 
        } 
       } 
     }); 
     testApp.getInstance().addToRequestQueue(request); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

しかし、現在のviewPager tabすなわちTest1タブの後でさえもmAdapter.notifyDataSetChanged()listviewは更新取得されていません。 Test2タブに移動すると、データが正しく読み込まれているリストビューの変更が表示されます。以下は、2つの異なるタブのスクリーンショットです。

Tabs

また、私はこの問題のために検索し、私のために動作しませんでした他の解決策を見つけました。溶液の存在のいずれか、以下のようにItemsAdapterにおけるリフレッシュ方法を追加:

public void refresh(List<Items> items) 
{ 
    this.items = items; 
    notifyDataSetChanged(); 
} 

、代わりのmAdapter.notifyDataSetChanged() IはmAdapter.refresh(lstItems);を用います。しかし残念ながら、それはどちらもうまくいきませんでした。どうすればこれを克服できますか?これについてさらに詳しく説明しなければならないかどうか教えてください。

答えて

1

私はあなたの問題はここにあると思う:

mAdapter = new ItemsListAdapter(getActivity(),lstItems);

あなたはItemsListAdapterの新しいインスタンスを作成し、

lstviewItems.setAdapter(mAdapter);

問題とリストビューにバインドし、このアダプタがあるということですstatic。したがって、新しいインスタンスを作成すると古いアダプタが破棄され、他のタブのリストビューにはアダプタがなくなり、データが更新されます。

EDIT:

私は中央の場所にデータをロードすることをお勧めしたいです。レスポンス(あなたのデータオブジェクト)をマネージャクラスに追加します。次に、このデータを使用するすべてのビューでコールバックを実装します(JsonDataChangedCallback)。 Manager.getInstance().registerCallback()を持つマネージャへのコールバックを実装するクラスを登録します。その後、データが変更されるたびにマネージャーのupdateCallbacks()に電話がかかり、すべてのビューが更新されます。それは私のアプリでそのプロセスを実装し、それが動作する方法です。

サンプルコード:

public class CDMMovieManager { 
    private CDMMovieManager() { 
    m_Movies = new ArrayList<>(); 
    m_MovieChangedCallbacks = new ArrayList<>(); 
    } 

    public static synchronized CDMMovieManager getInstance() { 
    if(ms_Instance == null) 
     ms_Instance = new CDMMovieManager(); 

    return ms_Instance; 
    } 

    public void addMovie(CDMMovie p_Movie) { 
    m_Movies.add(p_Movie); 
    notifyCallbacks(); 
    } 

    /** 
    * Registers a movie changed callback 
    * 
    * @param p_MovieChangedCallback the callback to register 
    */ 
    public void registerMovieChangedCallback(IDMMovieChangedCallback p_MovieChangedCallback) { 
    m_MovieChangedCallbacks.add(p_MovieChangedCallback); 
    } 

    /** 
    * Removes a movie changed callback 
    * 
    * @param p_MovieChangedCallback the callback to remove 
    */ 
    public void removeMovieChangedCallback(IDMMovieChangedCallback p_MovieChangedCallback) { 
    m_MovieChangedCallbacks.remove(p_MovieChangedCallback); 
    } 

    private void notifyCallbacks() { 
    for(IDMMovieChangedCallback l_MovieChangedCallback : m_MovieChangedCallbacks) { 
     l_MovieChangedCallback.onMoviesChanged(); 
    } 
    } 
} 

と実装クラス:

public class CDMBasicMovieFragment extends Fragment implements IDMMovieChangedCallback { 

//... 
    @Override 
    public void onMoviesChanged() { 
    m_Adapter.notifyDataSetChanged(); 
    } 
} 
+0

まあ、それは迅速でした。しかしこれは私の問題を解決しましたが、今は別の方法です。私は 'mAdapter'を非静的にし、' tab1'でデータを取得し始めましたが、 'tab2'では何も見つかりませんでした。あなたがこれについて提案できるものは何ですか? –

+0

これはあなたのスイッチケースのためです。現在のフラグメントが位置0にある場合にのみ、データをロードします。更新されたポストをチェックしてください。 – beeb

+0

ビットが混乱しているようです。デモとしてコードサンプルを追加すると便利です:) –

関連する問題