先来看看淘宝、唯品会长按商品的效果,以及简单Demo的效果:

    

 

首先分析一下场景:

  1. 长按条目时,弹出遮罩的效果遮挡在原来的条目布局上;
  2. 页面滑动或点击其他的条目,上一个正在遮罩的条目遮罩消失。
  3. 长按其他条目时,上一个遮罩的条目撤销遮罩,当前长按的显示遮罩;
  4. 条目添加遮罩的时添加动画;

1. 遮罩的效果,我们会很容易的想到Android布局控件FrameLayout布局,是基于叠加在上方的布局。所以在列表条目布局的时候,可以使用FrameLayout布局,在长按列表条目时,用条目的根布局添加一个遮罩的布局,就达到我们想要的效果了。

2. 记录当前长按的根布局,如果点击或长按其他的列表条目,亦或滑动页面(添加活动监听)时,就取消之前长按的条目遮罩,从条目根布局中删除遮罩布局就OK了;

3. 可以利用View动画或属性动画,在添加遮罩布局时显示动画;

接下来, 来撸一下代码吧:

 1. 首先,先定义一下遮罩的布局,根据需求自定义View

/***
* 长按条目遮罩界面
*/
public class ItemMaskLayout extends LinearLayout { public ItemMaskLayout(Context context) {
this(context, null);
} public ItemMaskLayout(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
} public ItemMaskLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
LayoutInflater.from(context).inflate(R.layout.layout_product_list_item_mask, this, true); findViewById(R.id.tv_find_same).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mItemMaskClickListener != null) {
mItemMaskClickListener.findTheSame();
}
}
}); findViewById(R.id.tv_collection).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mItemMaskClickListener != null) {
mItemMaskClickListener.collection();
}
}
});
} public ItemMaskClickListener mItemMaskClickListener; public void setMaskItemClickListener(ItemMaskClickListener listener) {
this.mItemMaskClickListener = listener;
} //提供遮罩中按钮点击操作接口 自定义
public interface ItemMaskClickListener {
void findTheSame();
void collection();
}
}

2. 封装一个帮助类,主要是根据该类的成员变量根据长按的条目指向列表Item的布局,然后为条目添加遮罩的效果;

/**
* 长按条目添加遮罩操作帮助类
*/
public class ItemLongClickMaskHelper { private FrameLayout mRootFrameLayout;
private ItemMaskLayout mMaskItemLayout;
private Context mContext;
private ScaleAnimation anim;
private String productId; public ItemLongClickMaskHelper(Context context){
this.mContext = context;
mMaskItemLayout = new ItemMaskLayout(mContext);
anim = new ScaleAnimation(
0f, 1.0f, 1.0f, 1.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f
);
anim.setDuration(300);
mMaskItemLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismissItemMaskLayout();
}
}); mMaskItemLayout.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
dismissItemMaskLayout();
return true;
}
}); mMaskItemLayout.setMaskItemClickListener(new ItemMaskLayout.ItemMaskClickListener() {
@Override
public void findTheSame() {
ToastUtil.showCustomToast("找相似 " + productId);
} @Override
public void collection() {
ToastUtil.showCustomToast("收藏 " + productId);
}
});
} public ItemLongClickMaskHelper setRootFrameLayout(FrameLayout frameLayout, String fundId){
if (mRootFrameLayout != null){
mRootFrameLayout.removeView(mMaskItemLayout);
}
mRootFrameLayout = frameLayout;
this.productId = fundId;
mRootFrameLayout.addView(mMaskItemLayout);
mMaskItemLayout.startAnimation(anim);
return this;
} public ItemLongClickMaskHelper setMaskItemListener(ItemMaskLayout.ItemMaskClickListener listener){
this.mMaskItemLayout.setMaskItemClickListener(listener);
return this;
} /**
* 遮罩消失
*/
public void dismissItemMaskLayout(){
if (mRootFrameLayout != null){
mRootFrameLayout.removeView(mMaskItemLayout);
}
}
}

3.注意在滑动RecyclerView列表的时候,监听滑动,撤销遮罩,直接定义RecyclerView的子类,添加滑动监听回调;

public class TouchCallbackRecyclerView extends RecyclerView {

    public TouchCallbackRecyclerView(Context context) {
super(context);
} public TouchCallbackRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
} public TouchCallbackRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} public interface ScrollCallback {
/**
* 滑动手指抬起事件
*
* @param diffY 抬起时相对于按下时的偏移量<br/>大于0:列表往下拉, 小于0: 列表往上拉
*/
void onTouchUp(float diffY);
} private ScrollCallback mScrollCallback; public void setScrollCallback(ScrollCallback callback) {
this.mScrollCallback = callback;
} private float mDownY, mMovingY, mUpY;
private boolean isUp = false; @SuppressWarnings("deprecation")
private static final float SLOP = ViewConfiguration.getTouchSlop(); @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownY = ev.getY();
isUp = false; break;
case MotionEvent.ACTION_MOVE:
mMovingY = ev.getY();
isUp = false;
break;
case MotionEvent.ACTION_UP:
mUpY = ev.getY();
isUp = true;
break;
}
if (isUp && mScrollCallback != null && Math.abs(mUpY - mDownY) > SLOP) {
mScrollCallback.onTouchUp(mMovingY - mDownY);
}
return super.dispatchTouchEvent(ev);
}
}

以上就是主要的代码实现部分,灵活地扩展应用ItemLongClickMaskHelper基本就能实现类似淘宝长按遮罩效果了。

源码地址:https://github.com/denluoyia/ItemLongClickMaskDemo

Android之淘宝商品列表长按遮罩效果的更多相关文章

  1. iOS 相似淘宝商品详情查看翻页效果的实现

    基本思路: 1.设置一个 UIScrollView 作为视图底层,而且设置分页为两页 2.然后在第一个分页上加入一个 UITableView 而且设置表格可以上提载入(上拉操作即为让视图滚动到下一页) ...

  2. 【原创smarty仿淘宝商品图片轮播+放大镜效果】

    1.去掉图片集字段,字符串的多余字符 $goods_pic_display=$row[DISPLAY];$goods_pic_display1=str_replace('"', '', $g ...

  3. Selenium+Chrome/phantomJS模拟浏览器爬取淘宝商品信息

    #使用selenium+Carome/phantomJS模拟浏览器爬取淘宝商品信息 # 思路: # 第一步:利用selenium驱动浏览器,搜索商品信息,得到商品列表 # 第二步:分析商品页数,驱动浏 ...

  4. python3编写网络爬虫16-使用selenium 爬取淘宝商品信息

    一.使用selenium 模拟浏览器操作爬取淘宝商品信息 之前我们已经成功尝试分析Ajax来抓取相关数据,但是并不是所有页面都可以通过分析Ajax来完成抓取.比如,淘宝,它的整个页面数据确实也是通过A ...

  5. python爬虫学习(三):使用re库爬取"淘宝商品",并把结果写进txt文件

    第二个例子是使用requests库+re库爬取淘宝搜索商品页面的商品信息 (1)分析网页源码 打开淘宝,输入关键字“python”,然后搜索,显示如下搜索结果 从url连接中可以得到搜索商品的关键字是 ...

  6. Python爬虫之定时抢购淘宝商品

    Python爬虫之定时抢购淘宝商品 import time from selenium import webdriver import datetime class Spider: def __ini ...

  7. python 获取淘宝商品信息

    python cookie 获取淘宝商品信息 # //get_goods_from_taobao import requests import re import xlsxwriter cok='' ...

  8. 3.使用Selenium模拟浏览器抓取淘宝商品美食信息

    # 使用selenium+phantomJS模拟浏览器爬取淘宝商品信息 # 思路: # 第一步:利用selenium驱动浏览器,搜索商品信息,得到商品列表 # 第二步:分析商品页数,驱动浏览器翻页,并 ...

  9. 爬取淘宝商品信息,放到html页面展示

    爬取淘宝商品信息 import pymysql import requests import re def getHTMLText(url): kv = {'cookie':'thw=cn; hng= ...

随机推荐

  1. 海量数据挖掘MMDS week6: 支持向量机Support-Vector Machines,SVM

    http://blog.csdn.net/pipisorry/article/details/49445387 海量数据挖掘Mining Massive Datasets(MMDs) -Jure Le ...

  2. Unity插件 - MeshEditor(一) 3D线段作画 & 模型网格编辑器

    之前,因为工作需要,项目中需要动态生成很多的电线,不能事先让模型做好,更不能用LineRenderer之类的,因为画出来没有3D的效果,最主要是拐角的时候还容易破面,而我们要的是真真实实纯3D的电线, ...

  3. 【shell脚本练习】grep sed awk

    下面是简单学习之后做得练习题,如果有不对的或者说解题思路不好的,请交流啊. Grep 练习 文件名grepfile Steve Blenheim:238-923-7366:95 Latham Lane ...

  4. 15_Android中任务栈

     1.一个应用程序一般都是由多个activity组成的. 2.任务栈(task stack)(别名backstack后退栈)记录存放用户开启的activity的. 3.一个应用程序一被开启系统就给 ...

  5. GDB 资料汇总

    很全的关于 GDB 调试的指导: GDB中应该知道的几个调试方法 用 GDB 调试程序 100个gdb调试小技巧 CGDB中文手册 Beej's Quick Guide to GDB

  6. unity 快速创建小地图

    先写一个纹理遮罩shader Shader "Unlit/TexMask" { Properties { _MainTex ("Texture", 2D) =  ...

  7. 【Coding算法导论】第4章:最大子数组问题

    Coding算法导论 本系列文章主要针对算法导论一书上的算法,将书中的伪代码用C++实现 代码未经过大量数据测试,如有问题,希望能在回复中指出! (一)问题描述 给定一个数组,求数组中连续的子数组的和 ...

  8. myeclipse和输入法冲突的问题

    问题:在myeclipse中编写注释的时候,偶尔出现繁体字的现象令人头疼. 原因:myeclipse中格式化快捷键为"ctrl+shift+f" 与搜狗输入法快捷键冲突.按下后输入 ...

  9. 导入android SlidingMenu 应用

    SlidingMenu is a helpful Android library for developers. It creates a side navigation like the Faceb ...

  10. 关于GPL329A中获取摄像头sensor id的问题

    首先我拿到了sensor_id应用程序的源码,我要在上面添加获取ov2685 的 sensor id的代码. 利用find . -name  get_sensor_id找到该代码编译之后生成的a.ou ...