Sunday 24 June 2012

AsyncTask run in background thread of a invisible Fragment of ViewPager

Further exercise from last post "Communication between Fragments in ViewPager".

When a button in MyFragmentA clicked, it will start a AsyncTask in MyFragmentC, running in background and update a ProgressBar. When the ProgressBar finished, it will update MyFragmentB. It can be noted that the AsyncTask run in background even MyFragmentC is not in visible screen.

AsyncTask run in background thread of a invisible Fragment of ViewPager


Modify MyFragmentA.java and /res/layout/fragment_a.xml to add a Butten to start AsyncTask in MyFragmentC.
package com.exercise.AndroidViewPager;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MyFragmentA extends Fragment {

EditText A_input;
Button A_enter;
Button A_startCProgress;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);

A_input = (EditText)myFragmentView.findViewById(R.id.a_input);
A_enter = (Button)myFragmentView.findViewById(R.id.a_enter);
A_enter.setOnClickListener(A_enterOnClickListener);

A_startCProgress = (Button)myFragmentView.findViewById(R.id.a_startcprogress);
A_startCProgress.setOnClickListener(A_startCProgressOnClickListener);

return myFragmentView;
}

OnClickListener A_startCProgressOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String TabOfFragmentC = ((AndroidViewPagerActivity)getActivity()).getTabFragmentC();

MyFragmentC fragmentC = (MyFragmentC)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentC);

fragmentC.StartProgress();

}

};

OnClickListener A_enterOnClickListener
= new OnClickListener(){

@Override
public void onClick(View arg0) {

String textPassToB = A_input.getText().toString();

String TabOfFragmentB = ((AndroidViewPagerActivity)getActivity()).getTabFragmentB();

MyFragmentB fragmentB = (MyFragmentB)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentB);

fragmentB.b_updateText(textPassToB);

Toast.makeText(getActivity(),
"text sent to Fragment B:\n " + TabOfFragmentB,
Toast.LENGTH_LONG).show();
}};

}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment A" />
<EditText
android:id="@+id/a_input"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/a_enter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter to Fragment B"/>
<Button
android:id="@+id/a_startcprogress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Async Progress in Fragment C"/>
</LinearLayout>


Modify MyFragmentC.java and /res/layout/fragment_c.xml to add a ProgressBar and implement AsyncTask.
package com.exercise.AndroidViewPager;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;

public class MyFragmentC extends Fragment {

ProgressBar cProgress;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_c, container, false);

String myTag = getTag();
((AndroidViewPagerActivity)getActivity()).setTabFragmentC(myTag);

cProgress = (ProgressBar)myFragmentView.findViewById(R.id.progressbar);

return myFragmentView;
}

public void StartProgress(){
new ProgressAsyncTask().execute();
}

public class ProgressAsyncTask extends
AsyncTask<Void, Integer, Void> {

int myProgress;

@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
myProgress = 0;
}

@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);

String TabOfFragmentB = ((AndroidViewPagerActivity)getActivity()).getTabFragmentB();
MyFragmentB fragmentB = (MyFragmentB)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentB);
fragmentB.b_updateText("Progress finished!");

}

@Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
while(myProgress<100){
myProgress++;
publishProgress(myProgress);
SystemClock.sleep(100);
}
return null;
}

@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
cProgress.setProgress(values[0]);
}

}

}


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="It's Fragment C" />
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
android:progress="0"
android:max="100"/>
</LinearLayout>


main activity, AndroidViewPagerActivity.java
package com.exercise.AndroidViewPager;

import java.util.ArrayList;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

public class AndroidViewPagerActivity extends FragmentActivity {

ViewPager mViewPager;
TabsAdapter mTabsAdapter;

String TabFragmentB;
String TabFragmentC;

public void setTabFragmentB(String t){
TabFragmentB = t;
}

public String getTabFragmentB(){
return TabFragmentB;
}

public void setTabFragmentC(String t){
TabFragmentC = t;
}

public String getTabFragmentC(){
return TabFragmentC;
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);

final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Fragment A"),
MyFragmentA.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment B"),
MyFragmentB.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Fragment C"),
MyFragmentC.class, null);

if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}

}

@Override
protected void onSaveInstanceState(Bundle outState) {
//super.onSaveInstanceState(outState);
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
}

public static class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {

private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

static final class TabInfo {
private final Class<?> clss;
private final Bundle args;

TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}

public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}

public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}

@Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub

}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub

}

@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
mActionBar.setSelectedNavigationItem(position);
}

@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub

}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub

}

@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}

@Override
public int getCount() {
return mTabs.size();
}

}

}


Download the files.

No comments:

Post a Comment