Implementation of sliding effect based on Android novel Reader

Source: Internet
Author: User

Implementation of sliding effect based on Android novel Reader

I have read novels and I know that the page flip function of a novel reader has a variety of effects, such as simulation pages, sliding pages, and so on. For some reason, I suddenly want to write a simple sliding flip effect. There is no intention to write it here. I hope you can write other effects based on this effect. The graph will not be available.

The following is the code: You can understand the onTouch event.

Package com. example. testscroll. view; import android. content. context; import android. util. attributeSet; import android. view. motionEvent; import android. view. velocityTracker; import android. view. view; import android. view. viewConfiguration; import android. view. viewGroup; import android. widget. scroller; public class FlipperLayout extends ViewGroup {private Scroller mScroller; private VelocityTracker mVelocityTra Cker; private int mVelocityValue = 0;/** determine whether the sliding distance is valid */private int limitDistance = 0; private int screenWidth = 0; /** finger movement direction */private static final int MOVE_TO_LEFT = 0; private static final int MOVE_TO_RIGHT = 1; private static final int MOVE_NO_RESULT = 2; /** result direction of the last touch */private int mTouchResult = MOVE_NO_RESULT;/** start direction */private int mDirection = MOVE_NO_RESULT; /** touch mode */private static final Int MODE_NONE = 0; private static final int MODE_MOVE = 1; private int mMode = MODE_NONE;/** sliding view */private View mScrollerView = null; /** Top view (on the edge, invisible) */private View currentTopView = null;/** view displayed, display on the screen */private View currentShowView = null;/** bottom view (invisible) */private View currentBottomView = null; public FlipperLayout (Context context) {super (context); init (context);} public FlipperLayo Ut (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); init (context);} public FlipperLayout (Context context, AttributeSet attrs) {super (context, attrs); init (context);} private void init (Context context) {mScroller = new Scroller (context); screenWidth = context. getResources (). getDisplayMetrics (). widthPixels; limitDistance = screenWidth/3;}/***** @ param listener * @ pa Ram currentBottomView * is the bottom-layer view. The * @ param currentShowView * display View * @ param currentTopView * is not displayed in the initial state, slip out of the screen */public void initFlipperViews (TouchListener listener, View currentBottomView, View currentShowView, View currentTopView) {this. currentBottomView = currentBottomView; this. currentShowView = currentShowView; this. currentTopView = currentTopView; setTouchResultListener (listener); add View (currentBottomView); addView (currentShowView); addView (currentTopView);/** the edge of the top view sliding by default (used to View the previous page) */currentTopView. scrollTo (-screenWidth, 0) ;}@ Overrideprotected void onLayout (boolean changed, int l, int t, int r, int B) {for (int I = 0; I <getChildCount (); I ++) {View child = getChildAt (I); int height = child. getMeasuredHeight (); int width = child. getMeasuredWidth (); child. layout (0, 0, width, he Ight) ;}@ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec. getSize (widthMeasureSpec); int height = MeasureSpec. getSize (heightMeasureSpec); setMeasuredDimension (width, height); for (int I = 0; I <getChildCount (); I ++) {getChildAt (I ). measure (widthMeasureSpec, heightMeasureSpec);} private int start X = 0; @ Overridepublic boolean dispatchTouchEvent (MotionEvent ev) {switch (ev. getAction () {case MotionEvent. ACTION_DOWN: if (! MScroller. isFinished () {break;} startX = (int) ev. getX (); break;} return super. dispatchTouchEvent (ev) ;}@ SuppressWarnings ("deprecation") @ Overridepublic boolean onTouchEvent (MotionEvent event) {obtainVelocityTracker (event); switch (event. getAction () {case MotionEvent. ACTION_MOVE: if (! MScroller. isFinished () {return super. onTouchEvent (event);} if (startX = 0) {startX = (int) event. getX ();} final int distance = startX-(int) event. getX (); if (mDirection = MOVE_NO_RESULT) {if (mListener. whetherHasNextPage () & distance> 0) {mDirection = MOVE_TO_LEFT;} else if (mListener. whetherHasPreviousPage () & distance <0) {mDirection = MOVE_TO_RIGHT ;}} if (mMode = MODE_NONE & (mDirection = = MOVE_TO_LEFT & mListener. whetherHasNextPage () | (mDirection = MOVE_TO_RIGHT & mListener. whetherHasPreviousPage () {mMode = MODE_MOVE;} if (mMode = MODE_MOVE) {if (mDirection = MOVE_TO_LEFT & distance <= 0) | (mDirection = MOVE_TO_RIGHT & distance> = 0) {mMode = MODE_NONE ;}} if (mDirection! = MOVE_NO_RESULT) {if (mDirection = MOVE_TO_LEFT) {if (mScrollerView! = CurrentShowView) {mScrollerView = currentShowView;} else {if (mScrollerView! = CurrentTopView) {mScrollerView = currentTopView;} if (mMode = MODE_MOVE) {mVelocityTracker. computeCurrentVelocity (1000, ViewConfiguration. getMaximumFlingVelocity (); if (mDirection = MOVE_TO_LEFT) {mScrollerView. scrollTo (distance, 0);} else {mScrollerView. scrollTo (screenWidth + distance, 0) ;}} else {final int scrollX = mScrollerView. getScrollX (); if (mDirection = MOVE_TO_LEFT & scrollX! = 0 & mListener. whetherHasNextPage () {mScrollerView. scrollTo (0, 0);} else if (mDirection = MOVE_TO_RIGHT & mListener. whetherHasPreviousPage () & screenWidth! = Math. abs (scrollX) {mScrollerView. scrollTo (-screenWidth, 0) ;}} break; case MotionEvent. ACTION_UP: if (mScrollerView = null) {return super. onTouchEvent (event);} final int scrollX = mScrollerView. getScrollX (); mVelocityValue = (int) mVelocityTracker. getXVelocity (); // scroll left positive, right negative (), (startX + dx) if the value is 0, that is, reset/** android. widget. scroller. startScroll (int startX, int startY, int * dx, int dy, int duration) */Int time = 500; if (mMode = MODE_MOVE & mDirection = MOVE_TO_LEFT) {if (scrollX> limitDistance | mVelocityValue <-time) {// move your finger to the left. You can flip the screen to mTouchResult = MOVE_TO_LEFT; if (mVelocityValue <-time) {time = 200;} mScroller. startScroll (scrollX, 0, screenWidth-scrollX, 0, time);} else {mTouchResult = MOVE_NO_RESULT; mScroller. startScroll (scrollX, 0,-scrollX, 0, time) ;}} else if (mMode = MODE_MOVE & MDirection = MOVE_TO_RIGHT) {if (screenWidth-scrollX)> limitDistance | mVelocityValue> time) {// move your finger to the right and you can flip the screen to mTouchResult = MOVE_TO_RIGHT; if (mVelocityValue> time) {time = 250;} mScroller. startScroll (scrollX, 0,-scrollX, 0, time);} else {mTouchResult = MOVE_NO_RESULT; mScroller. startScroll (scrollX, 0, screenWidth-scrollX, 0, time) ;}} resetVariables (); postInvalidate (); break;} return true;} Private void resetVariables () {mDirection = MOVE_NO_RESULT; mMode = MODE_NONE; startX = 0; random ();} private TouchListener mListener; private void setTouchResultListener (TouchListener listener) {this. mListener = listener;} @ Overridepublic void computeScroll () {super. computeScroll (); if (mScroller. computescroloffset () {mScrollerView. scrollTo (mScroller. getCurrX (), mScroller. getCurrY ()); PostInvalidate ();} else if (mScroller. isFinished () & mListener! = Null & mTouchResult! = MOVE_NO_RESULT) {if (mTouchResult = MOVE_TO_LEFT) {if (currentTopView! = Null) {removeView (currentTopView);} currentTopView = mScrollerView; currentShowView = currentBottomView; if (mListener. currentIsLastPage () {final View newView = mListener. createView (mTouchResult); currentBottomView = newView; addView (newView, 0);} else {currentBottomView = new View (getContext (); currentBottomView. setVisibility (View. GONE); addView (currentBottomView, 0) ;}} else {if (currentBottomView! = Null) {removeView (currentBottomView);} currentBottomView = currentShowView; currentShowView = mScrollerView; if (mListener. currentIsFirstPage () {final View newView = mListener. createView (mTouchResult); currentTopView = newView; currentTopView. scrollTo (-screenWidth, 0); addView (currentTopView);} else {currentTopView = new View (getContext (); currentTopView. scrollTo (-screenWidth, 0); currentTopView. setVis Ibility (View. GONE); addView (currentTopView) ;}} mTouchResult = MOVE_NO_RESULT;} private void locate (MotionEvent event) {if (mVelocityTracker = null) {mVelocityTracker = VelocityTracker. obtain ();} mVelocityTracker. addMovement (event);} private void releaseVelocityTracker () {if (mVelocityTracker! = Null) {mVelocityTracker. recycle (); mVelocityTracker = null;}/*** used for real-time callback of touch events ** @ author freeson */public interface TouchListener {/** swipe your finger to the left, view the next section */final int MOVE_TO_LEFT = 0;/** move your finger to the right to view the previous section */final int MOVE_TO_RIGHT = 1; /*** create a View that carries Text ** @ param direction * {@ link MOVE_TO_LEFT, MOVE_TO_RIGHT} * @ return */public View createView (final int direction ); /***** whether the current page is the first page ** @ return */public boolean currentIsFirstPage (); /***** whether the current page is the last page ** @ return */public boolean currentIsLastPage ();/*** whether the current page has a previous page (used to determine whether the page is slidable) ** @ return */public boolean whetherHasPreviousPage ();/*** determines whether the current page has a next page (used to determine whether it is slidable) ** @ return */public boolean whetherHasNextPage ();}}

Activity Test file:

package com.example.testscroll;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import android.app.Activity;import android.content.res.AssetManager;import android.os.Bundle;import android.os.Handler;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.widget.TextView;import com.example.testscroll.view.FlipperLayout;import com.example.testscroll.view.FlipperLayout.TouchListener;import com.example.testscrollactivity.R;public class MainActivity extends Activity implements OnClickListener, TouchListener {private String text = "";private int textLenght = 0;private static final int COUNT = 400;private int currentTopEndIndex = 0;private int currentShowEndIndex = 0;private int currentBottomEndIndex = 0;private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {FlipperLayout rootLayout = (FlipperLayout) findViewById(R.id.container);View recoverView = LayoutInflater.from(MainActivity.this).inflate(R.layout.view_new, null);View view1 = LayoutInflater.from(MainActivity.this).inflate(R.layout.view_new, null);View view2 = LayoutInflater.from(MainActivity.this).inflate(R.layout.view_new, null);rootLayout.initFlipperViews(MainActivity.this, view2, view1, recoverView);textLenght = text.length();System.out.println("----textLenght----->" + textLenght);TextView textView = (TextView) view1.findViewById(R.id.textview);if (textLenght > COUNT) {textView.setText(text.subSequence(0, COUNT));textView = (TextView) view2.findViewById(R.id.textview);if (textLenght > (COUNT << 1)) {textView.setText(text.subSequence(COUNT, COUNT * 2));currentShowEndIndex = COUNT;currentBottomEndIndex = COUNT << 1;} else {textView.setText(text.subSequence(COUNT, textLenght));currentShowEndIndex = textLenght;currentBottomEndIndex = textLenght;}} else {textView.setText(text.subSequence(0, textLenght));currentShowEndIndex = textLenght;currentBottomEndIndex = textLenght;}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);new ReadingThread().start();}@Overridepublic void onClick(View v) {}@Overridepublic View createView(final int direction) {String txt = "";if (direction == TouchListener.MOVE_TO_LEFT) {currentTopEndIndex = currentShowEndIndex;final int nextIndex = currentBottomEndIndex + COUNT;currentShowEndIndex = currentBottomEndIndex;if (textLenght > nextIndex) {txt = text.substring(currentBottomEndIndex, nextIndex);currentBottomEndIndex = nextIndex;} else {txt = text.substring(currentBottomEndIndex, textLenght);currentBottomEndIndex = textLenght;}} else {currentBottomEndIndex = currentShowEndIndex;currentShowEndIndex = currentTopEndIndex;currentTopEndIndex = currentTopEndIndex - COUNT;txt = text.substring(currentTopEndIndex - COUNT, currentTopEndIndex);}View view = LayoutInflater.from(this).inflate(R.layout.view_new, null);TextView textView = (TextView) view.findViewById(R.id.textview);textView.setText(txt);System.out.println("-top->" + currentTopEndIndex + "-show->" + currentShowEndIndex + "--bottom-->" + currentBottomEndIndex);return view;}@Overridepublic boolean whetherHasPreviousPage() {return currentShowEndIndex > COUNT;}@Overridepublic boolean whetherHasNextPage() {return currentShowEndIndex < textLenght;}@Overridepublic boolean currentIsFirstPage() {boolean should = currentTopEndIndex > COUNT;if (!should) {currentBottomEndIndex = currentShowEndIndex;currentShowEndIndex = currentTopEndIndex;currentTopEndIndex = currentTopEndIndex - COUNT;}return should;}@Overridepublic boolean currentIsLastPage() {boolean should = currentBottomEndIndex < textLenght;if (!should) {currentTopEndIndex = currentShowEndIndex;final int nextIndex = currentBottomEndIndex + COUNT;currentShowEndIndex = currentBottomEndIndex;if (textLenght > nextIndex) {currentBottomEndIndex = nextIndex;} else {currentBottomEndIndex = textLenght;}}return should;}private class ReadingThread extends Thread {public void run() {AssetManager am = getAssets();InputStream response;try {response = am.open("text.txt");if (response != null) {ByteArrayOutputStream baos = new ByteArrayOutputStream();int i = -1;while ((i = response.read()) != -1) {baos.write(i);}text = new String(baos.toByteArray(), "UTF-8");baos.close();response.close();handler.sendEmptyMessage(0);}} catch (IOException e) {e.printStackTrace();}}}}

Xml layout file:

 
     
      
  
 

Activity layout file:

 

Note: Why is a rate calculator added above? In fact, it is only to identify whether this action is a fast moving action, even if the sliding distance is less than 1/3 of the screen, however, as long as the speed is met, it can be determined that sliding is a flip action.

Note: This is only one of the slides, not the logic of the novels. Although it is a bit rough, there are still some things worth learning. If you have any good solutions, we can discuss them together.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.