我是靠谱客的博主 失眠毛衣,这篇文章主要介绍android仿微信下拉二楼_Android仿微信图片详情页面,可下拉关闭页面,现在分享给大家,希望可以做个参考。

话不多说,直接上效果图

imagereview.gif

1、要实现效果图的方案,需要操作重写ViewPager的事件处理。

2、下滑透明的方案可以使用设置背景来实现

下拉缩放的效果需要重写onInterceptTouchEvent和onTouchEvent,

在onInterceptTouchEvent中不拦截down事件,并且在move事件中判断是否满足下滑缩放的条件;

在onTouchEvent中实现具体的缩放以及透明度变化的效果;

同时在ViewPager的滑动要与下滑缩放区分开,因此需要监听OnPageChangeListener,并在onTouchEvent判断是否ViewPager在滑动中

public class DragViewPager extends ViewPager implements View.OnClickListener {

public static final int STATUS_NORMAL = 0;//正常浏览状态

public static final int STATUS_MOVING = 1;//滑动状态

public static final int STATUS_RESETTING = 2;//返回中状态

public static final String TAG = "DragViewPager";

public static final float MIN_SCALE_SIZE = 0.3f;//最小缩放比例

public static final int BACK_DURATION = 300;//ms

public static final int DRAG_GAP_PX = 50;

private int currentStatus = STATUS_NORMAL;

private int currentPageStatus;

private float mDownX;

private float mDownY;

private float screenHeight;

/**

* 要缩放的View

*/

private View currentShowView;

/**

* 滑动速度检测类

*/

private VelocityTracker mVelocityTracker;

private IAnimClose iAnimClose;

public void setIAnimClose(IAnimClose iAnimClose) {

this.iAnimClose = iAnimClose;

}

public DragViewPager(Context context) {

super(context);

init(context);

}

public DragViewPager(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

public void init(Context context) {

screenHeight = ScreenUtils.getScreenHeight(context);

setBackgroundColor(Color.BLACK);

addOnPageChangeListener(new OnPageChangeListener() {

@Override

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override

public void onPageSelected(int position) {

}

@Override

public void onPageScrollStateChanged(int state) {

currentPageStatus = state;

}

});

}

public void setCurrentShowView(View currentShowView) {

this.currentShowView = currentShowView;

if (this.currentShowView != null) {

this.currentShowView.setOnClickListener(this);

}

}

//配合SubsamplingScaleImageView使用,根据需要拦截ACTION_MOVE

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

if (getAdapter() instanceof ImagePagerAdapter) {

ImagePagerAdapter adapter = ((ImagePagerAdapter) getAdapter());

SubsamplingScaleImageView mImage = (SubsamplingScaleImageView) adapter.getItem(getCurrentItem()).getView().findViewById(R.id.image);

switch (ev.getAction()){

case MotionEvent.ACTION_DOWN:

Log.e("jc","onInterceptTouchEvent:ACTION_DOWN");

mDownX = ev.getRawX();

mDownY = ev.getRawY();

break;

case MotionEvent.ACTION_MOVE:

Log.e("jc","onInterceptTouchEvent:ACTION_MOVE");

if (mImage.getCenter() != null && mImage.getCenter().y <= mImage.getHeight() / mImage.getScale() / 2) {

Log.e("jc","onInterceptTouchEvent:ACTION_MOVE");

int deltaX = Math.abs((int) (ev.getRawX() - mDownX));

int deltaY = (int) (ev.getRawY() - mDownY);

if (deltaY > DRAG_GAP_PX && deltaX <= DRAG_GAP_PX) {//往下移动超过临界,左右移动不超过临界时,拦截滑动事件

return true;

}

}

break;

case MotionEvent.ACTION_UP:

Log.e("jc","onInterceptTouchEvent:ACTION_UP");

break;

}

}

return super.onInterceptTouchEvent(ev);

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

if (currentStatus == STATUS_RESETTING)

return false;

switch (ev.getActionMasked()) {

case MotionEvent.ACTION_DOWN:

mDownX = ev.getRawX();

mDownY = ev.getRawY();

addIntoVelocity(ev);

break;

case MotionEvent.ACTION_MOVE:

addIntoVelocity(ev);

int deltaY = (int) (ev.getRawY() - mDownY);

//手指往上滑动

if (deltaY <= DRAG_GAP_PX && currentStatus != STATUS_MOVING)

return super.onTouchEvent(ev);

//viewpager不在切换中,并且手指往下滑动,开始缩放

if (currentPageStatus != SCROLL_STATE_DRAGGING && (deltaY > DRAG_GAP_PX || currentStatus == STATUS_MOVING)) {

moveView(ev.getRawX(), ev.getRawY());

return true;

}

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

if (currentStatus != STATUS_MOVING)

return super.onTouchEvent(ev);

final float mUpX = ev.getRawX();

final float mUpY = ev.getRawY();

float vY = computeYVelocity();//松开时必须释放VelocityTracker资源

if (vY >= 1200 || Math.abs(mUpY - mDownY) > screenHeight / 4) {

//下滑速度快,或者下滑距离超过屏幕高度的一半,就关闭

if (iAnimClose != null) {

iAnimClose.onPictureRelease(currentShowView);

}

} else {

resetReviewState(mUpX, mUpY);

}

break;

}

return super.onTouchEvent(ev);

}

//返回浏览状态

private void resetReviewState(final float mUpX, final float mUpY) {

currentStatus = STATUS_RESETTING;

if (mUpY != mDownY) {

ValueAnimator valueAnimator = ValueAnimator.ofFloat(mUpY, mDownY);

valueAnimator.setDuration(BACK_DURATION);

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

float mY = (float) animation.getAnimatedValue();

float percent = (mY - mDownY) / (mUpY - mDownY);

float mX = percent * (mUpX - mDownX) + mDownX;

moveView(mX, mY);

if (mY == mDownY) {

mDownY = 0;

mDownX = 0;

currentStatus = STATUS_NORMAL;

}

}

});

valueAnimator.start();

} else if (mUpX != mDownX) {

ValueAnimator valueAnimator = ValueAnimator.ofFloat(mUpX, mDownX);

valueAnimator.setDuration(BACK_DURATION);

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

float mX = (float) animation.getAnimatedValue();

float percent = (mX - mDownX) / (mUpX - mDownX);

float mY = percent * (mUpY - mDownY) + mDownY;

moveView(mX, mY);

if (mX == mDownX) {

mDownY = 0;

mDownX = 0;

currentStatus = STATUS_NORMAL;

}

}

});

valueAnimator.start();

} else if (iAnimClose != null)

iAnimClose.onPictureClick();

}

//移动View

private void moveView(float movingX, float movingY) {

if (currentShowView == null)

return;

currentStatus = STATUS_MOVING;

float deltaX = movingX - mDownX;

float deltaY = movingY - mDownY;

float scale = 1f;

float alphaPercent = 1f;

if (deltaY > 0) {

scale = 1 - Math.abs(deltaY) / screenHeight;

alphaPercent = 1 - Math.abs(deltaY) / (screenHeight / 2);

}

ViewHelper.setTranslationX(currentShowView, deltaX);

ViewHelper.setTranslationY(currentShowView, deltaY);

scaleView(scale);

setBackgroundColor(getBlackAlpha(alphaPercent));

}

//缩放View

private void scaleView(float scale) {

scale = Math.min(Math.max(scale, MIN_SCALE_SIZE), 1);

ViewHelper.setScaleX(currentShowView, scale);

ViewHelper.setScaleY(currentShowView, scale);

}

private int getBlackAlpha(float percent) {

percent = Math.min(1, Math.max(0, percent));

int intAlpha = (int) (percent * 255);

return Color.argb(intAlpha,0,0,0);

}

private void addIntoVelocity(MotionEvent event) {

if (mVelocityTracker == null)

mVelocityTracker = VelocityTracker.obtain();

mVelocityTracker.addMovement(event);

}

private float computeYVelocity() {

float result = 0;

if (mVelocityTracker != null) {

mVelocityTracker.computeCurrentVelocity(1000);

result = mVelocityTracker.getYVelocity();

releaseVelocity();

}

return result;

}

private void releaseVelocity() {

if (mVelocityTracker != null) {

mVelocityTracker.clear();

mVelocityTracker.recycle();

mVelocityTracker = null;

}

}

@Override

public void onClick(View v) {

if (iAnimClose != null) {

iAnimClose.onPictureClick();

}

}

public interface IAnimClose {

void onPictureClick();

void onPictureRelease(View view);

}

}

需要进行缩放的View我这里在Adapter中添加回调设置,并且adapter可以实现更新的效果

public class ImagePagerAdapter extends FragmentStatePagerAdapter {

private DragViewPager mPager;

private ArrayList mFragmentList;

public ImagePagerAdapter(FragmentManager fm, List datas,DragViewPager pager) {

super(fm);

mPager=pager;

mPager.setAdapter(this);

updateData(datas);

}

public void updateData(List dataList) {

ArrayList fragments = new ArrayList<>();

for (int i = 0, size = dataList.size(); i < size; i++) {

final ImageDetailFragment fragment = ImageDetailFragment.newInstance(dataList.get(i));

fragment.setOnImageListener(new ImageDetailFragment.OnImageListener() {

@Override

public void onInit() {

View view = fragment.getView();

mPager.setCurrentShowView(view);

}

});

fragments.add(fragment);

}

setViewList(fragments);

}

private void setViewList(ArrayList fragmentList) {

if (mFragmentList != null) {

mFragmentList.clear();

}

mFragmentList = fragmentList;

notifyDataSetChanged();

}

@Override

public int getCount() {

return mFragmentList==null?0:mFragmentList.size();

}

public int getItemPosition(Object object) {

return POSITION_NONE;

}

@Override

public Fragment getItem(int position) {

return mFragmentList.get(position);

}

}

要实现透明度变化的效果还需要对activity设置theme

false

true

true

@android:color/transparent

android:theme="@style/translucent"/>

在需要使用的页面只需要调用即可

ImagePagerActivity.startImagePage(MainActivity.this,

urls,pos,recyclerView.getLayoutManager().findViewByPosition(pos));

在整个demo中采用的转场动画,需要设置共享元素,因此在需要使用的页面需要设置如下:

首先设置转场动画的共享元素,因为跳转和返回时都会调用onMapSharedElements,需要判断bundle是否为空,bundle会在返回的时候在onActivityReenter获取到

//设置转场动画的共享元素,因为跳转和返回时都会调用onMapSharedElements,需要判断bundle是否为空

setExitSharedElementCallback(new SharedElementCallback() {

@Override

public void onMapSharedElements(List names, Map sharedElements) {

if (bundle!=null){

int index = bundle.getInt(ImagePagerActivity.STATE_POSITION,0);

sharedElements.clear();

sharedElements.put("img", recyclerView.getLayoutManager().findViewByPosition(index));

bundle=null;

}

}

});

其次在返回的时候获取数据bundle

@Override

public void onActivityReenter(int resultCode, Intent data) {

super.onActivityReenter(resultCode, data);

bundle = data.getExtras();

int currentPosition = bundle.getInt(ImagePagerActivity.STATE_POSITION,0);

//做相应的滚动

recyclerView.scrollToPosition(currentPosition);

//暂时延迟 Transition 的使用,直到我们确定了共享元素的确切大小和位置才使用

//postponeEnterTransition后不要忘记调用startPostponedEnterTransition

ActivityCompat.postponeEnterTransition(this);

recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

@Override

public boolean onPreDraw() {

recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);

// TODO: figure out why it is necessary to request layout here in order to get a smooth transition.

recyclerView.requestLayout();

//共享元素准备好后调用startPostponedEnterTransition来恢复过渡效果

ActivityCompat.startPostponedEnterTransition(MainActivity.this);

return true;

}

});

}

完整的调用页面的代码如下:

public class MainActivity extends AppCompatActivity {

private RecyclerView recyclerView;

private MainAdapter mainAdapter;

//图片集合

private ArrayList urls;

//存放返回时当前页码

private Bundle bundle;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

urls=new ArrayList<>();

//为了显示效果,重复添加了三次

urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524477979306&di=3eb07e9302606048abe13d7b6a2bc601&imgtype=0&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201406%2F12%2F20140612211118_YYXAC.jpeg");

urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463580&di=1315bc4db30999f00b89ef79c3bb06e5&imgtype=0&src=http%3A%2F%2Fpic36.photophoto.cn%2F20150710%2F0005018721870517_b.jpg");

urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463575&di=6221f21bcb761675c5d161ebc53d5948&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201410%2F03%2F20141003112442_AkkuH.thumb.700_0.jpeg");

urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524477979306&di=3eb07e9302606048abe13d7b6a2bc601&imgtype=0&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201406%2F12%2F20140612211118_YYXAC.jpeg");

urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463580&di=1315bc4db30999f00b89ef79c3bb06e5&imgtype=0&src=http%3A%2F%2Fpic36.photophoto.cn%2F20150710%2F0005018721870517_b.jpg");

urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463575&di=6221f21bcb761675c5d161ebc53d5948&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201410%2F03%2F20141003112442_AkkuH.thumb.700_0.jpeg");

urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524477979306&di=3eb07e9302606048abe13d7b6a2bc601&imgtype=0&src=http%3A%2F%2Fimg4.duitang.com%2Fuploads%2Fitem%2F201406%2F12%2F20140612211118_YYXAC.jpeg");

urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463580&di=1315bc4db30999f00b89ef79c3bb06e5&imgtype=0&src=http%3A%2F%2Fpic36.photophoto.cn%2F20150710%2F0005018721870517_b.jpg");

urls.add("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524133463575&di=6221f21bcb761675c5d161ebc53d5948&imgtype=0&src=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201410%2F03%2F20141003112442_AkkuH.thumb.700_0.jpeg");

initView();

}

private void initView() {

recyclerView = (RecyclerView) findViewById(R.id.recycler);

recyclerView.setLayoutManager(new GridLayoutManager(this, 2));

mainAdapter = new MainAdapter(urls);

mainAdapter.setOnItemClickListener(new MainAdapter.OnItemClickListener() {

@Override

public void onItemClick(int pos) {

ImagePagerActivity.startImagePage(MainActivity.this,

urls,pos,recyclerView.getLayoutManager().findViewByPosition(pos));

}

});

recyclerView.setAdapter(mainAdapter);

//设置转场动画的共享元素,因为跳转和返回都会调用,需要判断bundle是否为空

setExitSharedElementCallback(new SharedElementCallback() {

@Override

public void onMapSharedElements(List names, Map sharedElements) {

if (bundle!=null){

int index = bundle.getInt(ImagePagerActivity.STATE_POSITION,0);

sharedElements.clear();

sharedElements.put("img", recyclerView.getLayoutManager().findViewByPosition(index));

bundle=null;

}

}

});

}

//返回的时候获取数据

@Override

public void onActivityReenter(int resultCode, Intent data) {

super.onActivityReenter(resultCode, data);

bundle = data.getExtras();

int currentPosition = bundle.getInt(ImagePagerActivity.STATE_POSITION,0);

//做相应的滚动

recyclerView.scrollToPosition(currentPosition);

//暂时延迟 Transition 的使用,直到我们确定了共享元素的确切大小和位置才使用

//postponeEnterTransition后不要忘记调用startPostponedEnterTransition

ActivityCompat.postponeEnterTransition(this);

recyclerView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

@Override

public boolean onPreDraw() {

recyclerView.getViewTreeObserver().removeOnPreDrawListener(this);

// TODO: figure out why it is necessary to request layout here in order to get a smooth transition.

recyclerView.requestLayout();

//共享元素准备好后调用startPostponedEnterTransition来恢复过渡效果

ActivityCompat.startPostponedEnterTransition(MainActivity.this);

return true;

}

});

}

}

需要查看完整代码点击这里,喜欢的请给个star,谢谢

最后

以上就是失眠毛衣最近收集整理的关于android仿微信下拉二楼_Android仿微信图片详情页面,可下拉关闭页面的全部内容,更多相关android仿微信下拉二楼_Android仿微信图片详情页面内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(96)

评论列表共有 0 条评论

立即
投稿
返回
顶部