SnakeLayout (仿gallery)

简要介绍:相信大部分用过Android Gallery控件的人,对gallery这个控件可谓是又爱又恨,gallery动画效果不错,非常实用,可是却有很多限制,从布局上来讲,gallery仅能水平放置,若想使用垂直放置的gallery,除非重写gallery。本文所述SnakeLayout继承于FrameLayout,用户可在SnakeLayout里自定义多个ImageView (大于等于3)的位置,并将指定的ID分配给所定义的ImageView;之后在主文件里进行简单的初始化后,就可以像gallery一样拖动所定义的ImageView,如同一条蛇一样连续的移动,不仅能横着拖,竖着拖,还能斜着拖,甚至绕圈圈。

效果图如下(android虚拟机长宽为800*600):

Android 自定义控件-SnakeLayout (仿gallery)


 

Android 自定义控件-SnakeLayout (仿gallery)


(测试版)代码如下:
package com.Snake;
/*
 * Author: Wallace Wang
 * Email: wallage@qq.com
 */
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class SnakeLayout extends FrameLayout {
 private static final String LOG_TAG = "SnakeLayout";
 private GestureDetector mGestureDetector;
 private SnakeOnGestureListener mGestureListener;
 private List<View> ViewHolder;
 private int selectImg;
 private int totalViewNum;
 private View mContentView;
 private SnakeView ScrollView;
 private Context mContext;
 private enum State {
  ABOUT_TO_ANIMATE,
  ANIMATING,
  ANIMATE_END,
  READY,
  TRACKING
 };
 private State mState;
 private double aniStartPos;// Value = scrollNum + percent*direction;
 private double aniStopPos;// Value = scrollNum + percent*direction;
 private Date aniStartTime;
 private long aniTime = 1000;
 private double aniSpeed = 500;
 private double aniDefG = 5;
 
 private int mContentWidth = 0;
 private int mContentHeight = 0;
 private int clickItem = -1;
 private int direction = 0;
 private int movDirection = 0;
 private double percent = 0;
 private int scrollNum = 0;
 private PathScale myPathViews;
 private List<Bitmap> BmpRecViews;
 private OnSelectListener selectListener;
 private OnClickListener clickListener;
 private int currentIndex = 0;
 public SnakeLayout(Context context, AttributeSet attrs) {
  super(context, attrs);
  Log.d(LOG_TAG, "Init Snake Layout");
  mContext = context;
  TypedArray a = context.obtainStyledAttributes(attrs,
    R.styleable.SnakeLayout);
  selectImg = a.getInteger(R.styleable.SnakeLayout_selectImg, -1);
  a.recycle();
  mGestureListener = new SnakeOnGestureListener();
  mGestureDetector = new GestureDetector(mGestureListener);
  mGestureDetector.setIsLongpressEnabled(false);
  BmpRecViews = new ArrayList<Bitmap>();
  myPathViews = new PathScale();
  mState = State.READY;
 }
 public void Init(){
  for (int i = 0; i < totalViewNum; i++) {
   ImageView v = (ImageView)ViewHolder.get(i);
   v.setScaleType(ImageView.ScaleType.FIT_XY);
   v.setImageBitmap(BmpRecViews.get((i + currentIndex)% BmpRecViews.size()));
  }
 }
 
 public void addBitmap(Bitmap b){
  if(b != null)
   BmpRecViews.add(b);
 }
 
 public void addBitmap(Bitmap b, int position){
  if(b != null)
   BmpRecViews.add(position, b);
 }
 
 public void addRec(int rec){
  Bitmap b = BitmapFactory.decodeResource(this.getResources(),rec);
  if(b != null)
   BmpRecViews.add(b);
 }
 ......
代码太长,省略
 
 
res/values/attrs.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable>
        <!-- Defines the special selected position Image -->
        <attr format="integer" />
    </declare-styleable>
</resources>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwsxzj.html