RotationAsync с каждой строкой в ​​представлении списка - PullRequest
1 голос
/ 03 января 2011

От этого ответа в переполнении стека и примера проекта, упомянутого там, я получил идею RotationAsync, где индикатор выполнения отлично работает с вращением устройства.

Но моя проблема в том, что у меня есть listview с каждой строкой progress bar.И есть ли способ сохранить прогресс во время поворота для достижения строки .

Я создаю объект onclicklistener для слушателя нажатия кнопки в функции getview моего класса adapter.Где ее onClick функция вызывает класс AsyncTask

Поскольку каждый getview (строка) вызывает разные моменты моего AsyncTask, я не могу сделать его статичным для класса одной тонны.
Любая идея включенаэто.
Спасибо.

Ответы [ 4 ]

2 голосов
/ 09 января 2011

Итак, у вас есть 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
 ... 
}

Это позволит сделать так, что при изменении ориентации адаптер будет воссоздан, но он будет повторно инициализирован до того же состояния, в котором находился ранее. Я сделал некоторые предположения о том, как вы сохраняете свой прогресс и о характере ваших асинхронных заданий, но я надеюсь, что вы сможете приспособиться по мере необходимости.

Вы могли бы даже, если вы не сохраняете ссылку на какой-либо контекст, вы могли бы избежать простого хранения всего самого адаптера внутри onRetainNonConfigurationInstance () и использования этого в getLastRetainedNonConfigurationInstance ()

0 голосов
/ 07 января 2011


Одно решение, которое я использовал. Если у нас есть только один макет для альбомного и портретного режимов, то мы можем решить эту проблему с помощью 1. Задайте действие asandroid:configChanges="orientation" в файле манифеста
2. ПереопределитеonConfigurationChanged вот так

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

    }

Но проблема все еще в том, что если мне нужно использовать разную компоновку как для альбомного, так и для портретного режима , у каждого есть список с индикатором выполнения в каждой строке,там мне нужно сохранить прогресс при повороте, который использует тот же класс AsyncTask.

0 голосов
/ 07 января 2011

Как вы можете установить процентное значение для каждого элемента строки?Почему бы вам не обновить это значение для элемента данных.Вы можете иметь что-то вроде ниже.Так как у вас есть элемент данных, вы можете хранить все, что вы хотите :)PS: Интересно, что я могу отформатировать текст в комментарии, чтобы не добавлять новый ответ.

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

public Object getChild(int groupPosition, int childPosition) 
0 голосов
/ 07 января 2011


Вы можете установить android: configChanges = "direction" в файле манифеста, чтобы ваша активность не возобновлялась при вращении

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...