与List视图中的每一行RotationAsync

时间:2011-01-03 10:37:10

标签: android rotation android-asynctask

从堆栈溢出中的this回答和那里提到的sample project,我得到了RotationAsync的想法,其中进度条与设备旋转一起正常工作。

我的问题是,我有一个listview,每一行都有progress bar。是否有任何方法保持进度,同时轮换到达行

我在getview类的adapter函数中为按钮单击侦听器创建onclicklistener对象。其onClick函数调用AsyncTask类

由于每个getview(行)都在调用AsyncTask的不同瞬间,因此无法使其成为单吨类的静态。
对此有任何想法。
谢谢。

4 个答案:

答案 0 :(得分:2)

所以你有一个ListView,我假设你有一些适配器,在它的get视图中托管进度条。但是,这一进展必须得到一些正确的支持吗?所以只需保存这些数据。就像我假设这样的适配器:

public class MyProgressBarAdapter extends BaseAdapter {
 private ArrayList<Integer> mProgessValues;
 private SparseArray<AsyncTask<?,?,?>> mTasks;
 // No stored reference to a Context

 private MyProgressBarAdapter() {

 }

 public void saveState(Bundle bundle) {
   bundle.putIntegerArrayList(getClass().getName() + ".progressValues", mProgressValues);
 }

 public Object exportLiveState() {
    return mTasks;
 }

 public static MyProgressBarAdapter restore(Bundle bundle, Object rawState) {
   MyProgressBarAdapter adapter = new MyProgressBarAdapter();
   Class<MyProgressBarAdapter> c = adapter.getClass();
   ArrayList<Integer> progresses = null;

   if (bundle != null) {
      progresses = bundle.getIntegerArrayList(c.getName() + ".progressValues");   
   }

   if (progresses == null) {
     progresses = new ArrayList<Integer>();
   }
   adapter.mProgressValues = progresses;

   if (rawState != null && rawState instanceof SparseArray) {
     adapter.mTasks = (SparseArray<AsyncTask<?,?,?>>) rawState;
   }

   return adapter;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
     convertView = getViewWithHolder(convertView, parent);
     ViewHolder holder = convertView.getTag();
     // set the appropriate things on the view elements.
     holder.position = position;
     holder.taskContainer = mTasks;
     holder.progressBar.setProgress(mProgressValues.get(position));
     convertView.setOnClickListener(new OnClickListener() {
        public void onClick(View view) {
          ViewHolder holder = view.getTag();
          int pos = holder.position;
          SparseArray<AsyncTask> tasks = holder.taskContainer;
          AsyncTask task = tasks.get(pos);
          if (task == null) {
             // Create your task
             task = new AsyncTask<?, ?, ?> (...);
             tasks.put(pos, task);
             task.execute();
          }
        }
    return convertView;
  }
  /// You can write the rest of the adapter I believe.
 ...
}

然后你真的不需要onConfigurationChanged。只需相应地阅读并保存您的数据。

public class MyActivity extends Activity {

 ListView mListView;
 MyProgressBarAdapter mAdapter;

 @Override
 public void onCreate(Bundle savedState) {
   super.onCreate();
   Object[] liveState = getLastNonConfigurationInstance();

   setContentView(R.layout.mylistview_with_progressbars);
   mListView = findViewById(R.id.listview);
   // Be consistent with the index
   MyProgressBarAdapter adapter = MyProgressBarAdapter.restore(savedState, liveState[0]);
   mListView.setAdapter(adapter);
   mAdapter = adapter;
  ...
 }

 @Override
 public void onSaveInstanceState(Bundle bundle) {
   mAdapter.save(bundle);
 }

 @Override
 public Object[] onRetainNonConfigurationInstance () {
   // size to be whatever live state you need to store other than the adapter
   Object[] objects = new Object[1]; 
   // This reference will be retained between onCreate() and onDestroy() calls. 
   objects[0] = mAdapter.exportLiveState();
   // Any other things that can't be serialized
   return objects;
 }

 @Override
 public Object[] getLastNonConfigurationInstance() {
  Object[] live = (Object[]) super.getLastNonConfigurationInstance();
  if (live == null) {
    live = new Object[1];
  }
  return live;
 }

 // The rest of your activity
 ... 
}

这将使得当您翻转方向时,将重新创建适配器,但它将重新初始化为之前的状态。我对您存储进度的方式和asyncTasks的性质做了一些假设,但我希望您可以根据需要进行调整。

你甚至可以,如果你不存储对任何上下文的引用,你可能只需将整个适配器本身存储在onRetainNonConfigurationInstance()中并在getLastRetainedNonConfigurationInstance()

中使用它。

答案 1 :(得分:0)


您可以在清单文件中设置android:configChanges =“orientation”,以便在旋转时不重启您的活动

答案 2 :(得分:0)


我用过的一个解决方案 如果我们只有横向和纵向模式的一个布局,那么我们可以通过以下方式解决这个问题 1.在清单文件中设置活动asandroid:configChanges="orientation" 2.像这样覆盖onConfigurationChanged

@Override
    public void onConfigurationChanged(Configuration newConfig) {
      super.onConfigurationChanged(newConfig);

    }

但问题仍然是如果我需要为横向和纵向模式使用不同的布局,每个都有一个列表视图,每行都有进度条。我需要在使用相同的AsyncTask类的旋转时保留进度。

答案 3 :(得分:0)

如何为每个行项设置百分比值?为什么不将该值更新为数据项。你可以有下面的东西。由于你有数据项,你可以存储你想要的任何东西:)左:我想知道我可以在评论中格式化文本而不添加新的答案。

public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
        ViewGroup parent) 

public Object getChild(int groupPosition, int childPosition)