1

FragmentActivityで構成される がありViewPagerますActionBar。これViewPagerには、3 つのフラグメントを持つアダプターがあります。これらのフラグメントは、TextViewで選択されているアイテムに応じて、 の値が変わりますActionBar

ここに私の問題があります: でビュー間をスワイプするたびに、ViewPagerで選択した項目に基づいてフラグメントのデータを設定したいと考えていますActionBar。リスナーを次のように設定して、これを試みます。

    mViewPager.setOnPageChangeListener(new OnPageChangeListener() {

        @Override
        public void onPageSelected(int arg0) 
        {
            setTimePeriod(actionBarItemPosition);
        }
    }

次に、setTimePeriod()と の 2 つのシミュレーション メソッドを呼び出しgetComparedUsage()ますgetThisUsage()。これらはそれぞれ CPU 負荷が高く、その結果、ビュー間をスワイプするとUI が非常に遅くなります。

これを解決するにはどうすればよいですか?

private void setTimePeriod(int position)
{
    periodDropDownPosition = position;

    // Get a reference to the active fragment currently shown by the ViewPager.
    currentFragment = (DetailedFragment) mMyFragmentPagerAdapter.getItem(mViewPager.getCurrentItem());
    List<UsageEntry> dataSet = currentFragment.getDataSet();

    setViewReferencessOnActiveFragment(currentFragment);

    differenceTextView = (TextView) activeView.findViewById(R.id.usage_results_total_value_tv);
    try
    {
        switch(position)
        {
        case PERIOD_DAY:
            resultsThisTextView.setText(R.string.compared_to_text_this_day);
            resultsComparedToTextView.setText(R.string.compared_to_text_compared_day);  
            comparedUsage = getComparedUsage(PERIOD_DAY, dataSet); 
                        // This call brings the phone to its knees
            thisUsage = getThisUsage(PERIOD_DAY, dataSet); 
                        // This call brings the phone to its knees
            break;
        case PERIOD_WEEK:
            resultsThisTextView.setText(R.string.compared_to_text_this_week);
            resultsComparedToTextView.setText(R.string.compared_to_text_compared_week);         
            comparedUsage = getComparedUsage(PERIOD_WEEK, dataSet);
                        // This call brings the phone to its knees
            thisUsage = getThisUsage(PERIOD_WEEK, dataSet);
                        // This call brings the phone to its knees
            break;
        case PERIOD_MONTH:
            resultsThisTextView.setText(R.string.compared_to_text_this_month);
            resultsComparedToTextView.setText(R.string.compared_to_text_compared_month);
            comparedUsage = getComparedUsage(PERIOD_MONTH, dataSet); 
                        // This call brings the phone to its knees
            thisUsage = getThisUsage(PERIOD_MONTH, dataSet); 
                        // This call brings the phone to its knees
            break;
        case PERIOD_YEAR:
            resultsThisTextView.setText(R.string.compared_to_text_this_year);
            resultsComparedToTextView.setText(R.string.compared_to_text_compared_year);
            comparedUsage = getComparedUsage(PERIOD_YEAR, dataSet); 
                        // This call brings the phone to its knees
            thisUsage = getThisUsage(PERIOD_YEAR, dataSet); 
                        // This call brings the phone to its knees
            break;
        }

        setCashOrUnits(isInCashMode);

    }catch(NotEnoughDataException e)
    {
        noDataLayout = (RelativeLayout)activeView.findViewById(R.id.results_not_enough_data_view);
        noDataLayout.setVisibility(View.VISIBLE);
        resultsView = (RelativeLayout)activeView.findViewById(R.id.results_view);
        resultsView.setVisibility(View.INVISIBLE);
        e.printStackTrace();
    }catch(NullPointerException e)
    {
        noDataLayout = (RelativeLayout)activeView.findViewById(R.id.results_not_enough_data_view);
        noDataLayout.setVisibility(View.VISIBLE);
        resultsView = (RelativeLayout)activeView.findViewById(R.id.results_view);
        resultsView.setVisibility(View.INVISIBLE);
        e.printStackTrace();
    }
}
4

1 に答える 1

0

おそらく、これにはAsyncTaskが必要です。

を使用AsyncTaskすると、遅い操作をバックグラウンド (別のスレッド) で実行し、終了時に UI コードを実行して、表示を更新できます。低速な操作が実行されている間、デバイスが完全に応答していないように見えることはありません。

AsyncTaskサブクラス (上記のクラスの内部クラスになります):

private class UsageTask extends AsyncTask<Integer, Void, Boolean> {

     private List<UsageEntry> dataSet;

     public UsageTask(List<UsageEntry> data) {
         this.dataSet = data;
     }

     protected Boolean doInBackground(Integer... params) {
         Boolean success = Boolean.TRUE;
         int period = params[0];
         try {
             // I'm assuming these two methods can throw the exceptions?
             comparedUsage = getComparedUsage(period, dataSet); 
             thisUsage = getThisUsage(period, dataSet);
         } catch(NotEnoughDataException e) {
             success = Boolean.FALSE; 
             e.printStackTrace();
         } catch(NullPointerException e) {
             success = Boolean.FALSE; 
             e.printStackTrace();
         } 
         return success;
     }

     protected void onPostExecute(Boolean success) {
         if (success) {
            // I'm assuming this call somehow modifies the UI?
            setCashOrUnits(isInCashMode);
         } else {
            noDataLayout = (RelativeLayout)activeView.findViewById(R.id.results_not_enough_data_view);
            noDataLayout.setVisibility(View.VISIBLE);
            resultsView = (RelativeLayout)activeView.findViewById(R.id.results_view);
            resultsView.setVisibility(View.INVISIBLE);
         }
     }
 }

そして、次のように使用します。

private void setTimePeriod(int position)
{
    periodDropDownPosition = position;

    // Get a reference to the active fragment currently shown by the ViewPager.
    currentFragment = (DetailedFragment) mMyFragmentPagerAdapter.getItem(mViewPager.getCurrentItem());
    List<UsageEntry> dataSet = currentFragment.getDataSet();

    setViewReferencessOnActiveFragment(currentFragment);

    differenceTextView = (TextView) activeView.findViewById(R.id.usage_results_total_value_tv);

    switch(position)
    {
        case PERIOD_DAY:
            resultsThisTextView.setText(R.string.compared_to_text_this_day);
            resultsComparedToTextView.setText(R.string.compared_to_text_compared_day);
            break;  
        case PERIOD_WEEK:
            resultsThisTextView.setText(R.string.compared_to_text_this_week);
            resultsComparedToTextView.setText(R.string.compared_to_text_compared_week);         
            break;
        case PERIOD_MONTH:
            resultsThisTextView.setText(R.string.compared_to_text_this_month);
            resultsComparedToTextView.setText(R.string.compared_to_text_compared_month);
            break;
        case PERIOD_YEAR:
            resultsThisTextView.setText(R.string.compared_to_text_this_year);
            resultsComparedToTextView.setText(R.string.compared_to_text_compared_year);
            break;
        default: 
            return;
            break;
    }

    UsageTask task = new UsageTask(dataSet);
    task.execute(position);
}

switch-case注:上記のステートメントに示されているように、テキスト ビューでテキストを設定したときに UI がどのように見えるかは正確にはわかりません。遅い操作が完了するまでそれらを変更したくない可能性があります。その場合は、それらを に移動してonPostExecute()ください。

また、遅い操作が始まる前にある種の進行状況インジケーターを表示して、何が起こっているかをユーザーに知らせることもおそらく良い習慣です。でタスクを作成する直前にそれを行うか、クラスにonPreExecute()setTimePeriod()を実装してそこに置くことができます。で進行状況インジケータを停止します。UsageTaskonPostExecute()

于 2013-05-24T09:10:16.933 に答える