热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Android仿淘宝商品详情页

这篇文章主要为大家详细介绍了Android仿淘宝商品详情页,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

看到有人在问如何实现淘宝商品详情页效果,献上效果图

大致梳理一下思路,这里不提供源码

状态栏透明使用开源库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&#63;1.0f:percentage);
    header.setBackgroundDrawable(new ColorDrawable(color));
    radioGroup.setBackgroundDrawable(new ColorDrawable(color));
    icon.setImageAlpha((int) ((percentage>0.9f&#63;1.0f:percentage)*255));
    radioGroup.setAlpha((percentage>0.9f&#63;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

判断当前属于哪个选项,根据滑动距离与传入绑定的View高度集合来计算

private int getCurrentPosition(int t, ArrayList arrayDistance) {

 int index = 0;
 for (int i=0;i=arrayDistance.get(i)&&t

切换选项卡以及回到顶部按钮的具体实现参考scrollTo函数

private void scrollToPosition(int position){
 scrollTo(0,arrayDistance.get(position));
 }

以上代码实现了上图效果,当然也可以使用RecyclerView AbsListView做容器。

希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 在《Python编程基础》课程中,我们将深入探讨Python中的循环结构。通过详细解析for循环和while循环的语法与应用场景,帮助初学者掌握循环控制语句的核心概念和实际应用技巧。此外,还将介绍如何利用循环结构解决复杂问题,提高编程效率和代码可读性。 ... [详细]
  • Redis哈希数据结构入门指南
    Redis的哈希数据结构与Java中的HashMap类似,采用数组加链表的方式实现。数组用于存储哈希值的位置,而链表则用于处理哈希冲突的情况。此外,Redis的哈希数据结构还支持高效的字段操作和内存优化,适用于多种应用场景,如缓存和会话管理。 ... [详细]
  • 在处理大数相加的问题时,有许多方法可以借鉴。本文介绍了两种不同的函数式编程方法:一种是从网络上找到的经典实现,另一种是作者自行设计的创新方案。通过函数式编程的方式重新实现了这两种方法,其中经典实现简洁明了,而创新方案则在性能和可读性方面有所提升。这些方法不仅适用于大数相加,还可以扩展应用于其他数值计算场景。 ... [详细]
  • 大家好,全新的技术专栏《从零开始掌握容器云网络实战》正式上线。该专栏将系统地介绍容器云网络的基础知识、核心技术和实际应用案例,帮助读者全面理解和掌握容器云网络的关键技术与实践方法。 ... [详细]
  • Golomb 编码是一种高效的变长编码技术,专门用于整数的压缩。该方法通过预定义的参数 \( M \) 将输入整数分解为商 \( q \) 和余数 \( r \) 两部分。具体而言,输入整数除以 \( M \) 得到商 \( q \) 和余数 \( r \),其中商 \( q \) 采用一元编码表示,而余数 \( r \) 则使用二进制编码。这种编码方式在数据压缩和信息传输中具有显著的优势,特别是在处理具有特定概率分布的数据时表现出色。 ... [详细]
  • 在使用Block时,正确的声明方法和确保线程安全是至关重要的。为了保证Block在堆中分配,应使用`copy`修饰符进行声明,因为栈中的Block与栈的生命周期绑定,容易导致内存问题。此外,还需注意Block捕获外部变量的行为,以避免潜在的循环引用和数据不一致问题。建议深入研究相关文档,以掌握更多高级技巧和最佳实践。 ... [详细]
  • 深入解析 Android TextView 中 getImeActionLabel() 方法的使用与代码示例 ... [详细]
  • K3Cloud 平台字符串解密技术详解与应用
    在 K3Cloud 平台中,配置文件内的敏感信息如密码会被加密处理。通过深入研究,我们发现可以通过 Kingdee.BOS.Api 提供的接口对这些加密字符串进行解密。本文详细介绍了这一解密技术的具体实现方法及其应用场景,为开发者提供了宝贵的参考和实践指导。此外,还探讨了该技术在数据安全和系统管理中的重要性,以及如何在实际项目中高效地应用这些技术,确保系统的稳定性和安全性。 ... [详细]
  • 在GitHub上克隆vue-element-admin项目时遇到依赖安装错误
    在 GitHub 上克隆 vue-element-admin 项目后,使用 `npm install` 安装依赖时遇到了未知的 Git 错误。具体错误信息为 `npm ERR! code 128`,提示命令执行失败。这可能是由于网络问题、Git 配置不正确或某些依赖包的仓库地址无效导致的。建议检查网络连接、更新 Git 版本并确保所有依赖项的 URL 正确无误。 ... [详细]
  • CentOS 7环境下Jenkins的安装与前后端应用部署详解
    CentOS 7环境下Jenkins的安装与前后端应用部署详解 ... [详细]
  • 在尝试为 Unity 编译一个简单的 Java 库时,运行 `ant jar` 命令后遇到了 Java I/O 异常。具体错误信息为“无法启动程序 ${aAPT},错误代码 2”,这通常表示指定的文件或目录不存在。此问题可能是由于环境配置不正确或路径设置有误导致的。建议检查相关路径和环境变量,确保所有依赖项都已正确安装和配置。 ... [详细]
  • 本文深入探讨了在Spring Boot中处理RESTful风格的表单请求的方法,包括请求参数处理、请求映射以及RESTful设计原则的应用。文章详细介绍了如何利用HTTP动词(如GET、POST、PUT、DELETE)来操作资源,并结合Spring Boot的注解(如@GetMapping、@PostMapping等)实现高效、清晰的请求处理逻辑。通过实例分析,展示了如何在实际项目中应用这些技术,提高开发效率和代码可维护性。 ... [详细]
  • 基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析
    基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析 ... [详细]
  • 设计模式详解:模板方法模式的应用与实现
    模板方法模式是一种行为设计模式,通过定义一个操作中的算法骨架,将具体步骤的实现延迟到子类中。本文详细解析了模板方法模式的类图结构、实现方式以及挂钩机制,并结合实际案例进行了深入探讨。此外,文章还提供了丰富的参考资料,帮助读者更好地理解和应用这一设计模式。对于手机用户,建议横屏阅读以获得更佳的阅读体验。 ... [详细]
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
author-avatar
xxyy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有