Reputation: 1253
I have a fragment and I am setting listview on fragment.
Following is the code:
public class AttachmentsFragment extends Fragment {
ListView lstView = null;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//retains fragment instance across Activity re-creation
setRetainInstance(true);
objects = new ArrayList<AttachModel>();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = null;
view = inflater.inflate(R.layout.tab_attachment, container, false);
lstView = (ListView) view.findViewById(R.id.listViewAttachment);
adapter = new AttachAdapter(getActivity(), 0, 0, objects);
lstView.setAdapter(adapter);
return view;
}
}
In the adapter I have a progress bar and a textview to show the progress of the progress bar. A button to start and stop the progress bar
public class AttachAdapter extends ArrayAdapter<AttachModel> implements OnClickListener {
Context context;
ArrayList<AttachModel> objects = new ArrayList<AttachModel>();
AttachModel info;
//Activity act;
AttachModel model;
public AttachmentsAdapter(Context context, int resource,
int textViewResourceId, ArrayList<AttachmentsModel> objects) {
super(context, textViewResourceId, textViewResourceId, objects);
this.context = context;
this.objects = objects;
}
// no. of attachments available
@Override
public int getCount() {
return objects.size();
}
@Override
public AttachmentsModel getItem(int position) {
return objects.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, final ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
if(null == row) {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.attachment_list_item, parent, false);
//textview for showing progress
holder.textViewProgress = (TextView) row.findViewById(R.id.txtViewPg);
//progress bar to show the progress
holder.progressBar = (ProgressBar) row.findViewById(R.id.pgBar);
holder.progressBar.setTag(position);
holder.textViewProgress.setVisibility(TextView.VISIBLE);
holder.img_view_fileIcon.setVisibility(ImageView.VISIBLE);
holder.progressBar.setVisibility(ProgressBar.VISIBLE);
//to start stop the progress bar
holder.button = (Button)row.findViewById(R.id.img_btn_download);
holder.button.setVisibility(Button.VISIBLE);
holder.button.setTag(position);
holder.button.setOnClickListener(this);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
return row;
}
private class ViewHolder {
TextView textViewProgress;
ProgressBar progressBar;
Button button;
boolean downloadFlag = false;
}
@Override
public void onClick(View v) {
View vParent=(View) v.getParent();
ViewHolder tempHolder = null;
tempHolder=(ViewHolder) vParent.getTag();
//toggle button like functionality
if(!tempHolder.downloadFlag) {
tempHolder.downloadFlag = true;
tempHolder.progressBarStatus = 0;
async = new AsyncTaskAttachments(tempHolder, objects.get(Integer.parseInt(v.getTag().toString())).getFilePath());
tempHolder.async.execute();
objects.get((Integer)tempHolder.progressBar.getTag()).setAsyncTask(tempHolder.async);
}else {
tempHolder.downloadFlag = false;
tempHolder.progressBar.setProgress(0);
tempHolder.textViewProgress.setVisibility(TextView.GONE);
tempHolder.textViewProgress.setText("");
tempHolder.progressBarStatus = 0;
tempHolder.async.cancel(true);
}
}
public class AsyncTaskAttachments extends AsyncTask<Void, Void, Void> {
private ViewHolder holder;
public AsyncTaskAttachments(ViewHolder holder, String filePath) {
this.holder = holder;
this.filePath = filePath;
}
public void attach(Activity act) {
this.act = act;
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
holder.progressBarStatus = 0;
for(int i=0; i<=10; i++) {
try {
Thread.sleep(1000);
holder.progressBarStatus = i*10;
if(isCancelled()) {
break;
}
publishProgress();
}catch (Exception e) {
// TODO: handle exception
}
}
return null;
}
/* (non-Javadoc)
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
/* (non-Javadoc)
* @see android.os.AsyncTask#onPreExecute()
*/
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
holder.progressBarStatus = 0;
holder.textViewProgress.setText("" + holder.progressBarStatus + "%");
holder.progressBar.setProgress(holder.progressBarStatus);
}
/* (non-Javadoc)
* @see android.os.AsyncTask#onProgressUpdate(Progress[])
*/
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
// TODO Auto-generated method stub
holder.progressBar.setProgress(holder.progressBarStatus);
holder.textViewProgress.setText("" + holder.progressBarStatus + "%");
}
}
}
Note: This is just to show the way I am doing it. This is just a glimpse. I need to know whether I am on the right track or not.
On Orientation change, the progress bar is not able to retain and start the progress from where the orientation change.
Thanks in advance
Upvotes: 2
Views: 1977
Reputation: 252
I know this question is old and it's been answered, so just for the record: you can keep the state of a progress bar after orientation change with a viewmodel. I had a progress bar in a fragment and the progress bar was activated upon pressing a button. The trick is setting a variable in the viewmodel when the progress bar is activated and reading this variable in the onCreatView method of the fragment. This way, the progress bar will continue doing the same thing it did before orientation change (spinning / not spinning). This can be applied to other situations with modifications.
Viewmodel:
// create livedata variable
private final MutableLiveData<Boolean> mIsProgressBarActive = new MutableLiveData<>();
// get status from viewmodel
public LiveData<Boolean> getProgressBarStatus() {return mIsProgressBarActive; }
// save status to viewmodel
public void setProgressBarStatus(boolean status) {
mIsProgressBarActive.postValue(status);
}
Fragment onCreate:
super.onCreate(savedInstanceState);
mViewModel = ViewModelProviders.of(getActivity()).get(yourViewModel.class);
Fragment onCreateview:
View content = inflater.inflate(R.layout.your_fragment, container, false);
ProgressBar progressBar = content.findViewById(R.id.progressbar);
// if it was spinning, keep progress bar spinning after orientation change
if(mViewModel.getProgressBarStatus().getValue()) {
progressBar.setIndeterminate(true);
}
// activate progress bar and save its state to viewmodel
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressBar.setIndeterminate(true);
mViewModel.setProgressBarStatus(true);
}
});
Xml layout:
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"/>
Upvotes: 1
Reputation: 1253
Its done.. For all those who are facing this problem or will face this in the future.
Do not try to recreate the view. Just inflate your listview once in the onCreate() method.
Because, the oncreate and ondestroy methods are called only once when the fragment is retained. So inorder to maintain the state of the progress bar, put the code in the oncreate method.
Upvotes: 0
Reputation: 1783
When orientation changes, your activity (and fragments in contains) are re-created. So You call your asyncTask again and it's setting progress to zero:
holder.progressBarStatus = 0;
Solution: save progress in fragment's onSaveInstanceState(), resotre in onCreateView() ans make asyncTask use this value for initial progress setting.
Upvotes: 1