1

我有一个FragmentActivity由一个ViewPager和一个组成的ActionBar。这ViewPager有一个带有 3 个片段的适配器。这些片段会TextView根据在ActionBar.

这是我的问题:每当我在 中的视图之间滑动时ViewPager,我希望根据在ActionBar. 我通过这样设置一个监听器来尝试这个:

    mViewPager.setOnPageChangeListener(new OnPageChangeListener() {

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

然后,setTimePeriod()调用两个模拟方法: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);
}

注意:当您在文本视图中设置文本时,我并不确切知道 UI 是什么样子,如上面的switch-case语句所示。缓慢的操作完成之前,您可能不想更改这些内容。如果是这样,只需将它们移动到onPostExecute().

此外,在缓慢的操作开始之前显示某种进度指示器可能是一种好习惯,让用户知道发生了什么。您可以在创建任务之前执行此操作,或者在类中setTimePeriod()实现onPreExecute()UsageTask并将其放在那里。停止进度指示器onPostExecute()

于 2013-05-24T09:10:16.933 回答