现在的位置: 首页 > 综合 > 正文

Android 左右滑动 控件 (1)

2012年11月12日 ⁄ 综合 ⁄ 共 17082字 ⁄ 字号 评论关闭
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://2660311.blog.51cto.com/2650311/600521

Android平台上可以左右滑动的控件,总共3个文件,其中一个用于是Activity,详细内容请从附件下载:

图片素材:

本来是PNG的,上传后成了gif。

                

界面:

   

 包括三个类:

1. SlipView用于显示

  1. package com.diydyq.android.swipeTest;  
  2.  
  3. import android.content.Context;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.drawable.BitmapDrawable;  
  7. import android.util.AttributeSet;  
  8. import android.util.Log;  
  9. import android.view.MotionEvent;  
  10. import android.view.View;  
  11.  
  12. /**  
  13.  * Slip the front part to some dock position  
  14.  *   
  15.  * @author diydyq  
  16.  *   
  17.  */ 
  18. public class SlipView extends View  
  19. {  
  20.     private static final String TAG = "SlipView";  
  21.  
  22.     /** Listen slip on the block, no matter the event is success or fail */ 
  23.     private OnSlipListener onSlipListener;  
  24.  
  25.     /** Slip entity to set the value about backImage, frontImage position */ 
  26.     private SlipEntity slipEntity;  
  27.  
  28.     private float tmpTouchX;  
  29.     private float tmpTouchGap;  
  30.  
  31.     public SlipView(Context context)  
  32.     {  
  33.         super(context);  
  34.  
  35.         Bitmap backImage = ((BitmapDrawable) getResources().getDrawable(R.drawable.back5)).getBitmap();  
  36.         Bitmap frotImage = ((BitmapDrawable) getResources().getDrawable(R.drawable.frot1)).getBitmap();  
  37.         this.slipEntity = new SlipEntity(backImage, frotImage);  
  38.     }  
  39.  
  40.     public SlipView(Context context, AttributeSet attr)  
  41.     {  
  42.         super(context, attr);  
  43.  
  44.         Bitmap backImage = ((BitmapDrawable) getResources().getDrawable(R.drawable.back5)).getBitmap();  
  45.         Bitmap frotImage = ((BitmapDrawable) getResources().getDrawable(R.drawable.frot1)).getBitmap();  
  46.         this.slipEntity = new SlipEntity(backImage, frotImage);  
  47.     }  
  48.  
  49.     public SlipView(Context context, SlipEntity slipEntity)  
  50.     {  
  51.         super(context);  
  52.  
  53.         this.slipEntity = slipEntity;  
  54.     }  
  55.  
  56.     @Override 
  57.     protected void onDraw(Canvas canvas)  
  58.     {  
  59.         super.onDraw(canvas);  
  60.  
  61.         if (!this.slipEntity.isInit)  
  62.         {  
  63.             Log.v(TAG, "Init SlipEntity");  
  64.             this.slipEntity.initSlipEntity(this.getWidth(), this.getHeight());  
  65.         }  
  66.  
  67.         canvas.drawBitmap(this.slipEntity.getBackImage(), this.slipEntity.xBackStart, this.slipEntity.yBackStart, null);  
  68.         canvas.drawBitmap(this.slipEntity.getFrotImage(), this.slipEntity.xFrotStart, this.slipEntity.yFrotStart, null);  
  69.     }  
  70.  
  71.     /**  
  72.      * listen touch events and notify listener  
  73.      */ 
  74.     @Override 
  75.     public boolean onTouchEvent(MotionEvent event)  
  76.     {  
  77.         Log.v(TAG, "Touch Position:" + event.getX());  
  78.  
  79.         switch (event.getAction())  
  80.         {  
  81.         case MotionEvent.ACTION_DOWN:  
  82.             // Log.v(TAG, "Down");  
  83.             if (this.slipEntity.isPointInImage(SlipEntity.FLAG_FROT, event.getX(), event.getY()))  
  84.             {  
  85.                 this.tmpTouchX = event.getX();  
  86.                 this.tmpTouchGap = event.getX() - this.slipEntity.xFrotStart;  
  87.             }  
  88.             break;  
  89.         case MotionEvent.ACTION_MOVE:  
  90.             // Log.v(TAG, "Move");  
  91.  
  92.             this.slipEntity.isReachRight();  
  93.             this.slipEntity.isReachLeft();  
  94.  
  95.             // if point(x,y) is not in back image, front image will not move  
  96.             if (this.slipEntity.isPointInImage(SlipEntity.FLAG_BACK, event.getX(), event.getY()))  
  97.             {  
  98.                 // Log.v(TAG, "Move2");  
  99.                 this.slipEntity.xFrotStart = event.getX() - this.tmpTouchGap;  
  100.             }  
  101.             break;  
  102.         case MotionEvent.ACTION_UP:  
  103.             Log.v(TAG, "Up");  
  104.  
  105.             int flagLR = 0;  
  106.               
  107.             if(event.getX() < this.tmpTouchX)  
  108.                 flagLR = 1;  
  109.             else 
  110.                 flagLR = 2;  
  111.               
  112.             float dockPer = this.slipEntity.isDock();  
  113.             if (dockPer != -1)  
  114.             {  
  115.                 // Dock at some Position  
  116.                 if (this.onSlipListener != null)  
  117.                     this.onSlipListener.slipDock(slipEntity, event, this.slipEntity.getCurDockPer());  
  118.                   
  119.                 if (event.getX() < this.tmpTouchX)  
  120.                 {  
  121.                     // Slip: <==  
  122.                     if (dockPer == 0.0)  
  123.                     {  
  124.                         // Reached  
  125.                         if (this.onSlipListener != null)  
  126.                             this.onSlipListener.slipLeft(slipEntity, event, true);  
  127.                     }  
  128.                     else 
  129.                     {  
  130.                         // Not Reached  
  131.                         this.slipEntity.xFrotStart = this.slipEntity.getCurDockPos();  
  132.                         if (this.onSlipListener != null)  
  133.                             this.onSlipListener.slipLeft(slipEntity, event, false);  
  134.                     }  
  135.                 }  
  136.                 else 
  137.                 {  
  138.                     // Slip: ==>  
  139.                     if (dockPer == 1.0)  
  140.                     {  
  141.                         // Reached  
  142.                         if (this.onSlipListener != null)  
  143.                             this.onSlipListener.slipRight(slipEntity, event, true);  
  144.                     }  
  145.                     else 
  146.                     {  
  147.                         // Not Reached  
  148.                         this.slipEntity.xFrotStart = this.slipEntity.getCurDockPos();  
  149.                         if (this.onSlipListener != null)  
  150.                             this.onSlipListener.slipRight(slipEntity, event, false);  
  151.                     }  
  152.                     break;  
  153.                 }  
  154.             }  
  155.             else 
  156.             {  
  157.                 // No dock  
  158.                 this.slipEntity.xFrotStart = this.slipEntity.getCurDockPos();  
  159.                   
  160.                 if(flagLR == 1)  
  161.                     this.onSlipListener.slipLeft(slipEntity, event, false);  
  162.                 else 
  163.                     this.onSlipListener.slipRight(slipEntity, event, false);  
  164.             }  
  165.  
  166. //          if (event.getX() < this.tmpTouchX)  
  167. //          {  
  168. //              // Slip: <==  
  169. //              if (this.slipEntity.isReachLeft())  
  170. //              {  
  171. //                  // Reached  
  172. //                  if (this.onSlipListener != null)  
  173. //                      this.onSlipListener.slipLeft(slipEntity, event, true);  
  174. //              }  
  175. //              else  
  176. //              {  
  177. //                  // Not Reached  
  178. //                  this.slipEntity.xFrotStart = this.slipEntity.getCurDockPos();  
  179. //                  if (this.onSlipListener != null)  
  180. //                      this.onSlipListener.slipLeft(slipEntity, event, false);  
  181. //              }  
  182. //          }  
  183. //          else  
  184. //          {  
  185. //              // Slip: ==>  
  186. //              if (this.slipEntity.isReachRight())  
  187. //              {  
  188. //                  // Reached  
  189. //                  if (this.onSlipListener != null)  
  190. //                      this.onSlipListener.slipRight(slipEntity, event, true);  
  191. //              }  
  192. //              else  
  193. //              {  
  194. //                  // Not Reached  
  195. //                  this.slipEntity.xFrotStart = this.slipEntity.getCurDockPos();  
  196. //                  if (this.onSlipListener != null)  
  197. //                      this.onSlipListener.slipRight(slipEntity, event, false);  
  198. //              }  
  199. //              break;  
  200. //          }  
  201.         }  
  202.         this.invalidate();  
  203.         return true;  
  204.     }  
  205.  
  206.     /**  
  207.      * Listener on slip event on slippery view author diydyq  
  208.      *   
  209.      */ 
  210.     public interface OnSlipListener  
  211.     {  
  212.         /**  
  213.          * Listen a slip after touch down and up, not including touch move  
  214.          *   
  215.          * @param slipEntity  
  216.          * @param event  
  217.          * @param isSuccess  
  218.          */ 
  219.         public abstract void slipLeft(SlipEntity slipEntity, MotionEvent event, boolean isSuccess);  
  220.  
  221.         /**  
  222.          * Listen a slip after touch down and up, not including touch move  
  223.          *   
  224.          * @param slipEntity  
  225.          * @param event  
  226.          * @param isSuccess  
  227.          */ 
  228.         public abstract void slipRight(SlipEntity slipEntity, MotionEvent event, boolean isSuccess);  
  229.  
  230.         /**  
  231.          * Listen some dock(more than DOCK_L,DOCK_R), normally need not implement it unless more docks are needed.  
  232.          *   
  233.          * @param slipEntity  
  234.          * @param event  
  235.          * @param dockPer  
  236.          */ 
  237.         public abstract void slipDock(SlipEntity slipEntity, MotionEvent event, float dockPer);  
  238.     }  
  239.  
  240.     public OnSlipListener getOnSlipListener()  
  241.     {  
  242.         return onSlipListener;  
  243.     }  
  244.  
  245.     public void setOnSlipListener(OnSlipListener onSlipListener)  
  246.     {  
  247.         this.onSlipListener = onSlipListener;  
  248.     }  
  249.  
  250. }  

2. SlipEntity用于调整前景、背景图片位置等的操作。 

  1. package com.diydyq.android.swipeTest;  
  2.  
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.  
  6. import android.graphics.Bitmap;  
  7. import android.util.Log;  
  8.  
  9. /**  
  10.  * Slip entity used to set position and maybe boundary of back and front image  
  11.  *   
  12.  * @author diydyq  
  13.  *   
  14.  */ 
  15. public class SlipEntity  
  16. {  
  17.     public static final int FLAG_BACK = 1;  
  18.     public static final int FLAG_FROT = 2;  
  19.       
  20.     public static final float DOCK_L = 0;  
  21.     public static final float DOCK_M = (float)0.5;  
  22.     public static final float DOCK_R = 1;  
  23.       
  24.     public static final float MICRO_X = 10;  
  25.       
  26.     /** Background image */ 
  27.     Bitmap backImage;  
  28.  
  29.     /** Front image */ 
  30.     Bitmap frotImage;  
  31.  
  32.     /** Start Position of back image */ 
  33.     float xBackStart;  
  34.  
  35.     /** Start Position of back image */ 
  36.     float yBackStart;  
  37.  
  38.     /** Start Position of front image */ 
  39.     float xFrotStart;  
  40.  
  41.     /** Start Position of front image */ 
  42.     float yFrotStart;  
  43.  
  44.     /** initial Position of front image */ 
  45.     float xFrotInitPos;  
  46.  
  47.     /** initial Position of front image */ 
  48.     float yFrotInitPos;  
  49.  
  50.     /** Margin of front and back image in X-Axis */ 
  51.     float xMarginLeft;  
  52.  
  53.     /** Margin of front and back image in Y-Axis */ 
  54.     float yMarginTop;  
  55.       
  56.     /** Containing dock position of the front image */ 
  57.     Map<Float, Float> dockPosList = new HashMap<Float, Float>();  
  58.       
  59.     /** Current dock Percentage: DOCK_L | DOCK_M | DOCK_R */ 
  60.     float curDockPer = DOCK_L;  
  61.       
  62.     /** Weather has invoked initSlipEntity() */ 
  63.     boolean isInit = false;  
  64.  
  65.     public SlipEntity()  
  66.     {  
  67.  
  68.     }  
  69.  
  70.     public SlipEntity(Bitmap backImage, Bitmap frotImage)  
  71.     {  
  72.         this.backImage = backImage;  
  73.         this.frotImage = frotImage;  
  74.     }  
  75.  
  76.     public SlipEntity(float xBackStart, float yBackStart, float xFrotStart, float yFrotStart)  
  77.     {  
  78.         this.xBackStart = xBackStart;  
  79.         this.yBackStart = yBackStart;  
  80.         this.xFrotStart = xFrotStart;  
  81.         this.yFrotStart = yFrotStart;  
  82.     }  
  83.  
  84.     public void initSlipEntity(float viewWidth, float viewHeight)  
  85.     {  
  86.         this.xBackStart = (viewWidth - this.backImage.getWidth()) / 2;  
  87.         this.yBackStart = (viewHeight - this.backImage.getHeight()) / 2;  
  88.  
  89.         this.xMarginLeft = 5;  
  90.         this.yMarginTop = (this.backImage.getHeight() - this.frotImage.getHeight()) / 2;  
  91.  
  92.         this.xFrotInitPos = this.xBackStart + this.xMarginLeft;  
  93.         this.yFrotInitPos = this.yBackStart + this.yMarginTop;  
  94.  
  95.         this.xFrotStart = this.xFrotInitPos;  
  96.         this.yFrotStart = this.yFrotInitPos;  
  97.           
  98.         // Add dock position  
  99.         float dockL = this.xFrotInitPos;  
  100.         float dockR = this.xBackStart + this.backImage.getWidth() - this.frotImage.getWidth() - this.xMarginLeft;  
  101.           
  102.         this.dockPosList.put(DOCK_L, dockL);  
  103.         this.dockPosList.put(DOCK_R, dockR);  
  104.           
  105.         for(Float dockPer : this.dockPosList.keySet())  
  106.         {  
  107.             if(this.dockPosList.get(dockPer) == 0)  
  108.             {  
  109.                 float docPos = (dockR - dockL) * dockPer + this.dockPosList.get(DOCK_L);  
  110.                 this.dockPosList.put(dockPer, docPos);  
  111.             }  
  112.         }  
  113.           
  114.         // Dock at current position  
  115.         this.xFrotStart = this.dockPosList.get(this.curDockPer);  
  116.           
  117.         this.isInit = true;  
  118.           
  119.         // For debug information  
  120.         StringBuilder sb = new StringBuilder();  
  121.         sb.append("BackImageW:" + this.backImage.getWidth() + "\n");  
  122.         sb.append("BackImageH:" + this.backImage.getHeight() + "\n");  
  123.         sb.append("FrotImageW:" + this.frotImage.getWidth() + "\n");  
  124.         sb.append("FrotImageH:" + this.frotImage.getHeight() + "\n");  
  125.         sb.append("xBackStart:" + xBackStart + "\n");  
  126.         sb.append("yBackStart:" + yBackStart + "\n");  
  127.         sb.append("xMarginLeft:"+ xMarginLeft + "\n");  
  128.         sb.append("yMarginTop:" + yMarginTop + "\n");  
  129.         sb.append("xFrotInitP:" + xFrotInitPos + "\n");  
  130.         sb.append("yFrotInitP:" + yFrotInitPos + "\n");  
  131.         sb.append("xFrotStart:" + xFrotStart + "\n");  
  132.         sb.append("yFrotStart:" + yFrotStart + "\n");  
  133.         Log.v("SlipEntity",  sb.toString());  
  134.     }  
  135.       
  136.     /**  
  137.      * Weather the front image reaches the max right of background image, if true, set xFrotStart to max right.  
  138.      * @return  
  139.      */ 
  140.     public boolean isReachRight()  
  141.     {  
  142.         if(this.xFrotStart > this.dockPosList.get(DOCK_R))  
  143.         {  
  144.             this.curDockPer = DOCK_R;  
  145.             this.xFrotStart = this.dockPosList.get(DOCK_R);  
  146.             return true;  
  147.         }  
  148.         else 
  149.         {  
  150.             return false;  
  151.         }  
  152.     }  
  153.       
  154.     /**  
  155.      * Weather the front image reaches the max left of background image, if true, set xFrotStart to max left.  
  156.      * @return  
  157.      */ 
  158.     public boolean isReachLeft()  
  159.     {  
  160.         if(this.xFrotStart < this.dockPosList.get(DOCK_L))  
  161.         {  
  162.             this.curDockPer = DOCK_L;  
  163.             this.xFrotStart = this.dockPosList.get(DOCK_L);  
  164.             return true;  
  165.         }  
  166.         else 
  167.         {  
  168.             return false;  
  169.         }  
  170.     }  
  171.       
  172.     /**  
  173.      * Weather the point(x,y) is in the area of back or front image  
  174.      * @param type FLAG_FROT(front image) | FLAG_BACK(back image)  
  175.      * @param x X-coordinate of point  
  176.      * @param y Y-coordinate of point  
  177.      * @return weather the point is in specified area  
  178.      */ 
  179.     public boolean isPointInImage(int type, float x, float y)  
  180.     {  
  181.         float rPointX;  
  182.         float rPointY;  
  183.           
  184.         switch(type)  
  185.         {  
  186.         case FLAG_FROT:  
  187.             rPointX = this.xFrotStart + this.frotImage.getWidth();  
  188.             rPointY = this.yFrotStart + this.frotImage.getHeight();  
  189.  
  190.             if (x > this.xFrotStart && y > this.yFrotStart && x < rPointX && y < rPointY)  
  191.                 return true;  
  192.             else 
  193.                 return false;  
  194.               
  195.         case FLAG_BACK:  
  196.             rPointX = this.xBackStart + this.backImage.getWidth();  
  197.             rPointY = this.yBackStart + this.backImage.getHeight();  
  198.  
  199.             if (x > this.xBackStart && y > this.yBackStart && x < rPointX && y < rPointY)  
  200.                 return true;  
  201.             else 
  202.                 return false;  
  203.         default:  
  204.             return false;  
  205.         }  
  206.     }  
  207.       
  208.     /**  
  209.      * Is the current touch in some dock position  
  210.      * @return return dockPer if in, or -1 while no match  
  211.      */ 
  212.     public float isDock()  
  213.     {  
  214.         for(float dockPer : this.dockPosList.keySet())  
  215.         {  
  216.             float dockPos = this.dockPosList.get(dockPer);  
  217.               
  218.             if(this.xFrotStart > dockPos - MICRO_X && this.xFrotStart < dockPos + MICRO_X)  
  219.             {  
  220.                 this.curDockPer = dockPer;  
  221.                 return dockPer;  
  222.             }  
  223.         }  
  224.         return -1;  
  225.     }  
  226.       
  227.     /**  
  228.      * Get the current dock percentage in x-axis   
  229.      * @return  
  230.      */ 
  231.     public float getCurDockPer()  
  232.     {  
  233.         return this.curDockPer;  
  234.     }  
  235.       
  236.     /**  
  237.      * Get the current dock position in x-axis   
  238.      * @return  
  239.      */ 
  240.     public float getCurDockPos()  
  241.     {  
  242.         return this.dockPosList.get(this.curDockPer);  
  243.     }  
  244.       
  245.     /**  
  246.      * Add dock position to the list  
  247.      * @param dockPer dock Percent should be between (0.0,1.0)  
  248.      */ 
  249.     public void addDockPos(float dockPer)  
  250.     {  
  251.         if(dockPer > 0 && dockPer < 1)  
  252.         {  
  253.             this.dockPosList.put(dockPer, (float)0.0);  
  254.         }  
  255.     }  
  256.  
  257.     /**  
  258.      * Return width of background image  
  259.      * @return  
  260.      */ 
  261.     public float getBackWidth()  
  262.     {  
  263.         return this.backImage.getWidth();  
  264.     }  
  265.  
  266.     /**  
  267.      * Return height of background image  
  268.      * @return  
  269.      */ 
  270.     public float getBackHeight()  
  271.     {  
  272.         return this.backImage.getHeight();  
  273.     }  
  274.  
  275.     /**  
  276.      * Return width of front image  
  277.      * @return  
  278.      */ 
  279.     public float getFrotWidth()  
  280.     {  
  281.         return this.frotImage.getWidth();  
  282.     }  
  283.  
  284.     /**  
  285.      * Return height of front image  
  286.      * @return  
  287.      */ 
  288.     public float getFrotHeight()  
  289.     {  
  290.         return this.frotImage.getWidth();  
  291.     }  
  292.       
  293.     /**  
  294.      * Dock at some position  
  295.      * @param curDockPer  
  296.      */ 
  297.     public void setCurDockPos(float curDockPer)  
  298.     {  
  299.         this.curDockPer = curDockPer;  
  300.     }  
  301.       
  302.     public Bitmap getBackImage()  
  303.     {  
  304.         return backImage;  
  305.     }  
  306.  
  307.     public void setBackImage(Bitmap backImage)  
  308.     {  
  309.         this.backImage = backImage;  
  310.     }  
  311.  
  312.     public Bitmap getFrotImage()  
  313.     {  
  314.         return frotImage;  
  315.     }  
  316.  
  317.     public void setFrotImage(Bitmap frotImage)  
  318.     {  
  319.         this.frotImage = frotImage;  
  320.     }  
  321.  
  322.     public float getxBackStart()  
  323.     {  
  324.         return xBackStart;  
  325.     }  
  326.  
  327.     public void setxBackStart(float xBackStart)  
  328.     {  
  329.         

抱歉!评论已关闭.