在项目中遇到了一个画廊展示照片墙效果 支持左右滑动 看起来效果不错!
今天就把这个效果做出来展示一下!
/**
* A view that shows items in a center-locked, horizontally scrolling list.
*
* The default values for the Gallery assume you will be using
* {@link android.R.styleable#Theme_galleryItemBackground} as the background for
* each View given to the Gallery from the Adapter. If you are not doing this,
* you may need to adjust some Gallery properties, such as the spacing.
*
* Views given to the Gallery should use {@link Gallery.LayoutParams} as their
* layout parameters type.
*
* @attr ref android.R.styleable#Gallery_animationDuration
* @attr ref android.R.styleable#Gallery_spacing
* @attr ref android.R.styleable#Gallery_gravity
*
* @deprecated This widget is no longer supported. Other horizontally scrolling
* widgets include {@link HorizontalScrollView} and {@link android.support.v4.view.ViewPager}
* from the support library.
*/
在使用这个组件的时候 官方API注明
该类已被弃用,其他水平滚动窗口小部件包括HorizontalScrollView和ViewPager从支持库。
因为这个类是里面的,时间比较久了。虽说被弃用,也只是不再支持后续的更新。
想要预期の效果 那就动手完成它吧
自定义View MyGallery 继承画廊类 把我们想要的属性设置一下
public class MyGallery extends Gallery {
private int centerPoint;
private static final String TAG = "MyGalleryHAHA";
private Camera mCamera;
private int maxRoate = 60;//旋转的最大角度
public MyGallery(Context context) {
super(context);
mCamera = new Camera();
setStaticTransformationsEnabled(true);
}
public MyGallery(Context context, AttributeSet attrs) {
super(context, attrs);
mCamera = new Camera();
setStaticTransformationsEnabled(true);
}
public MyGallery(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mCamera = new Camera();
setStaticTransformationsEnabled(true);
}
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
int viewCenterPoint = getItemViewCenterPoint(child); // item的中心点
int rotateAngle = 0; // 默认旋转角度为0
// 如果当前的View的中心点不等于gallery的中心点, 就是两边的图片, 需要计算旋转角度
if (viewCenterPoint != centerPoint) {
// gallery中心点 - 图片中心点 = 差值
int diff = centerPoint - viewCenterPoint;
// 差值 / 图片的宽度 = 比值
float scale = (float) diff / (float) child.getWidth();
// 比值 * 最大旋转角度 = 最终的旋转角度
rotateAngle = (int) (scale * maxRoate);
if (Math.abs(rotateAngle) > maxRoate) { // 当前角度超过了50, 需要赋值到50 或者 -50
rotateAngle = rotateAngle > 0 ? maxRoate : -maxRoate;
}
}
// 设置变换效果之前, 需要把Transformation中的上一个item的变换效果清楚
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX); // 设置变换效果的类型为矩阵类型
setItemStartAnim((ImageView) child, rotateAngle, t);
return true;
}
/**
* 设置变换效果
*
* @param iv gallery的item
* @param rotateAngle 旋转的角度
* @param t 变换的对象
*/
private void setItemStartAnim(ImageView iv, int rotateAngle, Transformation t) {
mCamera.save(); // 保存状态
int absRotateAngle = Math.abs(rotateAngle); // 取旋转角度的绝对值
// 放大效果
mCamera.translate(0, 0, 100f); // 给摄像机定位
int zoom = -240 + (absRotateAngle * 2);
mCamera.translate(0, 0, zoom);
// 透明度(中间的图片是完全显示, 两边有一定的透明度)
int alpha = (int) (255 - (absRotateAngle * 2.5));
iv.setAlpha(alpha); // 透明度取值范围: 0 ~ 255, 0 就是完全隐藏, 255 完全显示
// 旋转(在中间的图片没有旋转角度, 只要不在中间就有旋转角度)
mCamera.rotateY(rotateAngle);
Matrix matrix = t.getMatrix(); // 变换的矩阵, 需要把变换的效果添加到矩阵中
// 给matrix赋值
mCamera.getMatrix(matrix); // 把matrix矩阵给camera对象, camera对象就会把上面添加的效果转换成矩阵添加到matrix对象中
// 矩阵前乘
matrix.preTranslate(-iv.getWidth() >> 1, -iv.getHeight() >> 1);
// 矩阵后乘
matrix.postTranslate(iv.getWidth() >> 1, iv.getHeight() >> 1);
mCamera.restore(); // 恢复到之前保存的状态
}
/**
* 获取gallery的中心点
*
* @return
*/
public int getCenterPoint() {
return getWidth() / 2;
}
/**
* 获取item view的中心点
*/
public int getItemViewCenterPoint(View itemView) {
if (itemView != null) {
return itemView.getWidth() / 2 + itemView.getLeft();
}
return 0;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerPoint = getCenterPoint();
}
}
完成自定义View MyGallery 后
如何使用?
如果为Gallery组件指定了10张图像,那么当Gallery组件显 示到第10张时,就不会再继续显示了。这虽然在大多数时候没有什么关系,但在某些情况下,我们希望图像显示到最后一张时再重第1张开始显示,也就是循环显示。
public class InviteShareActivity extends AppCompatActivity {
private int[] ids = {R.mipmap.image_1, R.mipmap.image_2, R.mipmap.image_3, R.mipmap.image_4, R.mipmap.image_5,
R.mipmap.image_6, R.mipmap.image_7, R.mipmap.image_8, R.mipmap.image_9, R.mipmap.image_10};
private Unbinder mUnbinder;
@BindView(R.id.toolbar)
Toolbar mToolbar;
@BindView(R.id.gallery)
MyGallery gallery;
private int screenWidth;
private int screenHeigh;
private int count;//记录画廊图数
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_invite_share);
StatusBarUtils.transparencyBar(this);
mUnbinder = ButterKnife.bind(this);
setSupportActionBar(mToolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayShowTitleEnabled(false);
ActivityUtils.addToolbarTitle(this, mToolbar, "仿3D画廊");
mToolbar.setNavigationOnClickListener(v -> onBackPressed());
getScreenWidthAndHeight();
MyAdapter adapter = new MyAdapter();
gallery.setAdapter(adapter);
gallery.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
ToastUtils.showShort(InviteShareActivity.this, "您点击了第" + position + "张画廊图");
}
});
}
/**
* 内部Adapter
*/
class MyAdapter extends BaseAdapter {
public MyAdapter() {
count = ids.length;//用于照片循环滑动
}
@Override
public int getCount() {
return Integer.MAX_VALUE;//用于循环滑动
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView iv = null;
position = position % count;
if (convertView == null) {
iv = new ImageView(InviteShareActivity.this);
} else {
iv = (ImageView) convertView;
}
Bitmap bitmap = AppUtils.compoundBitmap(getResources(), ids[position]);
BitmapDrawable bd = new BitmapDrawable(bitmap);
bd.setAntiAlias(true); // 消除锯齿
iv.setImageDrawable(bd);
Gallery.LayoutParams params = new Gallery.LayoutParams(screenWidth / 2, screenHeigh / 2);
iv.setLayoutParams(params);
return iv;
}
}
/**
* 获取屏幕的宽和高
*/
public void getScreenWidthAndHeight() {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;
screenHeigh = dm.heightPixels;
}
@Override
protected void onDestroy() {
super.onDestroy();
mUnbinder.unbind();
}
}
重新学习了一下自定义View 把自定义的属性又用了一次
效果还可以的 完成后 心情还是很高兴地!
我要一步一步往上爬
在最高点乘着叶片往前飞
任风吹干流过的泪和汗
我要一步一步往上爬
等待阳光静静看着它的脸
小小的天有大大的梦想
我有属于我的天
任风吹干流过的泪和汗
总有一天我有属于我的天