ViewSwitcher
Below is a slideshow that shows the basic theory of operation. Just click through the slides.
The layout xml code:
<ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/flipper"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ScrollView android:id="@+id/scripScroll0"
android:layout_below="@id/navBar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff"
android:fadingEdgeLength="6px"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:id="@+id/text0"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginLeft="5px"
android:layout_marginRight="5px"
android:textColor="#111"
android:typeface="serif"
/>
</RelativeLayout>
</ScrollView>
<ScrollView android:id="@+id/scripScroll1"
android:layout_below="@id/navBar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff"
android:fadingEdgeLength="6px"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginLeft="5px"
android:layout_marginRight="5px"
android:textColor="#111"
android:typeface="serif"
/>
</RelativeLayout>
</ScrollView>
<ScrollView android:id="@+id/scripScroll2"
android:layout_below="@id/navBar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff"
android:fadingEdgeLength="6px"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:id="@+id/text2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginLeft="5px"
android:layout_marginRight="5px"
android:textColor="#111"
android:typeface="serif"
/>
</RelativeLayout>
</ScrollView>
</ViewFlipper>
The ViewFlipper contains 3 views that each contain a scrollView widget and inside of that is a RelativeLayout with a TextView
inside of that. In your code you will have to capture the swipe gesture and have it trigger your ViewFlipper to advance
to the next view. Keeping track of your views is a little tricky and I'll show you how I do it a little later.
This is how you do the gesture detection. First you need to set up some constants so that we can
find out if the touch event was a legitimate horizontal swipe gesture. So place the following in your variable declaration.
private Animation slideLeftIn;
private Animation slideLeftOut;
private Animation slideRightIn;
private Animation slideRightOut;
//swipe gesture constants
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private GestureDetector gestureDetector;
Next, you need to set up the animations and capture your xml layout elements in your onCreate() method.
scroller0 = (ScrollView)findViewById(R.id.scripScroll0);
scroller1 = (ScrollView)findViewById(R.id.scripScroll1);
scroller2 = (ScrollView)findViewById(R.id.scripScroll2);
flipper = (ViewFlipper)findViewById(R.id.flipper);//you will need to use the flipper object later in your SimpleOnGestureListener class to flip the views
slideLeftIn = AnimationUtils.loadAnimation(this, R.anim.slide_left_in);
slideLeftIn.setAnimationListener(new ScrollLeft());
slideLeftOut = AnimationUtils.loadAnimation(this, R.anim.slide_left_out);
slideRightIn = AnimationUtils.loadAnimation(this, R.anim.slide_right_in);
slideRightIn.setAnimationListener(new ScrollRight());
slideRightOut = AnimationUtils.loadAnimation(this, R.anim.slide_right_out);
the following sets up your event listeners on your scrollers. This also goes in your onCreate method.
gestureDetector = new GestureDetector(new MyGestureDetector());
scroller0.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
return true;
else
return false;
}
});
scroller1.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event){
if (gestureDetector.onTouchEvent(event))
return true;
else
return false;
}
});
scroller2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
return true;
else
return false;
}
});
Create a SimpleOnGestureListener like the following. You only need to override the onFling() method. Here we use the values declared earlier to find out if it is a left or right swipe.
Gesture Detection:
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// int delta = 0;
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
else{
try {
// right to left swipe
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
if(canFlipRight()){
flipper.setInAnimation(slideLeftIn);
flipper.setOutAnimation(slideLeftOut);
flipper.showNext();
}else{
return false;
}
//left to right swipe
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
if(canFlipLeft()){
flipper.setInAnimation(slideRightIn);
flipper.setOutAnimation(slideRightOut);
flipper.showPrevious();
}else{
return false;
}
}
} catch (Exception e) {
// nothing
}
return true;
}
}
}
Animation listener
the following is a very important component. Without it you will certainly get it to work, but it will work very slowly and your application will probably crash. This is because the Android UI framework is single threaded. No other threads are allowed to touch UI objects. As such, any processing that you need to do as a result of a UI event must therefore be done on the UI thread if it's going to affect any UI objects. In our project this is exactly the case. When you fling left or right, your code tells the flipper to change positions. Then your program needs to load the appropriate page onto the appropriate view. This work is probably very expensive if you have any SpannableStringBuilders or any HTML parsing. This means that the event will fire and all of that processing will be done before the UI changes regardless of where you stick the code. I lost many a sleepless night to this problem, so hopefully you won't have to. Luckily for us, the UI framework offers a few multi-threaded helper functions that allow you to do work outside the main UI thread, and then merge the changes back onto the UI thread. The one that I use is .postDelayed() as seen below. I'm using this particular one because for some odd reason the regular post() method ran my code just a fraction of a second too soon. So use the postDelayed() in this case. you can find documentation on all of these methods in the View object documentation . You will notice that back in our onCreate() method, these two classes were given to the flipper. The flipper fires the onAnimationEnd and then the chapter configuration method runs to guarantee that the Animation runs first -- providing a more seamless user experience.
class ScrollRight implements AnimationListener{
@Override
public void onAnimationEnd(Animation animation) {
flipper.postDelayed(new Runnable(){
@Override
public void run(){
configureChapters(-1);
}
}, 10);
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
}
class ScrollLeft implements AnimationListener{
@Override
public void onAnimationEnd(Animation animation) {
flipper.postDelayed(new Runnable(){
@Override
public void run(){
configureChapters(1);
}
}, 10);
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
}
Maybe the most difficult part about this whole feature is keeping track of what views to load and where. The following is the method I wrote for accomplishing it. The delta value can either be 0,1,or -1 for initial, right, and left movement respectively. The onCreate() method calls this when the activity loads and passes a delta value of 0 so that the initial chapter is fetched and presented and the appropriate previous and next chapters and set up. After this initial load, the ScrollRight and ScrollLeft classes call this method exclusively. It is just a matter of managing which variable points to which textView object. you either need to reset the previous or next textViews and then reset the aliases to reflect your new position. Be careful to do all of this in the correct order though so that you don't create circular references and find some strange things happening in your program.
private void configureChapters(int delta){
if(delta == 0){//this is initial loading value only
String current = getFormattedText(chapterNum);
String previous = "";
if(canFlipLeft()){
previous = getFormattedText(chapterNum - 1);
}
String next = "";
if(canFlipRight()){
next = getFormattedText(chapterNum + 1);
}
text0.setText(current);
text1.setText(next);
text2.setText(previous);
//set aliases
currentTextView = text0;
nextTextView = text1;
previousTextView = text2;
}
if(delta == 1){
int nextChapter = chapterNum +1;
TextView currTemp = currentTextView;
TextView prevTemp = previousTextView;
TextView nextTemp = nextTextView;
chapterNum = nextChapter;
String next = "";
if(canFlipRight()){
next = getFormattedText(chapterNum+1);
}
previousTextView.setText(next);
//reset aliases
previousTextView = currTemp;
currentTextView = nextTemp;
nextTextView = prevTemp;
}
if(delta == -1){
chapterNum = chapterNum - 1;
TextView currTemp = currentTextView;
TextView prevTemp = previousTextView;
TextView nextTemp = nextTextView;
String previous = "";
if(canFlipLeft()){
previous = getFormattedText(chapterNum - 1);
}
nextTextView.setText(previous);
//reselt aliases
currentTextView = prevTemp;
nextTextView = currTemp;
previousTextView = nextTemp;
}
// Set text on nav bar
navText.setText(subdiv);
if (numChapters > 1) {
navText.append(" " + chapterNum);
}
}
And that's all I have. I tried a number of tings including rewriting the Android ScrollView so that it would support horizontal scrolling(which it currently doesn't). But in the end, this was the least complicated and it works extremely fast, just give it a shot. You'll be glad you did. If anyone comes up with a better way, please post a comment and let me know how you did it. Thank you.
Thanks for your blog, i find in a forum the solution for scroll with swipe gesture compatible :
ReplyDelete@Override
public boolean dispatchTouchEvent(MotionEvent ev){
super.dispatchTouchEvent(ev);
return gestureScanner.onTouchEvent(ev);
}
Thx for this very interesting tuto. Was very helpful for me.
ReplyDeleteCan you please post the full source code ?
ReplyDeleteI have implemented a listview where each list item is a flipper. ListView has a array adapter to customize the look and feel of each list item.
I am trying to implement the swipe gesture for each list item, so that when I swipe the list item, only that list item flips to show additional information.
Do you know how that can be achieved ?
Could you post the XML for the animations? slide_left_in, etc.?
ReplyDeleteThis comment has been removed by the author.
ReplyDeletethe tutorial seems gr8 ..
ReplyDeletebut can u provide the source code ..
thanks
I checked this code.. but still Im getting a Null Pointer Exception.Can anyone pls upload a working project for this... Thank You
ReplyDeletei am checking this code but i'm getting ...Runtime exception... can any one give source code of this one..
ReplyDeleteyes i got the solution
ReplyDeletethis one is right as Raphael said, thanks
@Override
public boolean dispatchTouchEvent(MotionEvent ev){
super.dispatchTouchEvent(ev);
return gestureScanner.onTouchEvent(ev);
}
nice article...Thanks
ReplyDeleteJust wondering if you might be able to share your source code? Thanks.
ReplyDeleteToo bad you don't want to share the full source code. Spending more time on completing/fixing your code than on trying to understand your ideas.
ReplyDeleteuseless code , again and again , because not full source code !
ReplyDeleteIts a good explanation and i can easily to understood your information. so thanks for providing this good knowledge about android.
ReplyDeleteAndroid app developer
Come on guys its a good tutorial, you should a least be motivated enough to understand basics to use it. There'd be different ways to implement his code-pieces.
ReplyDeleteThanks for the nice explanation, gonny try this soon :-)
hey..developer can you send me demo file contain this swipe activty..
ReplyDeleteplease mail to my id.
its very helpfulll for make my application.
thank you soo much in advance..
my is is:
shah.jai75@gmail.com
hello friend
ReplyDeletecan u please send me the source code of it at santosh.suchit@gmail.com
Thank you
hello friend
ReplyDeletecan u please send me the source code of it at santosh.suchit@gmail.com
Thank you
A Smartphone has a working framework that gives it a chance to track various provisions. Case in point, Apple's iphone run on ios. Blackberry Smartphones run on the Blackberry OS and different units run Google's Android OS, HP's web OS, and Microsoft's Windows Phone.
ReplyDeleteDevelop Android Apps // Mobile Application Development // Android Application Development
For screen resolutions, this application is great achievement in android app development in which developer easy to implement navigation controls in this app using simple buttons. It is also easy to control screen for users.
ReplyDeleteHi Can anyone tell,how to insert swiping images in gridview so audio has to play correctly.please reply me soon friends am new to android.
ReplyDeleteI require Android application development associations. In the event that you have any thought as for such affiliation that goes on such associations then let me know.
ReplyDeletehttps://seoservices470.wordpress.com/
ReplyDeleteThanks for the nice tutorial. You worked really hard to find the solution for that. But as the time has passed and the Android Studio is updated, many of these functions are out of date.
ReplyDeleteCould you please look at it now and see what the solution could be? I am trying to fix similar problem in my app but no hope. Any help would be appretiated. Thanks in advance for the help.
ReplyDelete"best data collection and responsive blogs. Like it, thanks for sharing."!!
mobile app development for android
frnd in need a frnd in deed, is apt for it bro we are the team of best Mobile App Development company in vizag and also Best Digital Marketing Company in vizag for us it is very helpfull
ReplyDelete
ReplyDeleteOnline Yoga Teacher Training Uttarakhand
Yoga college in Rishikesh Uttarakhand
Yoga Teacher Training in Dehradun
Best Yoga Teacher Training in Uttarakhand
Top Yoga Classes in Haridwar Uttarakhand
Yoga Teacher Training Hours Uttarakhand
Best Yoga Training Centre in Uttarakhand
Best data collective and responsive blog. thanks for sharing
ReplyDeleteAndroid is a mobile operating system based on a modified version of the Linux kernel and other open source software, designed primarily for touchscreen mobile devices such as smartphones and tablets.
ReplyDeleteCustom Web Development | SEO Company Pakistan
Thanks, It helped me a lot. Appreciated!
ReplyDeleteWeb Design Company in Pakistan
Looking for graphic designer do visit the website
ReplyDeleteideahits
Your site is good Actually, i have seen your post and That was very informative and very entertaining for me. joseph sikora power book iv force bomber jacket
ReplyDeleteThis is the most helpful post that focused on the key points about the subject. This valuable content helps to figure out reliable details.
ReplyDeleteNFT Development Services Company in Dubai and UAE
Blockchain Development Services in Dubai and UAE
Blockchain Development Company in Dubai
Thank you so much for sharing this wonderful information. I hope that there’s more information to come.광양콜걸샵추천
ReplyDelete나주콜걸샵추천
목포콜걸샵추천
순천콜걸샵추천
여수콜걸샵추천
충주콜걸샵추천
제천콜걸샵추천