This example involves the following knowledge points:
1) Use of the attrs. xml file
2) gesturedetector. ongesturelistener listens for gestures
3) Use of onlayout (), onmeasure (), and ontouchevent ()
Next, let's talk about my Implementation ideas:
1) each desktop is a large component and horizontally arranged in a linear layout file. Each desktop is suitable for the same screen size. Therefore, we need to expand linearlayout and rewrite the onmeasure () and onlayout () methods.
2) To slide with gestures, you only need to implement the ondown () and onscroll () methods in the gesturedetector. ongesturelistener interface.
3) To receive touch-screen events, you must implement ontouchevent ()
Let's take a look at the Code:
- Public class scrolllayout extends linearlayout implements gesturedetector. ongesturelistener {
- Private int offset; // relative distance
- Private gesturedetector; // gesture event
- Private int childwidth; // The width of the sub-View
- Private int childcount; // Number of subviews
- Private int defaultwindow; // default window
- Private Boolean setsharewindowflag = false; // ensure that the default window settings are executed only once.
- Public scrolllayout (context ){
- Super (context );
- Init ();
- }
- Public scrolllayout (context, attributeset attrs ){
- Super (context, attrs );
- Init ();
- // Obtain the defined defaultwindow Value
- Typedarray = context. obtainstyledattributes (attrs, R. styleable. myscrollwindow );
- Defaultwindow = typedarray. getinteger (R. styleable. myscrollwindow_defaultwindow, 0 );
- }
- Private void Init (){
- Gesturedetector = new gesturedetector (this. getcontext (), this );
- }
- // A gesture event can be triggered only when the returned value is true.
- Public Boolean ondown (motionevent e ){
- Return true;
- }
- Public void onshowpress (motionevent e ){}
- Public Boolean onsingletapup (motionevent e ){
- Return false;
- }
- // Slide along the gesture
- Public Boolean onscroll (motionevent E1, motionevent E2, float distancex, float distancey ){
- // Obtain the sliding distance
- Offset = (INT) (offset-distancex );
- // Prevents sliding out of the Boundary
- If (Offset> 0 ){
- Offset = 0;
- } Else if (offset <-1 * childwidth * (childCount-1 )){
- Offset =-1 * childwidth * (childCount-1 );
- }
- // Redraw the Layout
- Requestlayout ();
- Return true;
- }
- Public void onlongpress (motionevent e ){
- }
- Public Boolean onfling (motionevent E1, motionevent E2, float velocityx, float velocityy ){
- Return false;
- }
- // Set the layout file width and height to the width and height of each desktop
- @ Override
- Protected void onmeasure (INT widthmeasurespec, int heightmeasurespec ){
- Super. onmeasure (widthmeasurespec, heightmeasurespec );
- // Set the same width and height for each desktop and Screen
- Int childcount = getchildcount ();
- For (INT I = 0; I <childcount; I ++ ){
- Getchildat (I). Measure (widthmeasurespec, heightmeasurespec );
- }
- }
- // Set the Layout
- @ Override
- Protected void onlayout (Boolean changed, int L, int T, int R, int B ){
- Childcount = getchildcount (); // gets the number of child views
- Childwidth = childcount> 0? Getchildat (0). getmeasuredwidth (): 0; // get the byte point width
- If (! Setsharewindowflag & defaultwindow> = 0 & defaultwindow <= childCount-1 ){
- // Set the left end distance of the default window
- Offset =-1 * defaultwindow * childwidth;
- Setmediawindowflag = true;
- }
- // Set the initial distance from (0, 0) to the X axis.
- Int left = 0 + offset;
- For (INT I = 0; I <childcount; I ++ ){
- // Set the position of each subview in the layout
- View child = getchildat (I );
- If (child. getvisibility ()! = View. Gone ){
- Child. layout (left, 0, childwidth + left, child. getmeasuredheight ());
- Left = left + childwidth;
- }
- }
- }
- // Touch screen events
- @ Override
- Public Boolean ontouchevent (motionevent event ){
- Boolean result = gesturedetector. ontouchevent (event );
- If (event. getaction () = motionevent. action_up ){
- // When the finger is raised, the entire sub-view is displayed based on the sliding distance.
- Showonedesktop ();
- }
- Return result;
- }
- // Determine the desktop that is displayed when your finger is raised
- Private void showonedesktop (){
- Int Index = math. Abs (offset)/childwidth;
- If (math. Abs (offset)-Index * childwidth> childwidth/2 ){
- Index ++;
- }
- Offset = offset> 0? Index * childwidth:-1 * Index * childwidth;
- Requestlayout ();
- }
- }
Copy code
The attrs. xml file used in this Code:
- <Resources>
- <Declare-styleable name = "myscrollwindow">
- <ATTR name = "defaultwindow" format = "integer"/>
- </Declare-styleable>
- </Resources>
Copy code
It can be used the same as the layout file provided by the system.
- <? XML version = "1.0" encoding = "UTF-8"?>
- <Com. WXG. scroll_1_view.scrolllayout
- Xmlns: Android = "http://schemas.android.com/apk/res/android"
- Xmlns: Demo = "http://schemas.android.com/apk/res/com.wxg.scroll_window"
- Android: Id = "@ + ID/testlayout"
- Android: layout_width = "fill_parent"
- Android: layout_height = "fill_parent"
- Demo: defaultwindow = "1"
- >
- <Framelayout
- Android: layout_height = "fill_parent"
- Android: layout_width = "fill_parent"
- Android: Background = "# cccccc">
- <Button
- Android: layout_height = "wrap_content"
- Android: layout_width = "wrap_content"
- Android: text = "1"/>
- </Framelayout>
- <Framelayout
- Android: layout_height = "fill_parent"
- Android: layout_width = "fill_parent"
- Android: Background = "# ffffff">
- <Button
- Android: layout_height = "wrap_content"
- Android: layout_width = "wrap_content"
- Android: text = "2"/>
- </Framelayout>
- <Framelayout
- Android: layout_height = "fill_parent"
- Android: layout_width = "fill_parent"
- Android: Background = "# bcbcbc">
- <Button
- Android: layout_height = "wrap_content"
- Android: layout_width = "wrap_content"
- Android: text = "3"/>
- </Framelayout>
- </COM. WXG. scroll_1_view.scrolllayout>