Android仿淘宝商品详情页
程序员文章站
2023-02-16 15:12:58
看到有人在问如何实现淘宝商品详情页效果,献上效果图
大致梳理一下思路,这里不提供源码
状态栏透明使用开源库statusbarcompat,为了兼容手机4.4...
看到有人在问如何实现淘宝商品详情页效果,献上效果图
大致梳理一下思路,这里不提供源码
状态栏透明使用开源库statusbarcompat,为了兼容手机4.4
dependencies { compile ('com.github.niorgai:statusbarcompat:2.1.4', { exclude group: 'com.android.support' }) } allprojects { repositories { ... maven { url "https://jitpack.io" } } }
标题栏图标透明度变化参考api setalpha()已过时
icon.setimagealpha(0);
banner控件为viewpager,淘宝显示为正方形,这里需要修改viewpager measure函数
public class ideaviewpager extends viewpager { private point point; public ideaviewpager(context context) { this(context,null); } public ideaviewpager(context context, attributeset attrs) { super(context, attrs); windowmanager windowmanager = (windowmanager) context.getsystemservice(context.window_service); point = new point(); windowmanager.getdefaultdisplay().getsize(point); } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); setmeasureddimension(point.x,point.x); } }
测量view高度,获取到高度集合绑定到scrollview,根据scrollview滑动距离判断是属于哪一个tab选项
public int getmeasureheight(view view){ int width = view.measurespec.makemeasurespec(0, view.measurespec.unspecified); int height = view.measurespec.makemeasurespec(0, view.measurespec.unspecified); view.measure(width, height); return view.getmeasuredheight(); }
重新onscrollchanged函数,实现viewpager滑动速度比其他view慢
@override protected void onscrollchanged(int l, int t, int oldl, int oldt) { super.onscrollchanged(l, t, oldl, oldt); if (viewpager != null && t != oldt) { viewpager.settranslationy(t/2); } }
根据限定距离(banner)计算百分比偏移量,实现颜色渐变、透明度渐变(淘宝商品详情页有二次颜色渐变)
@override protected void onscrollchanged(int l, int t, int oldl, int oldt) { super.onscrollchanged(l, t, oldl, oldt); if(viewpager!=null&&t<=point.x-headerheight&&getonscrollchangedcolorlistener()!=null){ getonscrollchangedcolorlistener().onchanged(math.abs(t)/float.valueof(point.x-headerheight)); if(t<=(point.x-headerheight)/2){ getonscrollchangedcolorlistener().onchangedfirstcolor(t/(point.x-headerheight)/2); }else{ getonscrollchangedcolorlistener().onchangedsecondcolor((t-(point.x-headerheight)/2)/(point.x-headerheight)/2); } } int currentposition = getcurrentposition(t,arraydistance); if(currentposition!=position&&getonselectedindicatechangedlistener()!=null){ getonselectedindicatechangedlistener().onselectedchanged(currentposition); } this.position = currentposition; }
单一颜色渐变透明度,还原argb通道,修改a值
ideascrollview.setonscrollchangedcolorlistener(new ideascrollview.onscrollchangedcolorlistener() { @override public void onchanged(float percentage) { int color = getalphacolor(percentage>0.9f?1.0f:percentage); header.setbackgrounddrawable(new colordrawable(color)); radiogroup.setbackgrounddrawable(new colordrawable(color)); icon.setimagealpha((int) ((percentage>0.9f?1.0f:percentage)*255)); radiogroup.setalpha((percentage>0.9f?1.0f:percentage)*255); setradiobuttontextcolor(percentage); } @override public void onchangedfirstcolor(float percentage) { } @override public void onchangedsecondcolor(float percentage) { } }); ideascrollview.setonselectedindicatechangedlistener(new ideascrollview.onselectedindicatechangedlistener() { @override public void onselectedchanged(int position) { isneedscrollto = false; radiogroup.check(radiogroup.getchildat(position).getid()); isneedscrollto = true; } }); public int getalphacolor(float f){ return color.argb((int) (f*255),0x09,0xc1,0xf4); }
tab选项属性不能太频繁,会有颜色值闪烁情况出现,这里需要策略
public void setradiobuttontextcolor(float percentage){ if(math.abs(percentage-currentpercentage)>=0.1f){ for(int i=0;i<radiogroup.getchildcount();i++){ radiobutton radiobutton = (radiobutton) radiogroup.getchildat(i); radiobutton.settextcolor(radiobutton.ischecked()?getradiocheckedalphacolor(percentage):getradioalphacolor(percentage)); } this.currentpercentage = percentage; } }
判断当前属于哪个选项,根据滑动距离与传入绑定的view高度集合来计算
private int getcurrentposition(int t, arraylist<integer> arraydistance) { int index = 0; for (int i=0;i<arraydistance.size();i++){ if(i==arraydistance.size()-1){ index = i; }else { if(t>=arraydistance.get(i)&&t<arraydistance.get(i+1)){ index = i; break; } } } return index; }
切换选项卡以及回到顶部按钮的具体实现参考scrollto函数
private void scrolltoposition(int position){ scrollto(0,arraydistance.get(position)); }
以上代码实现了上图效果,当然也可以使用recyclerview abslistview做容器。
希望对大家的学习有所帮助,也希望大家多多支持。