Video is not pausing in fragment ViewPager - android

I am using View Pager with fragment to showing image and video, I am able to show image and video properly but I have problem, when I swipe for video, then video is playing, but I swipe next or previous then video is still playing on just next or previous screen but when I move two slide next or previous then video is being stop, but why not on next or previous slide.
I search it more but I did not get any solution, any help will be appreciable.
Thanks in advance.
Here is my code:
This is Fragment Class
public class ContentFragment extends Fragment {
private final String imageResourceId;
private String type;
public ContentFragment(String imageResourceId,String type) {
System.out.println("Path In cons="+imageResourceId+"and type is="+type);
this.imageResourceId = imageResourceId;
this.type= type;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("Test", "hello");
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_layout, container, false);
TouchImageView imageView = (TouchImageView) view.findViewById(R.id.touchImage);
imageView.setImageResource(R.id.touchImage);
imageView.setMaxZoom(10f);
VideoView videoView =(VideoView) view.findViewById(R.id.videoView1);
if(type.equals("image")) {
imageView.invalidate();
imageView.setVisibility(View.VISIBLE);
videoView.setVisibility(View.GONE);
try {
System.out.println("IN Content Fragment"+imageResourceId.toString());
Bitmap bmp = BitmapFactory.decodeFile(imageResourceId.toString());
imageView.setImageBitmap(bmp);
} catch(Exception e) {
System.out.println("Error Of image File"+e);
}
} else
try {
if(type.equals("video")){
videoView.invalidate();
videoView.setVisibility(View.VISIBLE);
imageView.setVisibility(View.GONE);
String path = imageResourceId.toString();
videoView.setVideoURI(Uri.parse(path));
videoView.setMediaController(new MediaController(getActivity()));
videoView.setFocusable(true);
videoView.start();
}
} catch(Exception e) {
e.printStackTrace();
}
return view;
}
}
This is pager adapter activity
public class MediaActivity extends FragmentActivity {
private MyAdapter mAdapter;
private ViewPager mPager;
public ArrayList<Content> contentList;
Context context;
LinearLayout numberOfPageLayout;
SharedPreferences sharedPreferences;
Handler progressHandler;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media);
context=(Context) getApplicationContext();
mPager = (ViewPager) findViewById(R.id.pager);
progressHandler = new Handler();
contentList=new ArrayList<Content>();
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
contentList=new ContentDBAdapter(context).getAllContent();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
mAdapter = new MyAdapter(getSupportFragmentManager(),contentList);
mPager.setAdapter(mAdapter);
}
}.execute();
mPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
}
public static class MyAdapter extends FragmentPagerAdapter {
ArrayList <Content>contList=new ArrayList<Content>();
public MyAdapter(FragmentManager fm,ArrayList<Content> cont) {
super(fm);
this.contList=cont;
}
#Override
public int getCount() {
totalPage=contList.size();
return contList.size();
}
#Override
public Fragment getItem(int position) {
Content con=contList.get(position);
return new ContentFragment(con.getPath(),con.getType());
}
}
}

It is because ViewPager keeps offscreen fragments started. For instance you have a fragment visible to the user. ViewPager will try to keep the previous fragment (on the left side) and the next fragment (on the right side) started. This allows ViewPager performing smooth sliding when user decides to change the page, because the next and the previous pages are already prepared.
In your case the video player is not visible (offscreen), but ViewPager keeps it started as due to the behaviour described above. You can use setOffscreenPageLimit() method to change this behaviour. If you set page limit to 0, then offscreen fragments will be paused immediately. Unfortunately they will not only be paused, but stopped and detached from the activity too. This means when you return back to your fragment, it will recreate the whole layout anew. That's why you can try to override either Fragment.setUserVisibleHint() or Fragment.onHiddenChanged() and execute your pause/play logic there. ViewPager will update hidden state of a fragment depending on whether the fragment is actually visible to user or not.
Hope this helps.

You have to override setUserVisibleHint method in a fragment where u play video.
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (this.isVisible())
{
if (!isVisibleToUser) // If we are becoming invisible, then...
{
//pause or stop video
}
if (isVisibleToUser)
{
//play your video
}
}
}

I handle the problem like this:
boolean isVisible = false;
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
isVisible = isVisibleToUser;
if(player!=null)
player.pause();
super.setUserVisibleHint(isVisibleToUser);
}
then in onCreateView method:
SimpleExoPlayer player;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_screen_slide_page, container, false);
PlayerView playerView = v.findViewById(R.id.playerView);
playerView.getLayoutParams().width = ListPager.widthPixels;
playerView.getLayoutParams().height = ListPager.widthPixels;
if(player!=null)
player.release();
player = new SimpleExoPlayer.Builder(App.applicationContext).build();
playerView.setPlayer(player);
MediaItem mediaItem = MediaItem.fromUri(url);
player.setMediaItem(mediaItem);
player.prepare();
//---------The following code is important because if you remove the following if
// then if the next page is displaying, android will automatically initiate the
// previous and the next page, and the player will start playing :|
if(isVisible)
player.play();
}

Related

Why does pressing back from detail activity after landscape-to-portrait-switch show an empty screen?

Below is the MainActivity class that I'm using. The code checks to see if the phone is in landscape or portrait. If it's in portrait, it will show the main fragment in the main activity only (the main fragment is a static fragment in the main_activity.xml file). Then if a "Recipe" is clicked it will open a detail activity with its own fragment. If the phone is in landscape mode, it will show the main fragment and the detail fragment side by side. Everything works perfectly fine however when I follow the procedure below I get a white screen instead of the main activity:
Procedure:
Switch to landscape
Switch back to portrait
Choose an item and wait for the detail activity to open
Press back
Here instead of the main activity window I get a white screen
If I don't switch to landscape and just start with the portrait mode everything is fine. It seems like switching to landscape does something that causes the problem and I can't figure out what. Any tip on what's going on or where to look would be much appreciated.
public class MainActivity extends AppCompatActivity implements RecipesFragment.OnRecipeClickListener {
private String RECIPE_PARCEL_KEY;
private boolean mTwoPane;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RECIPE_PARCEL_KEY = getString(R.string.ParcelKey_RecipeParcel);
if (findViewById(R.id.linearLayoutTwoPane) != null) {
mTwoPane = true;
if (savedInstanceState == null) {
RecipeFragment recipeFragment = new RecipeFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.recipeFrameForTwoPane, recipeFragment)
.commit();
}
} else {
mTwoPane = false;
}
}
#Override
public void OnRecipeClick(Recipe recipe) {
if (mTwoPane) {
RecipeFragment recipeFragment = new RecipeFragment();
recipeFragment.setRecipe(recipe);
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.recipeFrameForTwoPane, recipeFragment)
.commit();
} else {
Class destinationClass = DetailActivity.class;
Intent intentToStartDetailActivity = new Intent(this, destinationClass);
intentToStartDetailActivity.putExtra(RECIPE_PARCEL_KEY, recipe);
startActivity(intentToStartDetailActivity);
}
}
}
EDIT:
Adding RecipeFragment's code below:
public class RecipeFragment extends Fragment {
private Recipe mRecipe;
#BindView(R.id.tv_recipeName) TextView recipeNameTextView;
public RecipeFragment(){
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recipe_fragment,container,false);
ButterKnife.bind(this,view);
if(mRecipe!=null) {
recipeNameTextView.setText(mRecipe.getName());
}else{
recipeNameTextView.setText(getString(R.string.messageSelectARecipe));
}
return view;
}
public void setRecipe(Recipe recipe){
mRecipe = recipe;
}
}
EDIT:
I followed #mt0s's advice and created different background colors for the fragments and activities and finally narrowed down the problem to a line in my recyclerview adapter code. My adapter code is below. Inside loadInBackground() on line URL url = new URL(getString(R.string.URL_RecipeJSON)); I get a Fragment RecipesFragment{96e9b6a} not attached to Activity exception. I don't understand why I'm getting this exception and what the best way to resolve this is. Have I placed the right code in the right fragment methods (ie OnCreate vs OnActivityCreated vs OnCreateView vs etc)?
public class RecipesFragment extends Fragment
implements RecipeAdapter.RecipeAdapterOnClickHandler,
LoaderManager.LoaderCallbacks<ArrayList<Recipe>> {
#BindView(R.id.rv_recipes) RecyclerView mRecyclerView;
private RecipeAdapter mRecipeAdapter;
private static final int LOADER_ID = 1000;
private static final String TAG = "RecipesFragment";
private OnRecipeClickListener mOnRecipeClickListener;
public RecipesFragment(){
}
public interface OnRecipeClickListener {
void OnRecipeClick(Recipe recipe);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recipes_fragment, container, false);
ButterKnife.bind(this, view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mRecipeAdapter = new RecipeAdapter(this);
mRecyclerView.setAdapter(mRecipeAdapter);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void OnClick(Recipe recipe) {
mOnRecipeClickListener.OnRecipeClick(recipe);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try{
mOnRecipeClickListener = (OnRecipeClickListener) context;
} catch (ClassCastException e){
Log.e(TAG, "onAttach: Host activity class must implement OnRecipeClickListener.");
}
}
#Override
public Loader<ArrayList<Recipe>> onCreateLoader(int i, Bundle bundle) {
return new AsyncTaskLoader<ArrayList<Recipe>>(getActivity()) {
#Override
protected void onStartLoading() {
super.onStartLoading();
forceLoad();
}
#Override
public ArrayList<Recipe> loadInBackground() {
String response;
ArrayList<Recipe> recipes = null;
try {
URL url = new URL(getString(R.string.URL_RecipeJSON)); //***I get an exception here***
response = NetworkUtils.getResponseFromHttpUrl(url, getActivity());
recipes = RecipeJsonUtils.getRecipeFromJson(getActivity(), response);
} catch (Exception e) {
Log.e(TAG, "loadInBackground: " + e.getMessage());
}
return recipes;
}
};
}
#Override
public void onLoadFinished(Loader<ArrayList<Recipe>> loader, ArrayList<Recipe> recipes) {
mRecipeAdapter.setRecipeData(recipes);
}
#Override
public void onLoaderReset(Loader<ArrayList<Recipe>> loader) {
}
}
I finally figured out the problem and the solution. The problem is that onStartLoading() in the AsyncTaskLoader anonymous class in RecipesFragment class gets called every time the fragment is resumed whether the enclosing Loader is called or not. This causes the problem. I need to have control over when onStartLoading() is being called and I only want it to be called if and only if the enclosing Loader is being initialized or restarted. As such, I destroyed the loader in onPause() of the fragment and restarted it in onResume(). Hence, I added the following code to the RecipesFragment class:
#Override
public void onPause() {
super.onPause();
getLoaderManager().destroyLoader(LOADER_ID);
}
#Override
public void onResume() {
super.onResume();
getLoaderManager().restartLoader(LOADER_ID, null, this);
}
I also removed initLoader() from onCreate(). This way, every time the fragment is resumed (or created) onStartLoading() will be called. I tried this and it solves my problem.
When you switch from the landscape to portrait or the opposite the Android OS destroy your activity and recreate it again. this what probably trigger your problem

Null object reference exception while calling mediaplayer methods

I am getting this error while calling my player.pause(); method in my application. I am pausing music using ImageButton. I am calling method from song_list class to pause the track. But, following exception occurs:
Attempt to invoke virtual method 'void android.media.MediaPlayer.pause()' on a null object reference
My MainActivity:
public class MusicKom extends AppCompatActivity {
private static String TAG = "PermissionDemo";
public static final int REQUEST_READ_STORAGE = 112;
private ImageButton btplay;
private ImageButton pausemusic;
public void playbutton(int playbuttonid){
btplay=(ImageButton)findViewById(R.id.play);
btplay.setBackgroundResource(playbuttonid);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_kom);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
// Create an adapter that knows which fragment should be shown on each page
final viewpageadapter adapter = new viewpageadapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
Button bt1 = (Button)findViewById(R.id.song_list);
Button bt2 = (Button)findViewById(R.id.album_list);
Button bt3 = (Button)findViewById(R.id.artist_list);
pausemusic = (ImageButton)findViewById(R.id.play);
bt1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setCurrentItem(0);
}
});
bt2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setCurrentItem(1);
}
});
bt3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setCurrentItem(2);
}
});
pausemusic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
songs_list sl=new songs_list();
sl.pauseplay();
pausemusic.setBackgroundResource(R.drawable.stop);
}
});
}
}
My song_list Fragment:
public class songs_list extends Fragment {
// Adapter that exposes data from a Cursor to a ListView widget.
private MediaCursorAdapter mediaAdapter = null;
public MediaPlayer player;
private String currentFile="";
private boolean isStarted = true;
private TextView selelctedFile = null;
private View v=null;
private String selectedtitem=null;
private int fileposition;
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
player = new MediaPlayer();
// Use cursor to get data from external resource
final Cursor cursor = getActivity().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
// check Cursor has data or not
if (null != cursor) {
cursor.moveToFirst();
mediaAdapter = new MediaCursorAdapter(getActivity().getApplicationContext(), R.layout.list_layout, cursor);
v=inflater.inflate(R.layout.fragment_songs_list, container, false);
ListView lv = (ListView)v.findViewById(android.R.id.list);
lv.setAdapter(mediaAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedtitem = (String) view.getTag();
startPlay(selectedtitem);
}
});
}
return v;
}
private void startPlay(String file) {
player.stop();
player.reset();
try {
player.setDataSource(file);
player.prepare();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
((MusicKom) getActivity()).playbutton(R.drawable.play);
}
public void pauseplay(){
Log.i(TAG, "pauseplay: ");
player.pause();
}
}
How can you call another activity method without actually launching the activity. In your case the another activity is not loaded and hence media player object is not created.
please post the whole code to get more information.
You are using a Fragment as a regular java class. Fragment's onCreateView() is not called when you instantiate Fragment. It is only called when you show a fragment with a valid FragmentTranscation. See Fragment Life cycle.
Comment down if you want the fragment to show up when you have to call pauseplay();, I will add the relevant code.
Otherwise, you should be using a regular java class to create and play/pause a media player from anywhere. Something like:
// package com.example.package_name;
import android.media.MediaPlayer;
public class SoundPlayer {
private MediaPlayer mediaPlayer;
// rawSongId is in form of 'R.id.song_name'
public SoundPlayer(Context context, int rawSongId){
mediaPlayer = MediaPlayer.create(context, rawSongId);
}
public SoundPlayer(Context context, String dataSource){
// handle media player with your data source
}
public void start(){
if(mediaPlayer != null) {
mediaPlayer.start();
}
}
public void pause(){
if(mediaPlayer != null) {
mediaPlayer.pause();
}
}
public void stop(){
if(mediaPlayer != null) {
mediaPlayer.stop(); // reset(); ?
}
}
}
Now, instead of
songs_list sl = new songs_list();
sl.pauseplay();
you can,
String dataSource = ""; // generate your dataSource here
// initialize MediaPlayer with dataSource
SoundPlayer soundPlayer = new SoundPlayer(this, dataSource);
// Use its methods
soundPlayer.start();
soundPlayer.pause();
soundPlayer.stop();
please try to use proper camelCase coding conventions. Your pauseplay() should be pausePlay(); or pauseOrPlay().

Using Cache in android application

I've developing a android application and there's a feature in it that loads some images using asynctask. I think if i can save these images as cache i can boost the performance of the app as i am loading a lot of images. How can i do this? How can i keep cache in my android application?
My class
public class MovieFragment extends Fragment {
private ViewPager viewPager;
private PageAdapter pageAdapter;
private ViewPageAdapter adapter;
private ArrayList<BaseElement> filmCategory;
private Fragment fragment;
private Activity activity;
private CommonVariable commonVariable;
private FilmCategory category;
private Dialog dialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.movie_fragment, container, false);
fragment = this;
activity = this.getActivity();
commonVariable = (CommonVariable) activity.getApplication();
viewPager = (ViewPager) view.findViewById(R.id.news_page_viewpager);
dialog = new Dialog(this.getActivity(),
android.R.style.Theme_Translucent_NoTitleBar);
new BackGround().execute();
return view;
}
public class BackGround extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
filmCategory = JSONServices.getCategory();
return null;
}
#Override
protected void onPostExecute(Void result) {
commonVariable.setCategory(filmCategory);
if (filmCategory != null) {
pageAdapter = new PageAdapter(
fragment.getChildFragmentManager(), filmCategory,
activity);
viewPager.setAdapter(pageAdapter);
} else {
Toast.makeText(activity, "No Active Internet Connection",
Toast.LENGTH_LONG).show();
}
dialog.dismiss();
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
// commonVariable.setFilmDetails((FilmCategory)
// category.getFilm().get(position));
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
super.onPostExecute(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
dialog.setContentView(R.layout.dialog);
dialog.show();
super.onPreExecute();
}
}
if you are downloading images from server then i think Volley library help you out. it will remove boilerplate code and easy to read it support caching also. and if you want to implement cache then follow this link. and please avoid asyctask it will not survive config changes. use asynctaskLoader :-)
It seems that it might be easiest to use a third party library such as Picasso, Universal Image Loader, or Volley
I would check those out first before trying to implement your system for image caching. In most cases one of those three options will handle everything you need to accomplish.

Android viewpager AsyncTask finish when page changed

I have view pager. My viewpager contains 3 fragments. In the first fragment I have an AsyncTask class. I parsed JSON with AsyncTask and I can show it in listview. (everything is ok)
I have one problem AsyncTask which I have in the first fragment does not finish when I go to the next fragments. When I am in the second fragment my AsyncTask is also running. How can I write code to cancel my AsyncTask when viewpager's page changed?
This is my source (this is the first fragment source; another fragment source is the same but the only difference is the Server Url):
public class StradaChefs1 extends Fragment {
public static CustomerStatistic stat;
private ConnectionDetector con;
private AlertDialogManager alert = new AlertDialogManager();
#SuppressLint("ClickableViewAccessibility")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.strada_chefs_1, container,
false);
stat = new CustomerStatistic();
con = new ConnectionDetector(getActivity());
if (!con.isConnectingToInternet()) {
alert.showAlertDialog(getActivity(),
"You have not internet connection");
} else {
stat.execute("my urlllllllll"); // geo
}
return rootView;
}
public class CustomerStatistic extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = ProgressDialog.show(getActivity(), "Please Wait... ",
"Loading... ");
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
return Utils.getJSONString(params[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONArray mainJson = new JSONArray(result);
String first = mainJson.getString(0);
JSONObject jobject = new JSONObject(first);
String image = jobject.getString("image");
String String_title = jobject.getString("title");
String String_name = jobject.getString("name");
String String_desc = jobject.getString("description");
String second = mainJson.getString(1);
} catch (JSONException e) {
e.printStackTrace();
}
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
}
#Override
public void onResume() {
Log.e("DEBUG", "onResume of HomeFragment");
super.onResume();
}
#Override
public void onStop() {
super.onStop();
if (stat != null && stat.equals(AsyncTask.Status.RUNNING)) {
stat.cancel(true);
Toast.makeText(getActivity(), "finished", Toast.LENGTH_SHORT)
.show();
}
}
}
This is a viewpager java code
public class TabbedActivity1 extends Fragment {
private StradaChefs1 mfragment1;
private StradaChefs2 mfragment2;
private StradaChefs3 mfragment3;
private StradaChefs4 mfragment4;
SectionsPagerAdapter mSe;
public static final String TAG = TabbedActivity1.class.getSimpleName();
ViewPager mViewPager;
private ArrayList<Fragment> fragmentList;
public static TabbedActivity1 newInstance() {
return new TabbedActivity1();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_item_one_1, container, false);
mSe=new SectionsPagerAdapter(getChildFragmentManager());
mViewPager = (ViewPager) v.findViewById(R.id.pager1);
CirclePageIndicator circle=(CirclePageIndicator)v.findViewById(R.id.circleindicator1);
mViewPager.setAdapter(mSe);
circle.setViewPager(mViewPager);
mfragment1 = new StradaChefs1();
mfragment2 = new StradaChefs2();
mfragment3 = new StradaChefs3();
mfragment4 = new StradaChefs4();
fragmentList = new ArrayList<Fragment>();
fragmentList.add(mfragment1);
fragmentList.add(mfragment2);
fragmentList.add(mfragment3);
fragmentList.add(mfragment4);
mViewPager.setPageTransformer(false, new PageTransformer() {
#Override
public void transformPage(View page, float position) {
page.setRotationY(position * -40);
}
});
return v;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
}
}
How can I solve this problem?
The FragmentPagerAdapter keeps additional fragments, besides the one shown, in resumed state, so you can't use onPause and onResume for starting/stopping the AsyncTask. The solution is to implement a custom OnPageChangeListener and create a new method for when the fragment is shown.
1) Create LifecycleManager Interface The interface will have two methods and each ViewPager’s Fragment will implement it. These methods Are as follows:
public interface FragmentLifecycle {
public void onPauseFragment();
public void onResumeFragment();
}
2) Let each Fragment implement the interface
3) Implement interface methods in each fragment - in onPauseFragment stop the AsyncTask, in onResumeFragment start it
4) Call interface methods on ViewPager page change You can set OnPageChangeListener on ViewPager and get callback each time when ViewPager shows another page
5) Implement OnPageChangeListener to call your custom Lifecycle methods
Listener knows the new position and can call the interface method on new Fragment with the help of PagerAdapter. I can here call onResumeFragment() for new fragment and onPauseFragment() on the current one.
I need to store also the current fragment’s position (initially the current position is equal to 0), since I don’t know whether the user scrolled from left to right or from right to left. See what I mean in code:
private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
int currentPosition = 0;
#Override
public void onPageSelected(int newPosition) {
FragmentLifecycle fragmentToShow = (FragmentLifecycle)pageAdapter.getItem(newPosition);
fragmentToShow.onResumeFragment();
FragmentLifecycle fragmentToHide = (FragmentLifecycle)pageAdapter.getItem(currentPosition);
fragmentToHide.onPauseFragment();
currentPosition = newPosition;
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) { }
public void onPageScrollStateChanged(int arg0) { }
};
I didn't write the code. Full tutorial here
When you start the asynctask set the flag isRunning=true
when you are trying to jump from one fragment to other it mean
as per fragment lifecycle your are pausing and stoping your current fragment
so in onStop method of fragment you can check isRunning flag of asynctask is true if yes the
cancel the asyntask
its my logic hope it will help you to achieve your requirement

onCreate invoke multiple times in fragment in android

I have a ListView in my activity.On clicking on the list item it invokes another activity.In that activity I have implemented ViewPager and fragments.
When it loads first time onResume() ,onCreate() and onCreateView() method called twice, if I clicks on first list item. (i.e. it loads first and second fragment view)
when I click on the any other List fragment except first then it calls onResume() ,onCreate() and onCreateView() methods three times (i.e. It loads previous and after and click view )
It is absoutely fine but I have google analytics code with which I have to track only current page so where I can put this code to load for only current page
My question is my googleAnalytics code tracs three or two pages at first time even user doesnot gone through those pages how to avoid this ?
My code is as below for fragment
public class MainListActivity extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate()");
CustomFragmentPagerAdapter adapter = new CustomFragmentPagerAdapter();
viewPager.setAdapter(adapter);
}
}
//code for fragment adapter
public class CustomFragmentPagerAdapter extends FragmentPagerAdapter {
public CustomFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
CustomFragment customFragment = new CustomFragment();
arrayList.add(customFragment);
return customFragment;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return arrayList.size();
}
}
//code for fragment
public class CustomFragment extends Fragment{
public CustomFragment() {
super();
}
#Override
public void onResume() {
super.onResume();
Log.v(TAG, "onCreate -Resume");
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Log.v(TAG, "onCreateView");
return myAnyView;
}
}
The problem is that the onResume() method is called for all your fragments, that is including the invisible ones.
Check gorn's answer here:
How to determine when Fragment becomes visible in ViewPager
You have to override
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// Your logic
}
and do your logic in there.

Categories

Resources