📜 ⬆️ ⬇️

Sliding screens inside the app



Hello!

Modern mobile devices are primarily focused on the management of fingers, in particular gestures and touches. This feature adds specificity to the organization of user interfaces. Intuitively understandable solutions come to the main role, they require the least effort from the user and at the same time are unobtrusive, preserving the maximum of useful space, i.e. no cluttering user interface.
')
An example of such solutions is switching between the working screens in Android, where to move from one screen to another, just make a gesture to the right or left. On the possible implementation of such a decision and will be discussed in this post.

Instead of intro


In order to illustrate, then what will be discussed further, and thereby add clarity, I recorded a small video of the application, which I will do today:



In the above application, there are four unrelated View , moving between them by gestures to the right / left across the screen. The contents of the View could be arbitrary, but for simplicity, I made them colored and numbered.

This functionality is not basic, i.e. does not have a completely ready built-in solution. And also, oddly enough, is not very common, and, probably, because of this is not covered in the Internet sufficiently.

Development


To implement the above application, you must perform the following steps:
  1. Find or implement a container for convenient storage and movement between the view.
  2. Intercept user gestures and, based on the information received, conclude which way to “move” view
  3. Add animation to visualize the movement between the screens.
Fortunately, the container that meets our requirements is already in the Android arsenal, it is called ViewFlipper . Create an empty project and add the ViewFlipper element to the main layout :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_layout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ViewFlipper android:id="@+id/flipper" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </LinearLayout> 

Now we will create four views between which we will move, in my example they look like:
 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@android:color/white" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:text="1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_centerInParent="true" android:textSize="140px" android:textStyle="bold"/> </RelativeLayout> 

Next, you need to link the available view with the ViewFlipper. To do this, in the OnCreate method of the base Activity, add the following code:
 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //  listener ,     LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main_layout); mainLayout.setOnTouchListener(this); //   ViewFlipper flipper = (ViewFlipper) findViewById(R.id.flipper); //  View       flipper LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); int layouts[] = new int[]{ R.layout.first, R.layout.second, R.layout.third, R.layout.fourth }; for (int layout : layouts) flipper.addView(inflater.inflate(layout, null)); } 

Now we can navigate between view calls to the showNext () and showPrevious () methods of the flipper object.

User gestures trigger OnTouch events; to handle these events, you need to implement a method:
 boolean onTouch(View view, MotionEvent event) 

In this method, in the object of the MotionEvent class, there is all the necessary information and the executed gesture.

Because we need to understand where the gesture was done to the right or left, then we will act very simply: save the coordinate along the X axis when you click on the screen, and compare it with the coordinate after the screen is released. If the original value is greater, then this movement is to the left, otherwise to the right. The code looks quite simple:
 public boolean onTouch(View view, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //    , ..   // fromPosition -    X    fromPosition = event.getX(); break; case MotionEvent.ACTION_UP: //   , ..   float toPosition = event.getX(); if (fromPosition > toPosition) flipper.showNext(); else if (fromPosition < toPosition) flipper.showPrevious(); default: break; } return true; } 

It remains to add animation. ViewFlipper, like all descendants of ViewAnimator, supports methods: setInAnimation (...) and setOutAnimation (...) , through which you can set animations ( Animation ) for entering the view on the screen and disappearing the view from the screen. But since Our animation will differ depending on the gestures, then you have to specify it again each time, based on the current operation. Those. the onTouch method needs to be modified as follows:
 ... if (fromPosition > toPosition) { flipper.setInAnimation(AnimationUtils.loadAnimation(this,R.anim.go_next_in)); flipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.go_next_out)); flipper.showNext(); } else if (fromPosition < toPosition) { flipper.setInAnimation(AnimationUtils.loadAnimation(this,R.anim.go_prev_in)); flipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.go_prev_out)); flipper.showPrevious(); } ... 

Where R.anim. * Resources with the appearance and disappearance animation view. I will not give all four options; I will give only the first one (all the rest will be shown in the example project, which I will attach to the post):
 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="400"/> <alpha android:fromAlpha="1.0" android:toAlpha="1.0" android:duration="400" /> </set> 

All is ready! An example project can be downloaded from here .

UPD. ViewFlipper option without releasing the finger (changing the onTouch method):
 ... //  ACTION_UP case MotionEvent.ACTION_MOVE: float toPosition = event.getX(); // MOVE_LENGTH -    X,      .  //     MOVE_LENGTH = 150 if ((fromPosition - MOVE_LENGTH) > toPosition) { fromPosition = toPosition; flipper.setInAnimation(AnimationUtils.loadAnimation(this,R.anim.go_next_in)); flipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.go_next_out)); flipper.showNext(); } else if ((fromPosition + MOVE_LENGTH) < toPosition) { fromPosition = toPosition; flipper.setInAnimation(AnimationUtils.loadAnimation(this,R.anim.go_prev_in)); flipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.go_prev_out)); flipper.showPrevious(); } ... 

UPD 2. If you prefer sliding with a preview of the next page, then you can look at solutions without ViewFlipper, based on ViewGroup and scrollTo , an example can be found, for example, here .

Conclusion


The main advantage of sliding'a, if properly used: unloading the user interface from redundant controls. As you can see, the implementation turned out to be simple, and the use of such a functional is truly wide.

But the fly in the ointment is still present. First, if you look at my example for the first time, it is almost impossible to guess that there is sliding (this is an example and I did not set such a task here), and therefore the use of sliding requires other UI solutions explaining the presence of this Sliding, for example, on the same Android home screens there is a “slider-indicator” showing which screen the user is in at the moment. Secondly, if there are controls on the view that have their own response to clicks, scrolling, etc., the onTouch method call inside the ViewFlipper will be blocked by its earlier interception inside the child view, so you will have to worry about forwarding this event. up "to the ViewFlipper.

Source: https://habr.com/ru/post/118482/


All Articles