自定义Touch360ImageView的代码如下:
package com.example.myapplication;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.LevelListDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
public class Touch360ImageView extends androidx.appcompat.widget.AppCompatImageView {
private float mDownX;
private float mLastX;
private long mTouchTime;
private int mImageLevel;
private int mDrawableCount;
private static final int TOUCH_SPACING = 5; //触摸间距
private static final int TIME_INTERVAL = 200; //触摸时间间隔
public Touch360ImageView(Context context) {
this(context, null);
}
public Touch360ImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public Touch360ImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Touch360ImageView);
int arrayId = typedArray.getResourceId(R.styleable.Touch360ImageView_drawableArray, R.array.image_list);
typedArray.recycle();
TypedArray drawableArray = context.getResources().obtainTypedArray(arrayId);
LevelListDrawable levelListDrawable = new LevelListDrawable();
mDrawableCount = drawableArray.length();
for (int i = 0; i < mDrawableCount; i++) {
levelListDrawable.addLevel(0, i, getResources().getDrawable(drawableArray.getResourceId(i, 0)));
}
setImageDrawable(levelListDrawable);
drawableArray.recycle();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = event.getRawX();
mLastX = mDownX;
mTouchTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) (event.getRawX() - mLastX);
mLastX = event.getRawX();
if (dx > TOUCH_SPACING) {
mImageLevel++;
if (mImageLevel >= mDrawableCount) {
mImageLevel = 0;
}
} else if (dx < -TOUCH_SPACING) {
mImageLevel--;
if (mImageLevel < 0) {
mImageLevel = mDrawableCount - 1;
}
}
setImageLevel(mImageLevel);
break;
case MotionEvent.ACTION_UP:
if (System.currentTimeMillis() - mTouchTime < TIME_INTERVAL && Math.abs(mDownX - event.getRawX()) < TOUCH_SPACING) {
performClick();
return false;
}
break;
}
return true;
}
}
可根据效果调整触摸间距和时间间隔以达到更好的效果。支持根据自定义图片数量来刷新图片。
布局文件中的代码
<com.example.myapplication.Touch360ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:drawableArray="@array/image_list"/>
arrays.xml的数组定义如下
<array name="image_list">
<item>@drawable/car_0001</item>
<item>@drawable/car_0010</item>
<item>@drawable/car_0020</item>
<item>@drawable/car_0030</item>
<item>@drawable/car_0040</item>
<item>@drawable/car_0050</item>
<item>@drawable/car_0060</item>
<item>@drawable/car_0070</item>
<item>@drawable/car_0080</item>
<item>@drawable/car_0090</item>
<item>@drawable/car_0100</item>
<item>@drawable/car_0110</item>
<item>@drawable/car_0120</item>
<item>@drawable/car_0130</item>
<item>@drawable/car_0140</item>
<item>@drawable/car_0150</item>
<item>@drawable/car_0160</item>
<item>@drawable/car_0170</item>
<item>@drawable/car_0180</item>
<item>@drawable/car_0190</item>
<item>@drawable/car_0200</item>
<item>@drawable/car_0210</item>
<item>@drawable/car_0220</item>
<item>@drawable/car_0230</item>
<item>@drawable/car_0240</item>
<item>@drawable/car_0250</item>
<item>@drawable/car_0260</item>
<item>@drawable/car_0270</item>
<item>@drawable/car_0280</item>
<item>@drawable/car_0290</item>
<item>@drawable/car_0300</item>
<item>@drawable/car_0310</item>
<item>@drawable/car_0320</item>
<item>@drawable/car_0330</item>
<item>@drawable/car_0340</item>
<item>@drawable/car_0350</item>
<item>@drawable/car_0360</item>
</array>
这里用到37张图片,实际上36张足够,最后一张图片car_0360和第一张图片car_0001是同一图片。当然尽量不要放入更多的图片以免OOM。
attrs.xml中自定义图片数组引用属性如下:
<declare-styleable name="Touch360ImageView">
<attr name="drawableArray" format="reference"/>
</declare-styleable>
最终效果如下:
这是替换3D效果的一种简单方案,要实现更好的360旋转或更高级的效果还是得依赖3D引擎,可以利用第三方3D软件生成android所需要的jar和so库集成在android项目里,本篇不做详细描述。