我有一个过渡效果,可以从一张图像滑动到下一张图像,再滑动到上一张图像。滑动的图像被移动到屏幕之外,上一个/下一个图像从屏幕的另一侧进入。
我无法实现的是,当我向上或向下滑动时,我会得到类似的垂直变换。 我已经开始工作了,但仍然不顺利。缓慢滑动时图像会有点上下跳动(仅在垂直滑动时)。
图像查看器活动
public class ImageViewerActivity extends ActivityBase {
private ArrayList<Uri> mImageUris;
private int mCurrentImageIndex = 0;
private ViewPager mViewPager;
private ImagePagerAdapter mPagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_viewer);
initializeUI();
setupToolbar();
mImageUris = getIntent().getParcelableArrayListExtra("image_uris");
mCurrentImageIndex = getIntent().getIntExtra("current_image_index", 0);
mPagerAdapter = new ImagePagerAdapter(this, mImageUris);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setCurrentItem(mCurrentImageIndex);
mPagerAdapter.instantiateItem(mViewPager, mCurrentImageIndex);
mPagerAdapter.notifyDataSetChanged();
// Set the PageTransformer to apply the custom animation
mViewPager.setPageTransformer(false, new DepthPageTransformer());
}
private void initializeUI() {
mViewPager = findViewById(R.id.viewPager);
mViewPager.setOnTouchListener(new View.OnTouchListener() {
private float startX = 0;
private float startY = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float endX = event.getX();
float endY = event.getY();
float deltaX = Math.abs(endX - startX);
float deltaY = Math.abs(endY - startY);
// Set a threshold value to determine primary direction
float threshold = 200; // Adjust this value as needed
if (deltaX > threshold && deltaX > deltaY) {
// Horizontal swipe
break;
}
// Vertical swipe
float translationY = endY - startY;
v.setTranslationY(translationY);
break;
case MotionEvent.ACTION_UP:
float endYUp = event.getY();
float deltaYUp = endYUp - startY;
// Set a threshold value for vertical swiping
float verticalThreshold = 100; // Adjust this value as needed
// Check if it's a vertical swipe and exceeds a certain threshold
if (deltaYUp < -verticalThreshold) {
// Swipe up, perform dismiss animation
v.animate().translationYBy(-v.getHeight()).withEndAction(new Runnable() {
@Override
public void run() {
onBackPressed();
v.setTranslationY(0); // Reset translation after dismissal
}
});
return true;
} else if (deltaYUp > verticalThreshold) {
// Swipe down, perform dismiss animation
final float translation = endYUp > startY ? v.getHeight() : -v.getHeight();
v.animate().translationYBy(translation).withEndAction(new Runnable() {
@Override
public void run() {
onBackPressed();
v.setTranslationY(0); // Reset translation after dismissal
}
});
return true;
}
// Reset translation on other cases
v.animate().translationY(0);
break;
}
return false;
}
});
}
private void setupToolbar() {
Toolbar toolbar = findViewById(R.id.activity_gallery_view_toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("");
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
深度页面转换器
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) {
view.setAlpha(0f);
} else if (position <= 0) {
view.setAlpha(1f);
view.setTranslationX(0f);
view.setScaleX(1f);
view.setScaleY(1f);
} else if (position <= 1) {
view.setAlpha(1 - position);
view.setTranslationX(pageWidth * -position);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else {
view.setAlpha(0f);
}
}
ImagePagerAdapter
public class ImagePagerAdapter extends PagerAdapter {
private Context mContext;
private HashMap<Integer, Bitmap> mImages;
private ArrayList<Uri> mImageUris;
private static final String TAG = ImagePagerAdapter.class.getSimpleName();
public ImagePagerAdapter(Context context, ArrayList<Uri> imageUris) {
mContext = context;
mImageUris = imageUris;
Log.d(TAG, "mImageUris: " + mImageUris);
mImages = new HashMap<>(imageUris.size());
if(imageUris.size() > 0) {
notifyDataSetChanged();
}
}
@Override
public int getCount() {
return mImageUris.size();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//Log.d(TAG, "instantiating position: " + position);
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View itemView = inflater.inflate(R.layout.image_pager_item, container, false);
Glide.with(mContext)
.asBitmap()
.load(mImageUris.get(position))
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
// Add the loaded image to the list
mImages.put(position, resource);
ImageView imageView = itemView.findViewById(R.id.imageView);
imageView.setImageBitmap(mImages.get(position));
container.addView(itemView);
//Log.d(TAG, "added image: " + position);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
// Handle the case when the resource is cleared (e.g., due to recycling)
//imagesLoaded.getAndIncrement(); // Increment the count in this case
}
});
return itemView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
public void updateData(ArrayList<Uri> imageUris) {
mImageUris = imageUris;
notifyDataSetChanged();
}
我认为你在转换课上的计算有问题
这里是 MIN_SCALE,它可能会弄乱你的整个计算
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) {
view.setAlpha(0f);
} else if (position <= 0) {
view.setAlpha(1f);
view.setTranslationX(0f);
view.setScaleX(1f);
view.setScaleY(1f);
} else if (position <= 1) {
view.setAlpha(1 - position);
view.setTranslationX(pageWidth * -position);
// actually this is can really make your image jumping
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else {
view.setAlpha(0f);
}
}
尝试使用这个
public class DepthTransformation implements ViewPager.PageTransformer{
@Override
public void transformPage(View page, float position) {
if (position < -1){ // [-Infinity,-1)
// This page is way off-screen to the left.
page.setAlpha(0);
}
else if (position <= 0){ // [-1,0]
page.setAlpha(1);
page.setTranslationX(0);
page.setScaleX(1);
page.setScaleY(1);
}
else if (position <= 1){ // (0,1]
page.setTranslationX(-position*page.getWidth());
page.setAlpha(1-Math.abs(position));
page.setScaleX(1-Math.abs(position));
page.setScaleY(1-Math.abs(position));
}
else { // (1,+Infinity]
// This page is way off-screen to the right.
page.setAlpha(0);
}
}
}