源码下载:http://download.csdn.net/detail/scimence/9027447
package com.sci.circularviewswitching;
import android.app.Activity;
import android.os.Bundle;
/**
* MainActivity
* -----
* 2015-8-18 下午4:48:07
* wangzhongyuan
*/
public class MainActivity extends Activity
{
int[] PicId = { R.drawable.pic1, R.drawable.pic2, R.drawable.pic3, R.drawable.pic4, R.drawable.pic5, R.drawable.pic6, R.drawable.pic7, R.drawable.pic8 };
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
CircularImageView main = new CircularImageView(this, PicId); // 创建主视图
setContentView(main); // 设置为游戏视图
// setContentView(R.layout.activity_main);
}
}
/**
* 2015-8-19上午9:48:34
* wangzhongyuan
*/
package com.shjc.jsbc.view2d.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.RelativeLayout;
import android.widget.Toast;
/**
* CircularImageView 此类用于实现多张ImageView的层叠展示循环切换,中间图像最前端显示,向两边图像尺寸依次递减
* selected()获取当前最前端显示的控件id
* -----
* 2015-8-19 上午9:48:34
* wangzhongyuan
*/
public class CircularImageView extends RelativeLayout implements OnTouchListener, android.view.View.OnClickListener
{
private Context context; // 控件所处的上下文环境
private int[] PicId; // 控件所要展示的子图像
private int len; // 子图像总数
private ImageView2[] pics; // 子图像数组
private int offSet = 0; // 图像显示偏移值,控制图像的显示位置
private float x1 = -1, y1 = -1, x2 = -1, y2 = -1; // 标志触摸按下和触摸释放时的坐标
/**
* 获取当前选中的子控件id = [0, len)
*/
public int selected()
{
// 选中图像id
int id = len / 2 + offSet;
if (id >= len)
id -= len;
else if (id < 0) id += len;
return id;
}
/**
* 选中子控件变动时调用该函数,子类可重写该函数,执行子控件选项变动逻辑
*/
public void selecteChanged()
{
// if(selected() == 0) ...;
// else if(selected() == 1) ...;
}
/**
* 创建控件, PicId = { R.drawable.pic1, R.drawable.pic2, R.drawable.pic3, R.drawable.pic4, R.drawable.pic5};
*/
public CircularImageView(Context context, int[] PicId)
{
super(context);
this.context = context;
this.PicId = PicId;
len = PicId.length;
offSet = -len / 2; // 初始时,显示第一项到最中间
creatMainView();
}
// 创建CircularImageView的子控件,以代码布局的方式显示PicId对应的图像
private void creatMainView()
{
int w = 480, h = 300; // CircularImageView整体大小
int w2 = 264, h2 = 165; // CircularImageView最中间位置的ImageView展示大小
// 控件主体部分
RelativeLayout body = new RelativeLayout(context); // 创建一个相对布局的视图
body.setBackgroundColor(Color.GRAY); // 为其设置背景色
body.setOnTouchListener(this); // 为CircularImageView添加触屏响应
// 添加游戏主体部分到主界面
RelativeLayout.LayoutParams paramsBody = new RelativeLayout.LayoutParams(w, h);
paramsBody.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
this.addView(body, paramsBody);
pics = new ImageView2[len];
for (int i = 0; i < len; i++)
{
// 修改控件的显示顺序
int j = i, half = len / 2;
if (i >= half) j = len - 1 - (i - half);
// 向body中添加子控件
ImageView2 pic = new ImageView2(context, j - half);
RelativeLayout.LayoutParams params = getLayoutParams(w / 2, h / 2, w2, h2, j);
body.addView(pic, params); // 将表示方格的文本框添加到窗体
pic.setScaleType(ScaleType.CENTER_CROP);
pic.setBackgroundResource(getPicId(PicId, j));
pics[j] = pic;
pic.setOnClickListener(this); // 添加事件监听
}
pics[len / 2].setOnTouchListener(this); // 为中间位置的子控件添加触屏响应
}
// 根据偏移值,循环获取图像资源对应的索引
private int getPicId(int[] PicId, int i)
{
i += offSet;
if (i >= len)
i -= len;
else if (i < 0) i += len;
return PicId[i];
}
// 获取第index项的布局参数,界面从0-len项依次布局,最中间的那项居中显示,从中间向两边尺寸依次递减
private RelativeLayout.LayoutParams getLayoutParams(int CenterX, int CenterY, int w, int h, int index)
{
int len = this.len, half = len / 2;
if (len % 2 == 0) len++;
index %= len;
int Sign = index >= half ? 1 : -1;
int W = getHalfWH(w, index - half);
int H = getHalfWH(h, index - half);
int sumW = getHalfWH_sum(w, index - half) * Sign;
// int sumH = getHalfWH_sum(h, index - half);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(W, H);
int left = CenterX + sumW - W / 2, top = CenterY - H / 2, right = left + W + 1, bottom = top + H + 1;
params.setMargins(left, top, right, bottom); // 设置index对应的View的布局位置
return params;
}
// 长宽值WH经过n次折半
private int getHalfWH(int WH, int n)
{
n = Math.abs(n);
while (n-- > 0)
WH /= 2;
return WH;
}
// 长宽值WH经过n次折半,偏移量累积值
private int getHalfWH_sum(int WH, int n)
{
n = Math.abs(n);
int sum = 0;
while (n-- > 0)
{
WH /= 2;
sum += WH;
}
return sum;
}
/* 点击界面中的View,切换显示至最前端 */
@SuppressLint("HandlerLeak")
@Override
public void onClick(View arg0)
{
if (arg0 instanceof ImageView2)
{
int half = len / 2;
ImageView2 view = (ImageView2) arg0;
if (view.offSet == 0) return;
// 根据点击的ImageView位置,为所有子控件添加简单的动画切换效果
for (int i = 0; i < len; i++)
{
if (i < half)
aniScale(pics[i], view.offSet < 0);
else if (i > half)
aniScale(pics[i], view.offSet > 0);
else
aniScale(pics[i], false);
}
// 根据点击控件位置,设置图像偏移值
offSet += view.offSet;
if (offSet >= len)
offSet -= len;
else if (offSet < 0) offSet += len;
// 延时执行切换显示动作
new Handler()
{
public void handleMessage(Message msg)
{
for (int i = 0; i < len; i++)
{
pics[i].setBackgroundResource(getPicId(PicId, i));
}
}
}.sendEmptyMessageDelayed(1, 55L);
// 执行选中子控件变动逻辑
selecteChanged();
// 选中图像提示信息
Toast.makeText(context, "选中图像" + selected(), Toast.LENGTH_SHORT).show();
}
}
// 为视图v添加动画效果,尺寸变化
private void aniScale(View v, boolean amplify)
{
// v.bringToFront(); //前端显示
AnimationSet aniSet = new AnimationSet(true);
// 设置尺寸从1倍变化到1.7倍
ScaleAnimation scaleAni;
if (amplify)
scaleAni = new ScaleAnimation(1f, 1.75f, 1f, 1.75f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
else
scaleAni = new ScaleAnimation(1f, 0.45f, 1f, 0.45f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAni.setDuration(50); // 设置动画效果时间
aniSet.addAnimation(scaleAni); // 将动画效果添加到动画集中
v.startAnimation(aniSet); // 视图v开始动画效果
}
// 为每个ImageView添加offSet属性值,记录相对于中间ImageView的偏移量
class ImageView2 extends ImageView
{
int offSet = -1;
ImageView2(Context context, int offSet)
{
super(context);
this.offSet = offSet;
}
}
/* 触屏响应 */
public boolean onTouch(View v, MotionEvent event)
{
// 获取触摸拖动起点和终点的坐标,以便于判断触摸移动方向
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN: // 触摸屏幕后记录坐标
x1 = event.getX(); // 按下点坐标
y1 = event.getY();
break;
case MotionEvent.ACTION_MOVE: // 触摸移动
break;
case MotionEvent.ACTION_UP:
x2 = event.getX(); // 移动点坐标
y2 = event.getY();
if (x2 - x1 > 6) onClick(pics[len / 2 - 1]); // 向右滑动
else if (x2 - x1 < -6) onClick(pics[len / 2 + 1]); // 向左滑动
break;
case MotionEvent.ACTION_CANCEL:
}
return true;
}
}