AndroidRecyclerView仿QQ滑动门菜单右滑菜单

Android开发中HorizontalScrollView即可实现横向水平滑动,若想实现左滑弹出菜单,右滑隐藏菜单需要修改HorizontalScrollView默认滑动事件。假设菜单长度为100像素,即左滑View向右移动100像素,右滑View向左移动100像素。

这里写图片描述

核心代码如下:
SwipeScrollView 封装的滑动页

public class SwipeScrollView extends HorizontalScrollView {
    private RelativeLayout container;//主内容容器
    private LinearLayout operate;//操作子项容器
    private int scrollWidth=0,scroll;//滚动距离
    private boolean swipe = false;//是否滑动
    private OnSwipeListener onSwipeListener;
    public SwipeScrollView(Context context) {
        super(context);
    }

    public SwipeScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SwipeScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
        this.onSwipeListener = onSwipeListener;
    }

    /***
     * 关闭菜单
     */
    public void closeMenu(){
        swipe = false;
        scroll=0;
        smoothScrollTo(0,0);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        container = (RelativeLayout)findViewById(R.id.item_container);
        operate = (LinearLayout)findViewById(R.id.item_operate);
        //设置容器宽度
        container.setLayoutParams(new LinearLayout.LayoutParams(ScreenHelper.getScreenWidth(getContext()), ViewGroup.LayoutParams.MATCH_PARENT));
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    //滑动距离大于10弹出隐藏菜单
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if(MotionEvent.ACTION_DOWN==ev.getAction())
            scroll=getScrollX();
        else if(MotionEvent.ACTION_UP==ev.getAction()){
            scroll = getScrollX()-scroll;
            if(scroll>10 || scroll<-10){
                scroll = swipe?0:scrollWidth;
                swipe = !swipe;
                if(onSwipeListener!=null)
                    onSwipeListener.onSwipe(swipe,SwipeScrollView.this);
            }
            else
                scroll = swipe?scrollWidth:0;
            //View移动动画
            smoothScrollTo(scroll,0);
            return true;
        }
        return super.onTouchEvent(ev);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //onMeasure计算后设置滑动的滚动宽度
        scrollWidth = operate.getMeasuredWidth();
        for(int i=0;i<operate.getChildCount();i++){
            final int position = i;
            operate.getChildAt(i).setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    //菜单点击事件
                    onSwipeListener.onMenuClick(position);
                }
            });
        }
       container.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //主内容点击事件  若菜单栏已打开关闭滑动菜单
                if(swipe){
                    swipe = false;
                    if(onSwipeListener!=null)
                        onSwipeListener.onSwipe(swipe,SwipeScrollView.this);
                }
                else{
                    if(onSwipeListener!=null)
                        onSwipeListener.onClick();
                }
            }
        });
        super.onLayout(changed, l, t, r, b);
    }

}

OnSwipeListener 滑动监听接口


/***
 * 滑动菜单监听
 */
public interface OnSwipeListener {

    /***
     * 滑动
     * @param swipe
     * @param view
     */
    void onSwipe(boolean swipe, View view);

    /***
     * 主内容点击
     */
    void onClick();

    /***
     * 子菜单点击
     * @param menuPosition
     */
    void onMenuClick(int menuPosition);
}

OnItemClickListener RecyclerView子项单击接口

public interface OnItemClickListener {
    void onItemClick(RecyclerView.ViewHolder viewHolder,int position);
}

OnMenuClickListener 菜单单击接口

public interface OnMenuClickListener {
    void onMenuClick(SwipeScrollAdapter.ItemViewHolder viewHolder,int position, int operatePosition);
}

SwipeScrollAdapter 滑动页适配器

public class SwipeScrollAdapter extends RecyclerView.Adapter<SwipeScrollAdapter.ItemViewHolder>{
    private List<PushMessage> mMessageList;
    private int mLayout;
    private int swipePosition=-1;
    private View swipeView;
    private OnItemClickListener onItemClickListener;
    private OnMenuClickListener onMenuClickListener;

    public void setOnMenuClickListener(OnMenuClickListener onMenuClickListener) {
        this.onMenuClickListener = onMenuClickListener;
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public SwipeScrollAdapter(int layout,List<PushMessage> messageList) {
        mMessageList = messageList;
        mLayout = layout;
    }

    @Override
    public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(mLayout, parent, false);
        ItemViewHolder itemViewHolder = new ItemViewHolder(view);
        return itemViewHolder;
    }

    /***
     * 获取当前滑动菜单位置 -1没有滑动菜单
     * @return
     */
    public int getSwipePosition() {
        return swipePosition;
    }

    /***
     * 初始化当前菜单
     * @param position
     * @param view
     */
    public void openMenu(int position,View view){
        swipePosition = position;
        swipeView = view;
    }

    /***
     * 删除子项
     * @param position 子项位置
     */
    public void closeMenu(int position){
        ((SwipeScrollView)swipeView).closeMenu();
        swipePosition=-1;
        swipeView=null;
        mMessageList.remove(position);
        notifyItemRemoved(position);
    }

    /***
     * 关闭当前滑动菜单
     */
    public void closeMenu(){
        ((SwipeScrollView)swipeView).closeMenu();
        swipePosition=-1;
        swipeView=null;
    }

    @Override
    public void onBindViewHolder(final ItemViewHolder holder, int position) {
        //先执行自定义TouchListener事件,再执行SwipeScrollView的onTouchEvent事件
        holder.swipeScrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //若未有滑动菜单或者滑动的菜单为当前菜单执行SwipeScrollView的onTouchEvent事件,否则关闭当前菜单
                if (swipePosition == -1 || swipePosition ==holder.getAdapterPosition())
                    return false;
                else {
                    closeMenu();
                    return true;
                }
            }
        });
        holder.swipeScrollView.setOnSwipeListener(new OnSwipeListener() {
            //左滑弹出菜单,右滑隐藏菜单
            @Override
            public void onSwipe(boolean swipe, View view) {
                if (swipe)
                    openMenu(holder.getAdapterPosition(), view);
                else
                    closeMenu();
            }

            @Override
            public void onClick() {
                //其他菜单子项点击后关闭当前菜单
                if (swipePosition != -1)
                    closeMenu();
                else{
                    if(onItemClickListener!=null)
                        onItemClickListener.onItemClick(holder,holder.getAdapterPosition());
                }
            }

            @Override
            public void onMenuClick(int operatePosition) {
                if(onMenuClickListener!=null){
                    onMenuClickListener.onMenuClick(holder,holder.getAdapterPosition(),operatePosition);
                }
            }
        });
        holder.read.setVisibility(mMessageList.get(position).isRead()?View.INVISIBLE:View.VISIBLE);
        holder.text.setText(mMessageList.get(position).getContent());
        holder.time.setText(DateHelper.toDate(mMessageList.get(position).getDate(),"HH:mm"));
    }

    @Override
    public int getItemCount() {
        return mMessageList.size();
    }

    public static class ItemViewHolder extends RecyclerView.ViewHolder {
        public SwipeScrollView swipeScrollView;
        public TextView text;
        public TextView time;
        public ImageView read;
        public RelativeLayout container;

        public ItemViewHolder(View itemView) {
            super(itemView);
            swipeScrollView = (SwipeScrollView)itemView.findViewById(R.id.scrollView);
            read = (ImageView)itemView.findViewById(R.id.item_read);
            text = (TextView)itemView.findViewById(R.id.item_text);
            time = (TextView)itemView.findViewById(R.id.item_time);
            container = (RelativeLayout)itemView.findViewById(R.id.item_container);
        }
    }
}

RoomFragment 实例页

public class RoomFragment extends BaseFragment {
    private RecyclerView recyclerView;
    private SwipeScrollAdapter adapter;
    private List<PushMessage> messageList;
    @Override
    public void onUpdateView(Object data) {
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_recycyclerview, container, false);
        messageList = new ArrayList<>();
        messageList.add(new PushMessage(1,String.valueOf(0),"A区"+0,false,new Date()));
        messageList.add(new PushMessage(1,String.valueOf(1),"A区"+1,false,new Date()));
        for(int i=2;i<10;i++){
            messageList.add(new PushMessage(1,String.valueOf(i),"A区"+i,true,new Date()));
        }
        adapter = new SwipeScrollAdapter(R.layout.fragment_room_item,messageList);
        recyclerView = (RecyclerView)view.findViewById(R.id.list);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setAdapter(adapter);
        recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //recyclerView上下滑动执行,若当前菜单不为空关闭当前菜单
                if (adapter.getSwipePosition() != -1) {
                    adapter.closeMenu();
                    return true;
                }
                return false;
            }
        });
        //子项单击事件
        adapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(RecyclerView.ViewHolder viewHolder, int position) {
                startActivity(new Intent(getContext(), CheckActivity.class));
            }
        });
        //子项菜单单击事件
        adapter.setOnMenuClickListener(new OnMenuClickListener() {
            @Override
            public void onMenuClick(SwipeScrollAdapter.ItemViewHolder viewHolder, int position, int operatePosition) {
                switch (operatePosition){
                    case 0:clean(viewHolder,position,operatePosition);break;
                    default:delete(position);break;
                }
            }
        });
        return view;
    }

    //未读改为已读
    private void clean(SwipeScrollAdapter.ItemViewHolder viewHolder, int position, int operatePosition){
        View menu = viewHolder.swipeScrollView.getChildAt(operatePosition);
        menu.setClickable(false);
        try {
            Thread.sleep(2000);
        }
        catch (Exception e){
            e.printStackTrace();
        }
        delete(position);
    }

    //删除
    private void delete(int position){
        adapter.closeMenu(position);
    }
}

PushMessage 数据实体

public class PushMessage {
    private int type;
    private String id;
    private String content;
    private boolean read;
    private Date date;
    public PushMessage(){

    }
    public PushMessage(int type, String id, String content,boolean read, Date date) {
        this.type = type;
        this.id = id;
        this.content = content;
        this.date = date;
        this.read = read;
    }

    public boolean isRead() {
        return read;
    }

    public void setRead(boolean read) {
        this.read = read;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

fragment_recycyclerview.xml 实例布局页

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:id="@id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

fragment_room_item.xml 实例菜单子项布局页

<?xml version="1.0" encoding="utf-8"?>
<com.room.control.scrollview.SwipeScrollView  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@id/scrollView"
    android:scrollbars="none"
    android:background="@color/white"
    android:layout_width="match_parent"
    android:layout_height="60dp">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <RelativeLayout
            android:orientation="horizontal"
            android:id="@id/item_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <View
                android:layout_alignParentBottom="true"
                android:background="@color/grey"
                android:layout_width="match_parent"
                android:layout_height="2px"/>
            <ImageView
                android:id="@id/item_read"
                android:layout_marginTop="1dp"
                android:visibility="visible"
                android:background="@drawable/read"
                android:layout_width="30dp"
                android:layout_height="30dp" />
            <LinearLayout
                android:padding="10dp"
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="60dp">

                <TextView
                    android:id="@id/item_text"
                    android:textSize="20dp"
                    android:textColor="#555"
                    android:gravity="left|center"
                    android:layout_marginRight="50dp"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
                <TextView
                    android:id="@id/item_time"
                    android:gravity="right|center"
                    android:layout_marginLeft="-40dp"
                    android:layout_width="40dp"
                    android:layout_height="match_parent" />
            </LinearLayout>
        </RelativeLayout>
        <LinearLayout
            android:orientation="horizontal"
            android:id="@id/item_operate"
            android:layout_width="wrap_content"
            android:layout_height="match_parent">
            <Button
                android:id="@id/item_check"
                android:text="@string/checked"
                android:background="#fe9d00"
                android:textColor="@color/white"
                android:layout_width="80dp"
                android:layout_height="match_parent" />
            <Button
                android:id="@id/item_delete"
                android:text="@string/delete"
                android:background="@color/orangered"
                android:textColor="@color/white"
                android:layout_width="80dp"
                android:layout_height="match_parent" />
        </LinearLayout>
    </LinearLayout>


</com.room.control.scrollview.SwipeScrollView>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值