RotationAsync 与列表视图中的每一行

发布于 2024-10-09 18:44:59 字数 651 浏览 0 评论 0原文

来自这个在堆栈溢出中回答并引用那里的 示例项目,我得到了 RotationAsync 的想法,其中进度条可以很好地配合设备旋转。

但是我的问题是,我有一个listview,每一行都有进度条。有什么方法可以在旋转到达行时保留进度

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

由于每个 getview (行)都调用我的 AsyncTask 的不同时刻,我无法使其静态吨级。
对此有任何想法。
谢谢。

From this answer in stack overflow and the sample project referred there, i got the Idea of RotationAsync, where a progress bar work fine with device rotation.

But my problem is, i have a listview with each row there is progress bar. And is there any way to retain the progress while rotation for reach row.

Me creating onclicklistener object for the button click listener in getview function of my adapter class. Where its onClick function call the AsyncTask class

Since each getview (row) is calling different instant of my AsyncTask, i cannot make it static of single ton class.
Any Idea on this.
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半﹌身腐败 2024-10-16 18:44:59

所以你有一个 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() 中使用它就可以了

So you have a ListView which I assume you have some adapter which in it's get view hosts the progress bars. However that progress must be backed by something right? So just save that data. Like I am assuming an adapter like so:

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.
 ...
}

and then you don't really need onConfigurationChanged. Just read and save your data accordingly.

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
 ... 
}

That will make it so that when you flip the orientation, the adapter will be recreated but it will be reinitialized to the same state it was in before. I made some assumptions about the way you store your progress and the nature of your asyncTasks but I hope you can adjust as needed.

You could even, if you don't store a reference to any context, you might be able to get away with just storing the entire adapter itself inside the onRetainNonConfigurationInstance() and using that in the getLastRetainedNonConfigurationInstance()

战皆罪 2024-10-16 18:44:59

您可以在清单文件中设置 android:configChanges="orientation" 以使您的 Activity 在旋转时不会重新启动

You can set android:configChanges="orientation" in manifest file to make your activity does not restart when rotating

朕就是辣么酷 2024-10-16 18:44:59

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

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

    }

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

One solution that i used
If we have only one layout for both landscape and portrait mode, then we can we can solve this by
1. Set the activity asandroid:configChanges="orientation" in manifest file
2. Override the onConfigurationChanged like this

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

    }

But the problem is still the if i need to use different layout for both landscape and portrait mode, each have a listview with progress bar in each row. there i need to retain the progress while rotate which use same AsyncTask class.

山田美奈子 2024-10-16 18:44:59

如何为每个行项目设置百分比值?为什么不将该值更新到数据项。你可以有像下面这样的东西。既然您拥有数据项,您就可以存储您想要的任何内容:)
Ps:我想知道我可以格式化评论中的文本而不添加新答案。

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

public Object getChild(int groupPosition, int childPosition) 

How can you set percentage value for each row item? Why don't you update that value to the data item. You can have some thing like below. Since you have the data item you can store whatever you want :)
Ps: I wonder that I can format text in comment to not add new answer.

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

public Object getChild(int groupPosition, int childPosition) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文