日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

【Android视图效果】共享元素实现仿微信查看大图效果

發(fā)布時(shí)間:2025/3/21 Android 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android视图效果】共享元素实现仿微信查看大图效果 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在之前的文章中,我們通過(guò)動(dòng)畫實(shí)現(xiàn)了這個(gè),具體可以查看【Android 動(dòng)畫】動(dòng)畫詳解之仿微信查看大圖效果(四),這里,我們用過(guò)度動(dòng)畫來(lái)實(shí)現(xiàn)。

什么是共享元素?

它是Android 5.0新加入的一種過(guò)度動(dòng)畫,主要用于2個(gè)activity之間,可以共享某些控件,實(shí)現(xiàn)無(wú)縫轉(zhuǎn)場(chǎng)的動(dòng)畫。

如何使用?

1.為共享元素指定統(tǒng)一的 transition name 2.啟動(dòng) Activity 時(shí)帶上共享元素參數(shù)

效果圖

錄制的gif 不是很流暢,實(shí)際效果還是很流暢的

首先,我們需要一個(gè)九宮格,9張圖片

list = new ArrayList<>();list.add("http://img1.imgtn.bdimg.com/it/u=4206294871,879077254&fm=26&gp=0.jpg");list.add("http://img1.imgtn.bdimg.com/it/u=1901690610,3955011377&fm=200&gp=0.jpg");list.add("http://img3.imgtn.bdimg.com/it/u=1546158593,2358526642&fm=200&gp=0.jpg");list.add("http://img0.imgtn.bdimg.com/it/u=3792909229,2321547963&fm=200&gp=0.jpg");list.add("http://img4.imgtn.bdimg.com/it/u=1621655683,865218969&fm=200&gp=0.jpg");list.add("http://img5.imgtn.bdimg.com/it/u=4286838121,1364454560&fm=26&gp=0.jpg");list.add("http://img5.imgtn.bdimg.com/it/u=551944592,1654216059&fm=26&gp=0.jpg");list.add("http://img1.imgtn.bdimg.com/it/u=2550323596,2167297465&fm=200&gp=0.jpg");list.add("http://img4.imgtn.bdimg.com/it/u=952962361,1269259737&fm=26&gp=0.jpg");wxAdapter = new WxAdapter(list);rvWx2.setLayoutManager(new GridLayoutManager(WX2Activity.this, 3));rvWx2.setAdapter(wxAdapter);wxAdapter.bindToRecyclerView(rvWx2); 復(fù)制代碼

WxAdapter,這里使用的是 BaseRecyclerViewAdapterHelper

class WxAdapter extends BaseQuickAdapter<String, BaseViewHolder> {public WxAdapter(List<String> list) {super(R.layout.item_wx2, list);}@Overrideprotected void convert(BaseViewHolder helper, String item) {ImageView iv_img = helper.getView(R.id.iv_wx_img);Glide.with(mContext).load(item).apply(new RequestOptions().centerCrop()).into(iv_img);}} 復(fù)制代碼

item_wx2.xml,請(qǐng)注意這里的指定了transitionName,這個(gè)可以自定義,只需和目標(biāo)view統(tǒng)一即可

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/iv_wx_img"android:layout_width="match_parent"android:transitionName="share"android:layout_height="0dp"app:layout_constraintDimensionRatio="1:1" /></android.support.constraint.ConstraintLayout> 復(fù)制代碼

當(dāng)點(diǎn)擊圖片時(shí),我們需要跳轉(zhuǎn)至查看大圖頁(yè)面

wxAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {@Overridepublic void onItemClick(BaseQuickAdapter adapter, View view, int position) {ImageView iv = view.findViewById(R.id.iv_wx_img);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {share(iv, position);}}}); 復(fù)制代碼

此處的share 需與之前布局保持一致

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)private void share(View view, int position) {Intent intent = new Intent(WX2Activity.this, Img2Activity.class);intent.putStringArrayListExtra(Img2Activity.IMG_KEY, list);intent.putExtra(Img2Activity.IMG_POSITION, position);Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this, view, "share").toBundle();startActivity(intent, bundle);} 復(fù)制代碼

Img2Activity ,這里我們使用RecyclerView+PagerSnapHelper,關(guān)于PagerSnapHelper,在之前的文章中,已經(jīng)說(shuō)過(guò),這里不再細(xì)述。具體可以查看【Android 進(jìn)階】仿抖音系列之翻頁(yè)上下滑切換視頻(四)

private void initView() {imgList = getIntent().getStringArrayListExtra(IMG_KEY);enterPosition = getIntent().getIntExtra(IMG_POSITION, 0);snapHelper = new PagerSnapHelper();snapHelper.attachToRecyclerView(rvPreview);imgAdapter = new ImgAdapter(imgList);rvPreview.setLayoutManager(new LinearLayoutManager(Img2Activity.this, LinearLayoutManager.HORIZONTAL, false));rvPreview.setAdapter(imgAdapter);imgAdapter.bindToRecyclerView(rvPreview);rvPreview.scrollToPosition(enterPosition); } 復(fù)制代碼

這里,取出之前傳遞的值,并初始化 ImgAdapter

class ImgAdapter extends BaseQuickAdapter<String, BaseViewHolder> {public ImgAdapter(List<String> list) {super(R.layout.item_img, list);}@Overrideprotected void convert(BaseViewHolder helper, String item) {ImageView iv_img = helper.getView(R.id.iv_img);Glide.with(mContext).load(item).into(iv_img);}} 復(fù)制代碼

item_img,transitionName 需要與之前保持一致,此處PhotoView支持手勢(shì)放大,不需要的可以用ImageView代替

<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><com.ch.animdemo.phoneView.PhotoViewandroid:id="@+id/iv_img"android:layout_width="0dp"android:layout_height="0dp"android:transitionName="share"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /></android.support.constraint.ConstraintLayout> 復(fù)制代碼

到這里,基本效果已經(jīng)實(shí)現(xiàn)了,不過(guò)還有2個(gè)坑要填。 1.當(dāng)我們運(yùn)行時(shí)會(huì)發(fā)現(xiàn),會(huì)出現(xiàn)Img2Activity出現(xiàn)是小圖,而不是我們期望的大圖。 這是因?yàn)?#xff0c;加載網(wǎng)絡(luò)圖片需要時(shí)間,如果過(guò)度動(dòng)畫執(zhí)行太快,圖片還沒(méi)有加載出來(lái),而glide緩存策略是按加載的尺寸+圖片路徑緩存,由于之前緩存過(guò)小圖,所以當(dāng)大圖沒(méi)有加載出來(lái)時(shí),會(huì)顯示小圖。 所以我們剛進(jìn)入界面時(shí),需要延遲過(guò)度動(dòng)畫的執(zhí)行

// 延遲共享動(dòng)畫的執(zhí)行postponeEnterTransition(); 復(fù)制代碼

當(dāng)圖片加載完成時(shí),才繼續(xù)執(zhí)行過(guò)度動(dòng)畫

//圖片加載完成的回調(diào)中,啟動(dòng)過(guò)渡動(dòng)畫startPostponedEnterTransition(); 復(fù)制代碼

2.當(dāng)我們滑動(dòng)大圖界面,然后返回時(shí)會(huì)發(fā)現(xiàn),返回動(dòng)畫依然是進(jìn)入大圖界面的位置,所以我們需要判斷,如果滑動(dòng)過(guò),就需要更新返回時(shí)的位置。 修改之前Img2Activity的initview方法如下:

private void initView() {// 延遲共享動(dòng)畫的執(zhí)行postponeEnterTransition();imgList = getIntent().getStringArrayListExtra(IMG_KEY);enterPosition = getIntent().getIntExtra(IMG_POSITION, 0);currentPosition = enterPosition;snapHelper = new PagerSnapHelper() {@Overridepublic int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {currentPosition = super.findTargetSnapPosition(layoutManager, velocityX, velocityY);return currentPosition;}};snapHelper.attachToRecyclerView(rvPreview);imgAdapter = new ImgAdapter(imgList);rvPreview.setLayoutManager(new LinearLayoutManager(Img2Activity.this, LinearLayoutManager.HORIZONTAL, false));rvPreview.setAdapter(imgAdapter);imgAdapter.bindToRecyclerView(rvPreview);rvPreview.scrollToPosition(enterPosition);} 復(fù)制代碼

finishAfterTransition重寫finishAfterTransition,傳遞最新的position

@Overridepublic void finishAfterTransition() {Intent intent = new Intent();if (enterPosition == currentPosition) {//沒(méi)有改變intent.putExtra(IMG_CURRENT_POSITION, -1);} else {intent.putExtra(IMG_CURRENT_POSITION, currentPosition);}setResult(RESULT_OK, intent);super.finishAfterTransition();} 復(fù)制代碼

然后在WX2Activity中處理

@Overridepublic void onActivityReenter(int resultCode, Intent data) {if (resultCode == RESULT_OK && data != null) {int exitPos = data.getIntExtra(Img2Activity.IMG_CURRENT_POSITION, -1);final View exitView = getExitView(exitPos);if (exitView != null) {ActivityCompat.setExitSharedElementCallback(this, new SharedElementCallback() {@Overridepublic void onMapSharedElements(List<String> names, Map<String, View> sharedElements) {names.clear();sharedElements.clear();names.add(ViewCompat.getTransitionName(exitView));sharedElements.put(Objects.requireNonNull(ViewCompat.getTransitionName(exitView)), exitView);setExitSharedElementCallback(new SharedElementCallback() {});}});}}}private View getExitView(int position) {if (position == -1) {return null;}if (wxAdapter != null) {return wxAdapter.getViewByPosition(position, R.id.iv_wx_img);}return null;} 復(fù)制代碼

最后獻(xiàn)上源碼 github

你的認(rèn)可,是我堅(jiān)持更新博客的動(dòng)力,如果覺(jué)得有用,就請(qǐng)點(diǎn)個(gè)贊,謝謝

總結(jié)

以上是生活随笔為你收集整理的【Android视图效果】共享元素实现仿微信查看大图效果的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。