0

ドロワーのメニューによってはTab + ViewPagerのコンテンツが開きます。各ページ(フラグメント)は、そのデータがサーバーから要求されたリストです。Drawer + Tab + ViewPagerと各フラグメントのサーバからのデータロード

私がそのメニューをクリックするたびに、空の画面の代わりにデータが依然として要求されていても、すぐにタブが表示されます。私はTabPragmentにプログレスバーを追加しようとします。そのため、ViewPagerとポケットベルのデータを準備するときに内容が表示されます。しかし、コンテンツはまだロードインジケータなしで空の画面を表示します。問題は、サーバーからデータを要求するメソッドが各ページャから呼び出されるためです。

データを要求するメソッドをTabFragmentに移動する必要がありますか?

マイTabFragmentクラスは次のようになります。

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    ..... 

    content = view.findViewById(R.id.content); 
    content.setVisibility(View.GONE); 
    tabLayout = (TabLayout) view.findViewById(R.id.tabs); 
    viewPager = (ViewPager) view.findViewById(R.id.pager); 

    progressBar = (ProgressBar) view.findViewById(R.id.progressBar1); 

    farmerViewPagerAdapter = new FarmerViewPagerAdapter(getChildFragmentManager(), titles); 
    viewPager.setOffscreenPageLimit(2); 
    viewPager.setAdapter(farmerViewPagerAdapter); 
     tabLayout.post(()->{ 
      tabLayout.setupWithViewPager(viewPager); 
      for (int i = 0; i < titles.length; ++i){ 
       tabLayout.getTabAt(i).setIcon(icons[i]); 
      } 
     }); 
} 

そして、ここで各ページの断片(各ページ要求異なるデータ)を次のとおりです。

@Override 
public void onViewCreated(View view, Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 

    this.view = view; 

    emptyView = view.findViewById(R.id.emptyView); 
    emptyText = (TextView) view.findViewById(R.id.emptyTextView); 

    recyclerView = (RecyclerView) view.findViewById(R.id.list); 

    recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 
    recyclerView.setItemAnimator(new DefaultItemAnimator()); 

    adapter = new FarmerAdapter(data, getContext()); 

    recyclerView.setAdapter(adapter); 
    recyclerView.addItemDecoration(
      new HorizontalDividerItemDecoration.Builder(getContext()) 
        .showLastDivider() 
        .marginResId(R.dimen.divider_margin_left, R.dimen.divider_margin_right) 
        .build()); 

    swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout); 
    swipeRefreshLayout.setOnRefreshListener(() -> { 

       if (!Util.isNetworkAvailable(getContext())) { 
        if (swipeRefreshLayout.isRefreshing()) swipeRefreshLayout.setRefreshing(false); 
       } else { 
        currentPage = 1; 
        loadData(); //method to request data from server 
       } 
      } 
    ); 


    if (user != null) { 
     getDataFromLocal(); 
     addToAdapter(); 
     loadData(); 
    } 

} 

(エド)loaddataの方法:

Observable<Response<List<Data>>> dataApi = request.getServerData(currentPage, 
      NUMBER_DATA_PER_PAGE, 
      token); 
    dataApi.subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(responseData -> { 
       if (swipeRefreshLayout.isRefreshing()) swipeRefreshLayout.setRefreshing(false); 
       if (responseData.isSuccessful() && responseData.code() == 200) { 

        currentPage++; 

        adapter.add(responseData.body()); 
        if (adapter.getItemCount() < 1) { 
         emptyText.setText("Empty"); 
         emptyView.setVisibility(View.VISIBLE); 
        } 

       } else { 
        try { 
         JSONObject json = new JSONObject(responseFarmer.errorBody().string()); 
         Toast.makeText(getContext(), json.getString("message"), Toast.LENGTH_LONG).show(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      }, error -> { 
       if (swipeRefreshLayout != null && swipeRefreshLayout.isRefreshing()) 
        swipeRefreshLayout.setRefreshing(false); 
       if (error != null && error.getLocalizedMessage() != null) 
        Toast.makeText(getContext(), error.getLocalizedMessage(), Toast.LENGTH_LONG).show(); 
      }); 

このメソッドは、ポケットベルのフラグメントから呼び出されます。

答えて

0

AsyncTaskには、空のdoInBackground()本体があります。それは本質的にそれを同期させます。

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    ..... 
    new SetAdapterTask().execute(); 
} 

が、あなたのAsyncTaskはバックグラウンドで何もしていないので、postExecuteは右preExecute後にオフに発射:

private class SetAdapterTask extends AsyncTask<Void,Void,Void> { 

    protected Void doInBackground(Void... params) { 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Void result) { 
      doPostExecute(); 
     } 

     @Override 
     protected void onPreExecute() { 
      doPreExecute(); 
     } 
    } 

、あなたはこのようなあなたのコードでこれを呼び出す:あなたはこのAsyncTaskを持っていると言います、これと同等の全部作る:つまり

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    ..... 
    doPreExecute(); 
    doPostExecute(); 
} 

を、あなたはそれがpostExに消すpreExecute中とimmediatellyその後、あなたのプログレスバーを表示させますエキュート。

これに適切にアプローチするには、ProgressBarの表示設定を、私が想定しているloadData()のどこかにあるデータをロードするために使用するAsyncTaskに移動します。データの読み込み自体については、データをロードする実際のメソッドを見ずに何が間違っているかを言うのは難しいです。

+0

loadDataメソッドを追加します。私はviewPagerのsetAdapterとTabLayoutのsetupWithViewPagerを設定できないので、doInBackgroud()は空です。 asynctaskをviewpagerを設定するために使用しなかった場合、コンテンツがviewpagerでタブに変わる前に、引き出しがフリーズします。 – Tobi

+0

私はgetSupportFragmentManager()をgetChildFragmentManager()に変更した後、私はもうasynctaskを必要としませんでした。問題は同じですが、私がドロワーメニューをクリックすると、ツールバーのタイトルがすぐに変わり、コンテンツはまだフリーズされ、すべてのリクエスト(各ページャーのloadData)が完了した後に変更されます。私が達成したいのは、私がドロワーメニューをクリックすると、すべての要求がまだ機能していても内容はすぐに変わるはずです。 – Tobi

+0

それはまだ関連している場合:私は非常に観測に慣れていませんが、問題はあなたadapter.add(responseData.body())の後にadapter.notifyDatasetChanged()を呼び出していないと思われる。 adapter.notifyDatasetChanged()を追加して、アダプタを更新し、新しく追加されたデータを表示します。 – Bjelis

関連する問題