Android uses the UC browser to scroll up and down (with source code) and androiduc
Original works of Lin bingwen Evankaka. Reprinted please indicate the source http://blog.csdn.net/evankaka
In this article, a text box is added to the right of the slide menu, and the text can be swiped up or down and the left and right sides of the menu can be rolled. We recommend that you take a good look at the android touch event distribution mechanism. I will not go into details here. I will only talk about this application. The functions to be implemented are like rolling the left and right of the UC browser (or other mobile browsers), switching the webpage, scrolling up and down, and dragging the content.
Directory:
I. Functional requirements and implementation
Ii. layout and code
Iii. Principles and instructions
Effect of this article:
(Free source code download)
I. Functional requirements and implementation
1. Functional requirements:
(1) When you start to move your fingers around the screen, you can only scroll the menu between the left and right. If your fingers keep pressing and move up and down, the display of the Menu remains unchanged, but the text box is not moved up or down!
(2) When you start to move your finger up or down the screen, you can only scroll up or down the text box. If your finger is pressed all the time, and the left and right are moved, the display part of the text box remains unchanged, but the menu is not left or right!
2. Initial implementation:
In the previous article, add a listview for the menu item on the left, add a textview for the content item on the right, and add a scrollview to textview to enable it to scroll up and down.
This effect is definitely not correct. You see, when we move the text with our fingers up and down, if we move the left and right, the menu is displayed.
3. Modification implementation
Now I want to start with the distribution of touch events, because I registered the touch events of ScrollView to LinearLayout. (LinearLayout contains ScrollView, do not understand the following layout), so the touch event is first passed to LinearLayout.
There are two situations:
(1) If the finger moves left or right, the touch event is sent to LinearLayout. The onTouch function returns true, indicating that the touch event is no longer transmitted, and the ScrollView cannot be moved.
(2) If the finger moves up or down, the touch event is first transmitted to LinearLayout, but LinearLayout does not process it. It is directly transmitted to ScrollView and ScrollView to process the touch event.
This is the modified effect:
Ii. layout and code
1. Layout
<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: tools = "http://schemas.android.com/tools" android: id = "@ + id/layout" android: layout_width = "match_parent" android: layout_height = "match_parent" android: orientation = "horizontal" tools: context = ". mainActivity "> <LinearLayout android: id =" @ + id/menu "android: layout_width =" match_parent "android: layout_height =" match_parent "android: Orientation = "vertical" android: background = "@ drawable/menu"> <! -- Add a ListView control --> <ListView android: id = "@ + id/menuList" android: layout_width = "fill_parent" android: layout_height = "fill_parent"/> </LinearLayout> <LinearLayout android: id = "@ + id/content" android: layout_width = "match_parent" android: layout_height = "match_parent" android: orientation = "vertical"> <ScrollView android: id = "@ + id/scrollview" android: layout_width = "fill_parent" android: layout_height = "wrap_content"> <TextView android: id = "@ + id/content_text" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: text = "@ string/text1" android: textSize = "22px"/> </ScrollView> </LinearLayout>
2. Code
/*** @ Author Lin bingwen * @ 2015.2.17 */package com. example. learningjava; import java. util. arrayList; import java. util. hashMap; import java. util. map; import com. example. learningjava. r. string; import android. r. integer; import android. r. menu; import android. OS. asyncTask; import android. OS. build; import android. OS. bundle; import android. annotation. suppressLint; import android. annotation. targetApi; import android. widget. A DapterView; import android. widget. adapterView. onItemClickListener; import android. widget. arrayAdapter; import android. widget. linearLayout. layoutParams; import android. widget. listView; import android. widget. scrollView; import android. widget. toast; import android. app. activity; import android. content. context; import android. util. attributeSet; import android. util. displayMetrics; import android. util. log; import Droid. view. gestureDetector; import android. view. menu; import android. view. motionEvent; import android. view. velocityTracker; import android. view. view; import android. view. view. onTouchListener; import android. view. window; import android. widget. linearLayout; public class MainActivity extends Activity implements OnTouchListener {private LinearLayout menuLayout; // menu item private LinearLayout contentLayout; // content item priva Te LayoutParams menuParams; // menu item parameter private LayoutParams contentParams; // The width value of the contentLayout parameter of the content item is private int disPlayWidth; // the screen resolution of the mobile phone is private float xDown; // The horizontal private float xMove when the finger points down; // The horizontal private float xUp when the finger moves down; // record the horizontal private float yDown when the finger moves down; // The ordinate private float yMove of the finger down; // The ordinate private VelocityTracker mVelocityTracker of the finger moving; // It is used to calculate the Sliding Speed of the finger. Private float velocityX; // the speed at which the left and right fingers move. public static final int SNAP_VELOCITY = 400; // the speed at which the fingers slide to display and hide the menu. Private boolean menuIsShow = false; // The initialization menu item cannot contain private static final int menuPadding = 160; // The menu is displayed, leaving the width of the content to private ListView menuListView; // The content of the menu list is private ScrollView scrollView; // the scroll bar of the text box is private boolean wantToScrollText = false; // You Want To scroll down the text content private boolean wantToScrollTextMenu = false; private boolean oneFucction = false; // ensure that the function is called only once protected void onCreate (Bundle savedInstanceState) {super. onCreate (sa VedInstanceState); requestWindowFeature (Window. FEATURE_NO_TITLE); setContentView (R. layout. activity_main); initLayoutParams (); initMenuList (); initScrollView ();}/*** initialize Layout and set its corresponding parameter */private void initLayoutParams () {// obtain the screen size DisplayMetrics dm = new DisplayMetrics (); getWindowManager (). getdefadisplay display (). getMetrics (dm); disPlayWidth = dm. widthPixels; // obtain the control menuLayout = (LinearLayout) findVi. EwById (R. id. menu); contentLayout = (LinearLayout) findViewById (R. id. content); findViewById (R. id. layout ). setOnTouchListener (this); // obtain the control parameter menuParams = (LinearLayout. layoutParams) menuLayout. getLayoutParams (); contentParams = (LinearLayout. layoutParams) contentLayout. getLayoutParams (); // initialize the width and margin menuParams of the menu and content. width = disPlayWidth-menuPadding; menuParams. leftMargin = 0-menuParams. width; content Params. width = disPlayWidth; contentParams. leftMargin = 0; // set the parameter menuLayout. setLayoutParams (menuParams); contentLayout. setLayoutParams (contentParams);}/*** initialize menu list content */private void initMenuList () {final String [] strs = new String [] {"Chapter 1st Java overview ", "Chapter 2nd understanding Object-Oriented", "Chapter 3rd data types and operators", "Chapter 4th Process Control and array", "Chapter 5th object-oriented (I )"}; menuListView = (ListView) findViewById (R. id. menuList); menuListView. setAdapter (new Arr AyAdapter <String> (this, android. r. layout. simple_list_item_1, strs); // bind an adapter to the ListView // start list click the listener event menuListView. setOnItemClickListener (new OnItemClickListener () {@ Overridepublic void onItemClick (AdapterView <?> Arg0, View arg1, int arg2, long arg3) {Toast. makeText (getApplicationContext (), "you selected" + strs [arg2], Toast. LENGTH_SHORT ). show () ;}}) ;}/ *** initialize scrollView */public void initScrollView () {scrollView = (ScrollView) this. findViewById (R. id. scrollview); scrollView. setOnTouchListener (this); // bind the View that listens to the slide event. That is, only the bound View slides to display and hide the left layout. This sentence is very important. Do not set its touch events. Do not swallow the layout touch events} @ Override public boolean onTouch (View v, MotionEvent event) {acquireVelocityTracker (event ); if (event. getAction () = MotionEvent. ACTION_DOWN) {xDown = event. getRawX (); yDown = event. getRawY (); return false;} else if (event. getAction () = MotionEvent. ACTION_MOVE) {if (wantToScrollText) // you can scroll to display the text. return false; xMove = event. getRawX (); yMove = event. getRawY (); if (menuIsShow) {IsScrollToShowMenu (); return true;} if (! OneFucction) {oneFucction = true; // This if can only be called once if (Math. abs (xDown-xMove) <Math. abs (yDown-yMove) {wantToScrollText = true; return false ;}} isScrollToShowMenu () ;} else if (event. getAction () = MotionEvent. ACTION_UP) {oneFucction = false; if (wantToScrollText) {wantToScrollText = false; return false;} xUp = event. getRawX (); isShowMenu (); releaseVelocityTracker ();} else if (event. getAction () = MotionEvent. ACT ION_CANCEL) {releaseVelocityTracker (); return false;} return true; // when false, the touch event can be sent to scroll}/*** based on the distance of the finger press, determines whether to scroll the display menu */private void isScrollToShowMenu () {int distanceX = (int) (xMove-xDown); if (! MenuIsShow) {scrollToShowMenu (distanceX);} else {scrollToHideMenu (distanceX) ;}/ *** raise your finger and determine whether to display the menu */private void isShowMenu () {velocityX = getScrollVelocity (); if (wantToShowMenu () {if (shouldShowMenu () {showMenu ();} else {hideMenu ();}} else if (wantToHideMenu () {if (shouldHideMenu () {hideMenu () ;}else {showMenu () ;}}/*** you want to display the menu, when the distance to the right is greater than 0 and the menu is invisible */private boolean wantToShowMenu () {r Eturn! MenuIsShow & xUp-xDown> 0;}/*** to hide the menu, when the distance to the left is greater than 0 and the menu is visible */private boolean wantToHideMenu () {return menuIsShow & xDown-xUp> 0;}/*** determines that the menu should be displayed, when the distance to the right is more than half of the menu or the speed exceeds the given value */private boolean shouldShowMenu () {return xUp-xDown> menuParams. width/2 | velocityX> SNAP_VELOCITY;}/*** determine whether the menu should be hidden, when the distance to the left is more than half of the menu or the speed exceeds the given value */private boolean shouldHideMenu () {return xDown-xUp> menuParams. width/2 | velocityX> SNAP_VELOCI TY;}/*** display menu bar */private void showMenu () {new showmenuasynctask(.exe cute (50); menuIsShow = true ;} /*** hide the menu bar */private void hideMenu () {new showmenuasynctask(cmd.exe cute (-50); menuIsShow = false;}/*** when the pointer is pressed, scroll to display the menu slowly * @ param scrollX the distance between each scroll movement */private void scrollToShowMenu (int scrollX) {if (scrollX> 0 & scrollX <= menuParams. width) menuParams. leftMargin =-menuParams. width + scrollX; menuLayou T. setLayoutParams (menuParams);}/*** when the pointer is pressed, scroll to gradually hide the menu * @ param scrollX the distance from each scroll */private void scrollToHideMenu (int scrollX) {if (scrollX> =-menuParams. width & scrollX <0) menuParams. leftMargin = scrollX; menuLayout. setLayoutParams (menuParams);}/*** create a VelocityTracker object and add the sliding event of the touch content interface to VelocityTracker. * @ Param event add MotionEvent */private void acquireVelocityTracker (final MotionEvent event) {if (null = mVelocityTracker) {mVelocityTracker = VelocityTracker. obtain ();} mVelocityTracker. addMovement (event);}/*** get the speed at which the finger slides on the content interface. * @ Return sliding speed, in the unit of how many pixels are moved per second. */Private int getScrollVelocity () {mVelocityTracker. computeCurrentVelocity (1000); int velocity = (int) mVelocityTracker. getXVelocity (); return Math. abs (velocity);}/*** release VelocityTracker */private void releaseVelocityTracker () {if (null! = MVelocityTracker) {mVelocityTracker. clear (); mVelocityTracker. recycle (); mVelocityTracker = null; }}/ *****: simulates the animation process to show the scrolling effect to the naked eye. **/class showMenuAsyncTask extends AsyncTask <Integer, Integer, integer >{@ Override protected Integer doInBackground (Integer... params) {int leftMargin = menuParams. leftMargin; while (true) {// scroll the interface based on the input speed. When the scroll reaches the Left or Right boundary, it jumps out of the loop. LeftMargin + = params [0]; if (params [0]> 0 & leftMargin> 0) {leftMargin = 0; break ;} else if (params [0] <0 & leftMargin <-menuParams. width) {leftMargin =-menuParams. width; break;} publishProgress (leftMargin); try {Thread. sleep (40); // sleep, visible to the naked eye} catch (InterruptedException e) {e. printStackTrace () ;}} return leftMargin;} @ Override protected void onProgressUpdate (Integer... value) {menuParams. leftMargin = value [0]; menuLayout. setLayoutParams (menuParams);} @ Override protected void onPostExecute (Integer result) {menuParams. leftMargin = result; menuLayout. setLayoutParams (menuParams );}}}
Iii. Principles and instructions
Principle:
1. register the ScrollView touch event to LinearLayout. (LinearLayout contains ScrollView, which does not understand the layout)
2. First, determine whether the gesture is intended to be left or right or up or down. If it is left or right motion, LinearLayout gets the touch event, that is, the OnTouch function returns true. If you want to move up or down, that is, the OnTouch function returns false;
What do you mean when a gesture is judged only once? That is to say, you press it 1st times until you press it all the time, and only judge the movement you Want to do once.
3. After the finger leaves the screen, all parameters are restored.
(Free source code download)
Original works of Lin bingwen Evankaka. Reprinted please indicate the source http://blog.csdn.net/evankaka