qq空间相册不能上传原图了吗,qq空间精选照片怎么设置别人看不到

简介除了直播之外,弹幕还能用来做什么呢?看过QQ空间的人应该都知道,QQ空间是用弹幕来预览图片的。今天,为了学习目的,我们来实现QQ空间图片预览对话框。如果你上周刚好看了我的博客,你就知道上周我写了如何实现弹幕https://www.jianshu.com/p/2b1f4da434f3

如果你注意细节,这个库就会变得非常有趣。

弹幕的手势有很多(大部分来自PhotoView),根据幻灯片高度变化的背景透明度,以及各种动画。前面我们已经讨论过弹幕如何实现,本文不再讨论。实现了弹幕,但只是直接引用弹幕库:https://github.com/mCyp/Muti-Barrage

目录一、总体理解如果我们想实现QQ空间中的图片预览,我们可以用什么来实现呢?首先,我们的基础应该是Dialog。然后您还可以使用ViewPager 在图像之间进行切换。 ViewPager2支持垂直图像切换和更好的动画过渡。那样的话你就得把整个库迁移到Android库了,但是你还能大展身手吗?剩下的工作就相对轻松了,你主要负责处理触摸事件和动画。现在我们知道ViewPager+PhotoView+Muti-BarrageView以及手势处理+动画可以形成一个简单的QQ空间般的图片预览。

1.类图我们已经知道需要使用什么技术来实现它。现在让我们看一下主要的UML 类图,以便于对以下代码进行实际解释。

如果你聪明的话,你可能已经注意到这不是代理模式。那是对的

2. 练习代码既然我们已经讨论过UML 类图,那么让我们从UML 类图顺序开始吧。

“1.IPhotoPager”

publicinterfaceIPhotoPager{voidshow();voiddismiss();voidsetConfig(Configconfig);/*config*/classConfig{Listpaths;//图片路径Listbitmaps;//BitmapbooleancanDelete=true;//普通主题booleanisShowAnimation=false;//显示是否动漫booleanisShowBarrage=true;//是否显示弹幕intanimationType;//动画类型intstartPosition=0;//图片起始位置DeleteListenerdeleteListener;//删除监听Listbarrages;//弹幕数据}}IPhotoPager 定义了必须的数据类型的基本约束使用。

“2.基本寻呼机”

publicabstractclassBasePagerextendsDialogimplementsViewPager.OnPageChangeListener,IPhotoPager{protectedContextmContext;//allbaseinfoprivateIPhotoPager.ConfigmConfig;//basicinfoprotectedintcurPosition;protectedbooleanisCanDelete;protectedbooleanisShowAnimation;protectedintanimationType;protectedDeleteListenerdeleteListener;protected booleanis ShowBarrages;protectedListbitmap s;protectedListbarrages;publicBasePager(@NonNullContextcontext){this(context,R.style.Dialog ) ; publicBasePager(@NonNullContextcontext,intthemeResId){super(context,themeResId);mContext=context;}@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);Windowwindow=getWindow();if(window!=null){window . setDimAmount (1f);}} //.省略一些ViewPager接口@OverridepublicvoidsetConfig(Configconfig){this.mConfig=config;initParams();}/*initparameter*/privatevoidinitParams(){this.isCanDelete=mConfig .canDelete ; this.isShowAnimation=mConfig.isShowAnimation;this.animationType=mConfig.animationType;this.curPosition=mConfig.startPosition;//initbitmapsthis.bitmaps=newArrayList();this.bitmaps.addAll(mConfig.bitmaps);this. mConfig .deleteListener;this.barrages=mConfig.barrages;this.isShowBarrages=mConfig.isShowBarrage;}@Overridepublicvoidshow(){if(bitmaps==null||bitmaps.size()==0){ thrownewRuntimeException(\’bitmapscan \’tbenull \’ );}super.show();//设置rect必须在dialog.showing()之后,否则dialog会在initialsize中显示。Rectrect=newRect();((Activity)mContext).getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);//设置positionandsizeWindowwindow=getWindow ();WindowManager.LayoutParamslp=window.getAttributes();lp.gravity=Gravity.BOTTOM;lp.width=WindowManager.LayoutParams.MATCH_PARENT;lp.height=rect.height();window.setAttributes(lp) ;if ( isShowAnimation){if(animationType==ANIMATION_SCALE_ALPHA){window.setWindowAnimations(R.style.PhotoPagerScale);}elseif(animationType==ANIMATION_TRANSLATION){window.setWindowAnimations(R.style.PhotoPagerTranslation);}else{//defaultanimaiontistranslationwindow. setWindowAnimations(R.style.PhotoPagerAlpha);}}}}BasePager的内容也很简单,它实现了ViewPager的监听器,但是在第二步中它使用检索到的Config来填充基础数据。

《3.QQ寻呼机》

QQPager 有近400 行代码,所以我将把它分解并逐步引导您完成它。

3.1 数据初始化

数据初始化主要分为ViewPager和Muti-BarrageView初始化。作为一个快速的初始化过程,我们在这里只介绍数据。

publicclassQQPagerextendsBasePager{privatestaticfinalStringTAG=\’QQPager\’;privatestaticfinalintSCROLL_THRESHolD=100;//滑动阈值privatestaticfinalintMSG_UP=0;privateImageViewmBarrage;//弹幕切换privateMyViewPagermPhotoPager;//简单处理的ViewPager privateTextViewmPosition;//位置信息privatePhotoP gerAdaptermAdapter;//ViewPager项PhotoViewprivateBarrage ViewmBarrageView就是。 privateBarrageAdaptermBarrageAdapter; privatebooleanisInittouchSloop;//滑动阈值privatefloatlastX;//最后一个事件的坐标privatebooleanisorizontalmove=false;privatebooleanisVerticalMove=false;privatebooleanisMove=false;privateateintclickCount=0;//判断是单击还是双击。对于双击,必须传递给PhotoView进行处理privateHandlermHandler=newQQPagerHandler(this);privatestaticclassQQPagerHandlerextendsHandler{privateWeakReferencemQQPagerReference;QQPagerHandler(QQPagerqqPager){this.mQQPagerReference=newWeakReference(qqPager);}@Overridepublicvoidhandle Message(Messagemsg){ super. );switch (msg.what){caseMSG_UP:if(mQQPagerReference.get().clickCount==1)mQQPagerReference.get().dismiss();elsemQQPagerReference.get().clickCount=0;break }} }classTextViewHolderextendsBarrageAdapter.BarrageViewHolder {//.省略代码}classViewHolderextendsBarrageAdapter.BarrageViewHolder{//.省略代码}} 根据需要省略了两类弹幕持有者的一些基本数据和代码。你可以看看源代码。 QQPagerHandler的作用是检测双击。下面解释一下具体过程。

3.2 事件分发

如果您是使用过PhotoView的学生,您可能知道双击会放大图像,但既然您使用的是PhotoView,那当然是一样的,以下是直播事件时需要考虑的要点。

单击可关闭图像预览。您需要阻止发送触摸事件,Dialog 将自动处理该事件。双击必须传递给ViewPager,ViewPager 将其传递给PhotoView 进行处理。水平移动是ViewPager内部的图像切换,事件会传递给ViewPager进行处理。垂直移动意味着移动ViewPager,这是由Dialog本身处理的,ViewPager的垂直滑动距离影响背景的透明度。

话虽如此,我想你需要明白,我们只需要处理单击和双击,以及垂直和水平决策。看一下代码。

publicbooleanddispatchTouchEvent(@NonNullMotionEventev){if(ishorizontalmove)returnsuper.dispatchTouchEvent(ev);floatcurX=ev.getX();//获取当前坐标floatcurY=ev.getY();switch(ev.getAction() ){caseMotionEvent.setAlpha(1f);//Action_Down触发位置文本的显示mPosition.setVisibility(View.VISIBLE);isMove=false;clickCount++;//点击次数增加break;caseMotionEvent. curY-lastY ;if(Math.abs(deltaX)touchSloop||Math.abs(deltaY)touchSloop){isMove=true;//由于滑动距离超过阈值,点击次数会自动重置clickCount=0; } if(Math.abs(deltaX)SCROLL_THRESHolD ){scrollCloseAnimation();}else{rollbackAnimation();}}break;}returnsuper.onTouchEvent(event);} 添加很多你想要的项目的代码注释非常详细。这里的东西:

单击和双击由QQPagerHandler决定,延迟发送400毫秒。 400 毫秒内单击一次将执行关闭动画。再次点击将重置点击次数。 QQPager处理onTouchEvent时,通过getWindow().setDimamount(1f – offsetPercent)改变背景透明度。垂直移动会阻止ViewPager 事件的触发,因此当您松开手指时,该事件最终会被传递进行处理,并且如果垂直移动距离大于您设置的最小滑动阈值,则会出现滑动关闭动画。将被执行。否则,ViewPager 将回滚并移动到其初始位置。让我们看一下手势处理、双击、水平移动和垂直移动。

3.3 动画处理

预览图像需要两种类型的动画:视图动画和属性动画。有关详细信息,请参阅上面的BasePager 的show() 方法。属性动画使用的场景有位置文本的定时显示、回滚、ViewPager滑动退出。在这里我们将解释幻灯片的结尾。

privatevoidscrollCloseAnimation(){Windowwindow=getWindow();if(window!=null)window.setDimAmount(0f);if(deltaY0){mPhotoPager.animate().y(mPhotoPager.getMeasuredHeight()).setDuration(600).setListener (newSimpleAnimationListener(){@OverridepublicvoidonAnimationEnd(Animatoranimation){super.onAnimationEnd(animation);//getWindow().setWindowAnimations(R.style.PhotoPagerAlpha);dismiss();}}).start();}else{mPhotoPager. animate().y(-mPhotoPager.getMeasuredHeight()).setDuration(600).setListener(newSimpleAnimationListener(){@OverridepublicvoidonAnimationEnd(Animatoranimation){super.onAnimationEnd(animation);//getWindow().setWindowAnimations(R.style. PhotoPagerAlpha);dismiss();}}).start();}} 我不得不说,要使用属性动画,在视图本身上使用animate() 非常方便。用了很多次感觉还是不错的~

“4.PhotoPagerViewProxy”

最后,我们介绍以下主要用于构造数据的代理类:

publicclassPhotoPagerViewProxyimplementsIPhotoPager{publicstaticfinalintTYPE_NORMAL=1;publicstaticfinalintTYPE_QQ=2;publicstaticfinalintTYPE_WE_CHAT=3;publicstaticfinalintANIMATION_SCALE_ALPHA=1;publicstaticfinalintANIMATION_TRANSLATION=2;publicstaticfinalintANIMATION_ALPHA=3;privateBasePagerphotoPageView;privatePhotoPagerViewProxy(inttype,Configconfig){开关(类型){caseTYPE_QQ:photoPageView=newQQPager(context,R.style .Dialog);break;caseTYPE_WE_CHAT:break;default:photoPageView=newNormalPager(context,R.style.Dialog);break;}setConfig(config);}@Overridepublicvoidshow(){photoPageView.show();}@Overridepublicvoiddismiss(){photoPageView. ( );}@OverridepublicvoidsetConfig(Configconfig){photoPageView.setConfig(config);}publicstaticclassBuilder{privateActivitycontext;privateIPhotoPager.Configconfig;privateinttype;publicBuilder(Activitycontext,inttype){this.context=context;this.config=newIPhotoPager.Config( ) ; this.type=type;}publicBuilder(Activitycontext){//defaulttypeisTYPE_NORMALthis(context,TYPE_NORMAL);}//.另外,省略大部分代码。您需要让构建器了解的是,这是初始化数据。 mode publicPhotoPagerViewProxycreate(){returnnewPhotoPagerViewProxy(context,type,config);}}} 3.总结总的来说,代码量并不大,难度也不是很大。然而,这段代码仍然有很大的改进空间。 ViewPager垂直滑动距离变化没那么快,背景透明度增加等当然,我的水平有限,难免有错误。如有问题,欢迎指正。

就这些了~ Demo地址:https://github.com/mCyp/PhotoPagerView

Android核心知识点笔记github:https://github.com/AndroidCot/Android

本文和图片来自网络,不代表火豚游戏立场,如若侵权请联系我们删除:https://www.huotun.com/game/643970.html

(0)
上一篇 2024年5月29日
下一篇 2024年5月29日

相关推荐

  • 和平精英键位初始键位设置号码?

    和平精英键位初始键位设置号码? 没有一个特定的初始键位设置号码,因为这个设置是根据玩家个人的操作习惯和键位偏好来进行的。但是一般来说,在游戏开始时,玩家需要点击屏幕中央的“操作”按钮,进入到“设置”页面,再选择“控制”选项,根据自己的喜好进行键位设置。在这个页面中,玩家可以设置移动、射击、切换武器、投掷物品、瞄准等操作的键位,同时还可以进行灵敏度、视角等设置…

    游戏快讯 1小时前
  • 和平精英身法必备的枪?

    和平精英身法必备的枪? 是步枪。步枪是一种全能性枪械,具有中远距离射击、连发和单发射击等多种功能,可以应对多种情况,而且精准度高,不易误伤队友。在和平精英游戏中,体现身法的关键就是要快速切换姿势,而步枪可以快速切换姿势并进行精准射击,因此是必备的。除了步枪外,一些玩家可能会选择短枪或冲锋枪等快速射击的武器来体现身法。但是这些武器的精准度和射程都相对较低,容易…

    游戏快讯 2小时前
  • 和平精英的牌子怎么获得?

    和平精英的牌子怎么获得? 方法/步骤: 1. 打开和平精英,登录好账号;进入到主页后,点击右下角的直播图标 2. 进入到直播页面之后,切换右上角的页签到“我的” 3. 在“我的”页面中,点击进入“任务中心”;通过完成任务,获取赛事币 4. 退出“任务中心”,返回到“直播”的页签;点击“助威”按钮 和平精英花瓣如何获得? 通过参加和平精英游戏内的各种活动,包括…

    游戏快讯 4小时前
  • 和平精英怎么开变声器免费?

    和平精英怎么开变声器免费? 1. 首先打开和平营地 2. 在和平营地里选择营地工具 3. 然后打开变声器 4. 启动游戏,就可以在和平精英开免费的变声器了 和平精英变声器怎么关? 1.点击设置 2.从游戏中找到游戏设置选项并点击一下。 3.点击声音设置 4.在设置界面找到“声音设置”选项进入。 5.关闭变声器 6.在变声器栏下点击关闭按钮即可。 和平精英如何…

    游戏快讯 5小时前
  • 和平精英无敌版怎么获得礼包?

    和平精英无敌版怎么获得礼包? 礼包领取大全: 1、官网礼包,官网这里是有预约的礼包,玩家可以领取到下载的专属套装,188金币、海滨突袭套装、头盔皮肤、首款背包,玩家可以领取很多的助力礼包,奖励和平精英中的助力礼包。 2、游戏网站礼包,玩家直接通过官网去领取对应的礼包,这里是有大量的专属礼包有需要的玩家可以去领取。 3、购买礼包,玩家也可以去购买礼包,这种礼包…

    游戏快讯 7小时前