Show animations on every viewpager change - android

I want to show animations on every content of layout inflater. Below is the code that I am using but the problem is animations shows only on first page of view pager.
What I have understood so far is that animations on all pages content gets loaded on position 0 but I may be wrong.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = null;
if (position == 0) {
Home.rel_footer.setVisibility(View.VISIBLE);
v = inflater.inflate(R.layout.reward_points_circles, container,
false);
YoYo.with(Techniques.ZoomIn).duration(5000)
.playOn(v.findViewById(R.id.circle_1));
YoYo.with(Techniques.ZoomIn).duration(5000)
.playOn(v.findViewById(R.id.circle_2));
YoYo.with(Techniques.ZoomIn).duration(5000)
.playOn(v.findViewById(R.id.circle_3));
} else if (position == 1) {
Home.rel_footer.setVisibility(View.GONE);
v = inflater.inflate(R.layout.qrcode_scanner_promotion, container,
false);
YoYo.with(Techniques.Landing).duration(5000)
.playOn(v.findViewById(R.id.imgView_iphone));
YoYo.with(Techniques.Landing).duration(5000)
.playOn(v.findViewById(R.id.imgView_ipad));
} else if (position == 2) {
Home.rel_footer.setVisibility(View.GONE);
v = inflater.inflate(R.layout.deals_promotion, container, false);
YoYo.with(Techniques.ZoomIn).duration(5000)
.playOn(v.findViewById(R.id.imgView_iphone_left));
YoYo.with(Techniques.ZoomIn).duration(5000)
.playOn(v.findViewById(R.id.imageView_iphone_front));
YoYo.with(Techniques.ZoomIn).duration(5000)
.playOn(v.findViewById(R.id.imgView_iphone_right));
}
return v;
}

In my opinion you should not apply animations in onCreateView if you want to see your animation on each page change. You should instead use OnPageChangeListener interface and apply your animation there once user has changed a pager (switching to another page).
A simple code snippet to get you started.
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener(){
#Override
public void onPageSelected (int position){
// Apply animations here w.r.t the position
}
... Other overridden methods ...
});

mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
switch (arg0) {
case 1:
//load ur animations here
break;
default:
break;
}
}
#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
}
});

Related

Cannot update views on left and right side of view pager

I have used viewpager which displays view with an image and radiobutton below. Each swipe screen is not a fragment, they are layouts which just swipe the same view with different imageview. The problem is that, I am unable to deselect the radio button which is in left and right side of the current view after i select the radio button of the current screen. If I return POSITION_NONE in getItemPosition(), it refresh the screen and radio button also deselected but the view is flickered. If i am able to call instantiateItem(), my problem is solved . But this method is called only when view is destroyed based on the setOffsetScreenPageLimit(). How can I achieved such requirements, if view pager cannot help?
Fragment:
public class AnswerImageDialogFragment extends DialogFragment implements ViewPager.OnPageChangeListener {
//member declaration
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strQuestion = null;
View rootView = inflater.inflate(R.layout.activity_viewpager_demo, container,
false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
intro_images = (ViewPager) rootView.findViewById(R.id.pager_introduction);
pager_indicator = (LinearLayout) rootView.findViewById(R.id.viewPagerCountDots);
//do some stuff
//set the adapter
mAdapter = new ViewPagerAdapter(getContext(), map);
intro_images.setAdapter(mAdapter);
intro_images.setCurrentItem(clickPosition);
intro_images.setOnPageChangeListener(this);
setUiPageViewController();
bus = EventBus.getDefault();
bus.register(this);
return rootView;
}
//other method
}
PagerAdapter:
public class ViewPagerAdapter extends PagerAdapter {
// member declaration
public ViewPagerAdapter(Context mContext, HashMap<String, Object> map) {
//other initialization
}
#Override
public int getCount() {
return optionImages.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.pager_item, container, false);
final ImageView ivOption = (ImageView) itemView.findViewById(R.id.answerId); // this is used as radio button in this case
/*The code snippet is to select the answer option based on whether answer is choosen or not.
If choosen, select as default in the pop up answer.
*/
if (null != ans) {
Iterator iterator = ans.iterator();
if (ans.size() > 0) {
int value = (int) iterator.next();
if (value == position) {
ivOption.setImageResource(R.drawable.ic_radio_button_tick);
} else {
ivOption.setImageResource(R.drawable.ic_radio_button_nontick);
}
}
}
p = position;
/*The code snippet is to change the answer value based on the user selection.
This means if user choosen another answer then clear the earlier choosen answer
*/
ivOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//do stuff
}
});
txtQuestion.setText(question);
txtOption.setText(optionsList.get(position));
imageView.setParseFile(optionImages.get(position));
imageView.loadInBackground();
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
LinearLayout ll = (LinearLayout) object;
/*RelativeLayout ivOption = (RelativeLayout) ll.getChildAt(2);
ImageView iv = (ImageView) ivOption.getChildAt(1);
iv.setImageResource(R.drawable.ic_radio_button_tick);*/
container.removeView(ll);
}
#Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
public void refresh(ArrayList object) {
this.object = new ArrayList();
this.object.addAll(object);
this.notifyDataSetChanged();
}

Can't communicate with fragments in ViewPager after orientation change

I have a tab that holds a view pager with 5 fragments in it.
When onPageSelected is called then I tell the current fragment to animate up using
((ItemFragment) pagerAdapter.getItem(position)).animateUp();
and Inside the fragment
public void animateUp(){
if(linearLayout != null){
linearLayout.animate().translationYBy(-75));
}
}
Everything seems to work fine until I rotate the device. The fragments are shown and I can move them but the animateUp() method doesn't do anything. It seems like the viewpager doesn't have a reference to the fragments being shown.
Edit: onCreate is empty, here is onCreateView
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_explore_tab, container, false);
pager = (MultiViewPager)rootView.findViewById(R.id.pager);
List<Fragment> fragmentsList = new ArrayList<>();
for(int i = 0; i < header.length; i++){
ItemFragment fragment = new ItemFragment();
Bundle bundle = new Bundle();
bundle.putInt(ItemFragment.IMAGE_KEY, header[i]);
fragment.setArguments(bundle);
fragmentsList.add(fragment);
}
pager.addOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
((ItemFragment) pagerAdapter.getItem(position)).animateUp();
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
pagerAdapter = new BaseFragmentPagerAdapter(getChildFragmentManager(), fragmentsList);
pager.setAdapter(pagerAdapter);
return rootView;
}
if(linearLayout != null){ *your listener change to null when you rotate device*
linearLayout.animate().translationYBy(-75)); }
You must subscribe listener once more. Try to do this in onResume

Update SeekBar in Fragment with value from SharedPreferences

I have an app with action bar. It has a "Main" fragment and a "Preferences" fragment.
final Main main = new Main();
final Preferences preferences = new Preferences();
drawer.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
Fragment fragment= null;
FragmentManager fragmentManager = getSupportFragmentManager();
switch(position) {
case 0:
fragment = main;
break;
case 1:
fragment = preferences;
break;
}
fragmentManager.beginTransaction()
.replace(R.id.fragment1, fragment)
.commit();
drawerLayout.closeDrawers();
}
});
The "Preferences" fragment has a seekBar that is updated with a value from SharedPreferences. This is the relevant code that makes this within the "Preferences" fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
container.removeAllViews();
View view = inflater.inflate(R.layout.preferences, container, false);
fontSizeBar = (SeekBar) view.findViewById(R.id.fontSizeBar);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(Preferences.this.getActivity().getBaseContext());
final int fontSize = preferences.getInt("fontSize", 10);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
fontSizeBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
Log.v("Progress changed", "Font size: " + progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
Log.v("Start touching", "Font size: " + seekBar.getProgress());
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
Log.v("Stop touching", "Font size: " + seekBar.getProgress());
}
});
fontSizeBar.setMax(10);
fontSizeBar.setProgress(fontSize);
}
});
// Inflate the layout for this fragment
return inflater.inflate(R.layout.preferences, container, false);
}
The method onProgressChanged() is called, because I can see the output "Progress changed", "Font size: 10" in LogCat, but the SeekBar is not visually updated. Additionally,the SeekBar does not responds to the methods onStartTrackingTouch() and onStopTrackingTouch().
I will appreciate any information that could shed some light about the problem.
You're doing everything right, inflating the views and setting up the logic but at the end you do this:
return inflater.inflate(R.layout.preferences, container, false);
which will return a newly inflated layout(so you drop everything you previously done). Instead you need to return the view which you previously inflated:
return view;

How to eliminate white frame while flipping half-way through the next view?

iam using Aphid-FlipView-Library to display static html pages using webview.
but while flipping ,(moving) from one page to another iam getting some white frame ,after that second page is normally loading..
can any one help me , how to remove that flash appearance..
public class FlipTextViewFragment extends Fragment {
private FlipViewController flipView;
String[] urls = {"file:///android_asset/Introduction_print.html","file:///android_asset/introduction2.html"};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
flipView = new FlipViewController(inflater.getContext(), FlipViewController.HORIZONTAL);
flipView.setAdapter(new adp(getActivity().getApplicationContext()));
return flipView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void setText(String item) {
flipView.setAdapter(new adp(getActivity().getApplicationContext()));
}}
then my adapter class is here:
package com.example.flipwebview;
public class adp extends BaseAdapter {
String[] urls = {"file:///android_asset/Introduction_print.html","file///android_asset/introduction2.html"};
Context con;
public adp(Context applicationContext) {
// TODO Auto-generated constructor stub
con=applicationContext;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return urls.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
WebView wv=new WebView(con);
wv.loadUrl(urls[position]);
return wv;
}}
By using my code , i can flip across multiple webviews,but the problem i am getting is when i am halfway flipping the page i cant see my next view,it seems to be a blank page,it gets loaded after i flip my page completely..here is the screen regarding that
loadUrl isn't fastest method to render local HTML files. Since they are included in your app you should load their content into String and use loadData method.
http://developer.android.com/reference/android/webkit/WebView.html#loadData%28java.lang.String,%20java.lang.String,%20java.lang.String%29
EDIT:
One more thing. You should use convertView instead of creating new WebView every time you flip.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
WebView webView = null;
if (convertView == null)
{
webView = new WebView(con);
} else {
webView = (WebView) convertView;
}
webView.loadUrl(urls[position]);
return webView;
}}

Circular ViewPager which uses FragmentPagerAdapter

I would like to implement a ViewPager which uses Fragments and can be swiped in a curcular motion e.g. Page (A<-->B<-->C<-->A).
I have read a couple of posts on how this is done, e.g. returning a fake count of how many elements there are and setting the position at the start in the middle.
how to create circular viewpager?
These all seem to be based of a PagerAdapter. When I try to do a similar thing while extending FragmentPagerAdapter, as soon as I return a fakeCount of pages I get an exception when I Swipe through my Fragments, I only have 2 Fragments.
Exception: java.lang.IllegalStateException: Can't change tag of fragment.
I think this is caused as the FragmentManager thinks I am in position 2 but position 2 points to the fragment at position 0. Does anyone know how I can avoid this? I am thinking I should experiment with extending Fragmentmanager. Any examples or help with this would be greatly appreciated.
I know it is a bit late but this is how it worked for me:
I needed a circular swipe between 3 fragments, so I made those 3 and two more virtual to help me implement the page looping:
public static class FirstViewFragment extends Fragment {
// Empty Constructor
public FirstViewFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_landing_1, container, false);
}
}
public static class SecondViewFragment extends Fragment {
// Empty Constructor
public SecondViewFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_landing_2, container, false);
}
}
public static class ThirdViewFragment extends Fragment {
// Empty Constructor
public ThirdViewFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_landing_3, container, false);
}
}
And two more virtual fragments that enabled me to swipe left from the first and right from the last. The first virtual inflates the same layout as the last actual and the last virtual the same layout as the first actual:
public static class StartVirtualFragment extends Fragment {
public StartVirtualFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_landing_3, container, false);
}
}
public static class EndVirtualFragment extends Fragment {
public EndVirtualFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_landing_1, container, false);
}
}
My Adapter:
private class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return new StartVirtualFragment();
case 1:
if (firstViewFragment == null) {
firstViewFragment = new FirstViewFragment();
}
return firstViewFragment;
case 2:
if (secondViewFragment == null) {
secondViewFragment = new SecondViewFragment();
}
return secondViewFragment;
case 3:
if (thirdViewFragment == null) {
thirdViewFragment = new ThirdViewFragment();
}
return thirdViewFragment;
case 4:
return new EndVirtualFragment();
}
return null;
}
#Override
public int getCount() {
return 5;
}
}
And my page listener I used the onPageScrollStateChanged to set the correct page and implement the loop:
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_DRAGGING) {
int pageCount = viewPager.getChildCount();
int currentItem = viewPager.getCurrentItem();
if (currentItem == 0) {
viewPager.setCurrentItem(pageCount - 2, false);
} else if (currentItem == pageCount - 1) {
viewPager.setCurrentItem(1, false);
}
}
}
});
And in the end:
viewPager.setCurrentItem(1);
Hope I helped
I have a project in the GitHub with some widgets I've created. Here it its:
https://github.com/CyberEagle/AndroidWidgets
In the following package, there are the adapters to be used with the CircularViewPager:
https://github.com/CyberEagle/AndroidWidgets/tree/master/src/main/java/br/com/cybereagle/androidwidgets/adapter
First, you will use CircularViewPager instead of ViewPager in your layout. The CircularViewPager is here: https://github.com/CyberEagle/AndroidWidgets/blob/master/src/main/java/br/com/cybereagle/androidwidgets/view/CircularViewPager.java
This ViewPager expects a WrapperCircularPagerAdapter, instead of a PagerAdapter. This wrapper is used to trick the ViewPager, making it to think there are a lot of items in the ViewPager, but it actually repeat your items to make the circular effect. So, instead of implementing either PagerAdapter, FragmentPagerAdapter or FragmentStatePagerAdapter, you will implement either CircularFragmentPagerAdapter, CircularFragmentStatePagerAdapter or CircularPagerAdapter. Then, you will wrap your adapter with the WrapperCircularPagerAdapter and set the wrapper in the CircularViewPager, instead of your adapter. Also, when it's time to notify dataset changed, you will call the notifyDatasetChanged() in the wrapper.
When implementing one of the circular adapter, you will notice that instead of implementing instantiateItem, you will have to implement instantiateVirtualItem. For the fragment's pager adapter, you will implement getVirtualItem instead of getItem. That is because I've created the concept of virtual items.
To make it clear, imagine a view pager with 4 items, giving that each item represents a music. When you go all the way to left, you will see the 4th item in the left of the first. Actually, it's a whole new item, but it's linked to the virtual item that represents the 4th music.
Another example: imagine there's only one music now. You will see the same music on the left and on the right. There're 3 items at a time, but only one virtual item.
So, as explained, the Wrapper is tricking the ViewPager, making it think that there are a lot of items. To make it more difficult for the user to reach one of the ends of the ViewPager (it'd take a long time anyway), everytime a change happens to the dataset, the ViewPager goes to the same virtual item, but to one of the real items near the middle.
One more important thing is that the CircularViewPager has the method setCurrentVirtualItem. This method calculates which real item is the nearest desired virtual item and then it uses the setCurrentItem to set it. You have also the option to use the getCurrentVirtualItem, that will return the index of the current virtual item. Notice that if you use getCurrentItem, you'll get a large index.
Well, this is it. I'm sorry for the lack of documentation of the project. I'm planning document it soon. I'm also planning to remove the need for the wrapper. Feel free to copy the code (respecting the Apache 2.0 license), to fork or even contribute to it.
**If you want to make 3 views visible at same time and make it circular**
public abstract class CircularPagerAdapter extends PagerAdapter{
private int count;
int[] pagePositionArray;
public static final int EXTRA_ITEM_EACH_SIDE = 2;
private ViewPager.OnPageChangeListener pageChangeListener;
private ViewPager viewPager;
public CircularPagerAdapter(final ViewPager pager, int originalCount ) {
super();
this.viewPager = pager;
count = originalCount + 2*EXTRA_ITEM_EACH_SIDE;
pager.setOffscreenPageLimit(count-2);
pagePositionArray = new int[count];
for (int i = 0; i < originalCount; i++) {
pagePositionArray[i + EXTRA_ITEM_EACH_SIDE] = i;
}
pagePositionArray[0] = originalCount - 2;
pagePositionArray[1] = originalCount -1;
pagePositionArray[count - 2] = 0;
pagePositionArray[count - 1] = 1;
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageSelected(final int position) {
if(pageChangeListener != null)
{
pageChangeListener.onPageSelected(pagePositionArray[position]);
}
pager.post(new Runnable() {
#Override
public void run() {
if (position == 1){
pager.setCurrentItem(count-3,false);
} else if (position == count-2){
pager.setCurrentItem(2,false);
}
}
});
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(pageChangeListener != null)
{
pageChangeListener.onPageScrolled(pagePositionArray[position],positionOffset,positionOffsetPixels);
}
}
public void onPageScrollStateChanged(int state) {
if(pageChangeListener != null)
{
pageChangeListener.onPageScrollStateChanged(state);
}
}
});
}
#Override
public int getCount() {
return count;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return false;
}
public abstract Object customInstantiateItem(ViewGroup container, int position);
public void setPageChangeListener(ViewPager.OnPageChangeListener pageChangeListener)
{
this.pageChangeListener = pageChangeListener;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
int pageId = pagePositionArray[position];
return customInstantiateItem(container,pageId);
}
#Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
public void setFirstItem()
{
viewPager.setCurrentItem(EXTRA_ITEM_EACH_SIDE - 1);
}
}

Categories

Resources