Exploration of Android Art Development 2 --- First Ideas View
Catalogue
2. Fundamentals of View
1. What is View
View is the base class for all controls in all Android s and is an abstraction at the interface level
2.View's position parameters
3.MotionEvent
MotionEvent is a touch screen event. Typical events fall into the following categories:
- ACTION_DOWN: Finger just touched screen
- ACTION_MOVE: Finger moving on screen
- ACTION_UP: The moment your finger is released from the screen
The MotionEvent object gives us the x and y coordinates of the click event.
- getX/getY relative to upper left corner of View
- getRawX/getRawY relative to the upper left corner of the phone screen
How to get MotionEvent:
- Intercept touch events in View or Activity, override onTouchEvent method
- For View, you can also listen for touch events through the setOnTouchListener() method
4.TouchSlop
TouchSlop is the minimum distance that the system can recognize and is considered to be sliding.This is a constant, device dependent, and may be different on different devices.
Get TouchSlop: ViewConfiguration.get(getContext).getScaledTouchSlop() in Java code;
5.VelocityTracker
VelocityTracker is a speed track used to determine the speed at which the final gesture is sliding.Includes both horizontal and vertical speeds.
Use:
//Track the speed of the current event in View's onTouchEvent method
VelocityTracker velocityTracker = VelocityTracker.obtain();
velocityTracker.addMovement(event);
//The parameter 1000 represents the time interval, and the resulting speed represents the size of the pixels that have been scratched in 1,000 milliseconds.
velocityTracker.computeCurrentVelocity(1000);
int xVelocity = (int) velocityTracker.getXVelocity();
int yVelocity = (int) velocityTracker.getYVelocity();
//No, call the clear method to reclaim and reset memory
velocityTracker.clear();
velocityTracker.recycle();
Note: The result is positive in the same direction as the Android axis and negative in the opposite direction
6.GestureDetector
GestureDetector is gesture detection, which assists in detecting user click, slide, long press, double click, etc.
Listener interface inside GestureDetector:
- OnGesture Listener, which listens for gestures such as click, slide, long press, etc.
- OnDoubleTap Listener, which listens for double-click and single-click events.
- OnContextClickListener, right mouse button (add peripherals)
- SimpleOnGestureListener, a class that implements the three interfaces above, has all three callback methods above.
Use:
- Instantiate the GestureDetectorCompat class
- Implement the OnGestureListener/OnGestureListener/SimpleOnGestureListener interface
- OnTouchEvent method to take over the target View
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
GestureDetector mGestureDetector;
GestureDetector.SimpleOnGestureListener mSimpleOnGestureListener = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.d(TAG, "onSingleTapUp: finger(Touch)Send away");
return false;
} //Finger (touch) away
@Override
public void onLongPress(MotionEvent e) { //Long press
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) { //Press and Drag
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) { //Press Touch Long Press and Release
return false;
}
@Override
public void onShowPress(MotionEvent e) { //The moment your finger touches the screen, it's not released yet
}
@Override
public boolean onDown(MotionEvent e) {
return false;
} //The moment your finger touches the screen
@Override
public boolean onDoubleTap(MotionEvent e) {
Log.d(TAG, "onDoubleTap: double-click");
return false;
} //double-click
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
} //A double click occurred and sent away
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
} //Strict Click
@Override
public boolean onContextClick(MotionEvent e) { //Callback when the mouse/touch panel, right-click.
return false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGestureDetector = new GestureDetector(this, mSimpleOnGestureListener); //Example
View view= findViewById(R.id.view);
view.setOnTouchListener(new View.OnTouchListener() { //onTouch Taking Over View
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
});
view.setLongClickable(true);
}
}
3. Slide of View
There are three ways to implement View's sliding:
- Use scrollTo/scrollBy
- Use animation
- Changing layout parameters
1. Use scrollTo/scrollBy
Use:
Call the scrollTo/scrollBy method of the parent container where the control resides
The difference between scrollTo/scrollBy:
- scrollTo is an absolute sliding based on parameters.
- scrollBy is a relative sliding based on parameters.
- Note that both are the contents of the mobile View, not the VIew itself
Implementation of scrollTo/scrollBy in source code:
/**
* Set the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the x position to scroll to
* @param y the y position to scroll to
*/
public void scrollTo(int x, int y) {
if (mScrollX != x || mScrollY != y) {
int oldX = mScrollX;
int oldY = mScrollY;
mScrollX = x;
mScrollY = y;
invalidateParentCaches();
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (!awakenScrollBars()) {
postInvalidateOnAnimation();
}
}
}
/**
* Move the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the amount of pixels to scroll by horizontally
* @param y the amount of pixels to scroll by vertically
*/
public void scrollBy(int x, int y) { //You can see that scrollBy is also implemented by calling scrollBy
scrollTo(mScrollX + x, mScrollY + y);
}
2. Use animation
By using animation, we can also translate a View, mainly by manipulating the translationX and translationY of the View, which can either complement the animation or take attribute animation.
Interstitial animation
//New translate.xml in anim package under layout
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
>
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="300"
android:toYDelta="800"
android:duration="1000"
android:interpolator="@android:anim/linear_interpolator"
/>
</set>
Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate);
layout.setAnimation(animation);
animation.start();
Property Animation
ObjectAnimator.ofFloat(layout,"translationX",0,100).setDuration(1000).start();
It is easy to see from the gif diagram that:
View animation operates on the image of View.That is, View animation does not really change the position of the View.
Attribute animation is really about changing the position of the View, but it started with Android 3.0.
3. Changing layout parameters
Change the layout parameters LayoutParams:
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) layout.getLayoutParams();
params.width+=300;
params.leftMargin+=300;
layout.requestLayout();
4. Comparison of various sliding modes
4. Elastic Sliding
Achieve the elastic sliding of the View, that is, progressive sliding.There are many ways to achieve this, but there is a common idea that divides a large slide into several small slides and completes them in a period of time. Here are the common ways to achieve this.
1. Use Scroller
Use:
- Create Scroller Instance
- Call the startScroll() method to initialize scrolling data and refresh the interface
- Rewrite the computeScroll() method and complete the logic of smooth scrolling within it
//Step One
private Scroller mScroller;
mScroller = new Scroller(context);
// The second step calls the startScroll() method to initialize scrolling data and refresh the interface
mScroller.startScroll(getScrollX(), 0, dx, 0);
@Override
public void computeScroll() {
// Step 3, override the computeScroll() method and complete the logic of smooth scrolling within it
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
}
}
2. By animation
Animation itself is a gradual process, so it can be used to achieve a too natural elastic effect.For example, the code below allows a VIew to move 200 pixels to the right at 100 ms
ObjectAnimator.ofFloat(layout,"translationX",0,200).setDuration(100).start();
3. Use Delay Policy
The core idea of the delay strategy is to achieve an incremental effect by sending a series of delay messages, using either the Handler, View's PostDelayed method, or the thread's sleep method.
In the case of Handled, the code below moves the contents of the VIew 100 pixels to the left.
private static final int MESSAGE_SCROLL_TO = 1;
private static final int FRAME_COUNT = 30;
private static final int DELAYED_TIME = 33;
private int mCount;
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_SCROLL_TO: {
mCount++;
if (mCount <= FRAME_COUNT) {
float fraction = mCount / (float) FRAME_COUNT;
int scrollX = (int) (fraction * 100);
Button mButton;
mButton.scrollTo(scrollX,0);
mHandler.sendEmptyMessageDelayed(MESSAGE_SCROLL_TO,DELAYED_TIME);
}
break;
}
default:
break;
}
}
};
5. References
Exploration of Android Art Development
Notes on the Exploration of Android Development Art - View (1)
Android Gesture Detection-GestureDetector Comprehensive Analysis
Android Scroller completely parses everything you need to know about Scroller