我有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();
}
}
答案 0 :(得分: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()
中执行此操作,或在UsageTask
类中实现onPreExecute(),并将其放在那里。停止onPostExecute()
中的进度指示器。