精华内容
下载资源
问答
  • 主要为大家详细介绍了Android实现QQ侧滑删除置顶等功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • android:id="@+id/btnTop" android:layout_width="60dp" android:layout_height="match_parent" android:background="#d9dee4" android:text="置顶" android:textColor="@android:color/white"/> android:id="@+id/...

    基本实现思路

    通过自定义View的方式实现步骤:

    1、自定义ViewGroup

    2、在onLayout 中,获取childView并对他们进行布局,这一步比较重要,content 占满屏幕,菜单View 在屏幕之外,当滑动的时候,content滑屏幕,menu 进入屏幕,就达到了我需要的效果,布局草图如下:

    6aa308996238

    image

    3、重写dispatchTouchEvent和onInterceptTouchEvent方法拦截事件和处理滚动。滑动效果的实现既可以用Scroller,也可以用属性动画ValueAnimator。

    添加依赖

    //侧滑SwipeRecyclerView

    implementation 'com.yanzhenjie:recyclerview-swipe:1.1.4'

    1、SwipeRevealLayout

    SwipeRevealLayout 使用简单、代码入侵低,不但支持左右侧滑菜单,还支持上下滑出菜单。可以配合各种布局使用,包括RecyclerView 、ListView、ScrollView 等,效果很赞

    使用方式:

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    app:mode="same_level"

    app:dragEdge="left">

    android:layout_width="wrap_content"

    android:layout_height="match_parent" />

    android:layout_width="match_parent"

    android:layout_height="match_parent" />

    在adapterclass 中:

    public class Adapter extends RecyclerView.Adapter {

    // This object helps you save/restore the open/close state of each view

    private final ViewBinderHelper viewBinderHelper = new ViewBinderHelper();

    public Adapter() {

    // uncomment the line below if you want to open only one row at a time

    // viewBinderHelper.setOpenOnlyOne(true);

    }

    @Override

    public void onBindViewHolder(ViewHolder holder, int position) {

    // get your data object first.

    YourDataObject dataObject = mDataSet.get(position);

    // Save/restore the open/close state.

    // You need to provide a String id which uniquely defines the data object.

    viewBinderHelper.bind(holder.swipeRevealLayout, dataObject.getId());

    // do your regular binding stuff here

    }

    }

    private class ViewHolder extends RecyclerView.ViewHolder {

    private SwipeRevealLayout swipeLayout;

    private View frontLayout;

    private View deleteLayout;

    private TextView textView;

    public ViewHolder(View itemView) {

    super(itemView);

    swipeLayout = (SwipeRevealLayout) itemView.findViewById(R.id.swipe_layout);

    frontLayout = itemView.findViewById(R.id.front_layout);

    deleteLayout = itemView.findViewById(R.id.delete_layout);

    textView = (TextView) itemView.findViewById(R.id.text);

    }

    public void bind(final String data) {

    deleteLayout.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

    mDataSet.remove(getAdapterPosition());

    notifyItemRemoved(getAdapterPosition());

    }

    });

    textView.setText(data);

    frontLayout.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View view) {

    String displayText = "" + data + " clicked";

    Toast.makeText(mContext, displayText, Toast.LENGTH_SHORT).show();

    Log.d("RecyclerAdapter", displayText);

    }

    });

    }

    }

    效果图:

    6aa308996238

    image

    6aa308996238

    image

    6aa308996238

    image

    2、SwipeDelMenuLayout

    和SwipeRevealLayout差不多。

    使用方式:

    在RecyclerView、ListView 可直接使用,在Adapter 中,在item布局最外层包上

    SwipeMenuLayout就好。

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="100dp"

    android:clickable="true"

    android:paddingBottom="1dp">

    android:id="@+id/content"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:background="?android:attr/selectableItemBackground"

    android:gravity="center"

    android:text="项目中我是任意复杂的原ContentItem布局"/>

    android:id="@+id/btnTop"

    android:layout_width="60dp"

    android:layout_height="match_parent"

    android:background="#d9dee4"

    android:text="置顶"

    android:textColor="@android:color/white"/>

    android:id="@+id/btnUnRead"

    android:layout_width="120dp"

    android:layout_height="match_parent"

    android:background="#ecd50a"

    android:clickable="true"

    android:text="标记未读"

    android:textColor="@android:color/white"/>

    android:id="@+id/btnDelete"

    android:layout_width="60dp"

    android:layout_height="match_parent"

    android:background="@color/red_ff4a57"

    android:text="删除"

    android:textColor="@android:color/white"/>

    效果图:

    6aa308996238

    image

    6aa308996238

    image

    3、AndroidSwipeLayout

    出自代码家大神,功能强大,支持上下左右四个方向滑出菜单,可单独使用,也支持RecyclerView 和 ListView等列表,Adapter需要继承RecylerViewAdapter或者BaseSwipeAdapter。

    使用:

    android:layout_width="match_parent" android:layout_height="80dp">

    android:background="#66ddff00"

    android:id="@+id/bottom_wrapper"

    android:layout_width="160dp"

    android:weightSum="1"

    android:layout_height="match_parent">

    android:padding="10dp"

    android:background="#ffffff"

    android:layout_width="match_parent"

    android:layout_height="match_parent">

    代码中:

    SwipeLayout swipeLayout = (SwipeLayout)findViewById(R.id.sample1);

    //set show mode.

    swipeLayout.setShowMode(SwipeLayout.ShowMode.LayDown);

    //add drag edge.(If the BottomView has 'layout_gravity' attribute, this line is unnecessary)

    swipeLayout.addDrag(SwipeLayout.DragEdge.Left, findViewById(R.id.bottom_wrapper));

    swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() {

    @Override

    public void onClose(SwipeLayout layout) {

    //when the SurfaceView totally cover the BottomView.

    }

    @Override

    public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) {

    //you are swiping.

    }

    @Override

    public void onStartOpen(SwipeLayout layout) {

    }

    @Override

    public void onOpen(SwipeLayout layout) {

    //when the BottomView totally show.

    }

    @Override

    public void onStartClose(SwipeLayout layout) {

    }

    @Override

    public void onHandRelease(SwipeLayout layout, float xvel, float yvel) {

    //when user's hand released.

    }

    });

    配合RecyclerView 和ListView 等列表的使用,请看github给出的 Samples

    效果图:

    6aa308996238

    image

    4、SwipeRecyclerView

    本库的一大特色是它滑出的菜单可以是左右排列的,也可以是上下排列,提供多种选择,不过侵入性稍微有点高,需要使用本库提供的SwipeRecyclerView,但是使用方式与提供的api和原生的RecyclerView是一样的。还有它通过代码来创建划出的菜单。如下:

    // 设置监听器。

    swipeRecyclerView.setSwipeMenuCreator(mSwipeMenuCreator);

    // 创建菜单:

    SwipeMenuCreator mSwipeMenuCreator = new SwipeMenuCreator() {

    @Override

    public void onCreateMenu(SwipeMenu leftMenu, SwipeMenu rightMenu, int position) {

    SwipeMenuItem deleteItem = new SwipeMenuItem(mContext)

    ...; // 各种文字和图标属性设置。

    leftMenu.addMenuItem(deleteItem); // 在Item左侧添加一个菜单。

    SwipeMenuItem deleteItem = new SwipeMenuItem(mContext)

    ...; // 各种文字和图标属性设置。

    leftMenu.addMenuItem(deleteItem); // 在Item右侧添加一个菜单。

    // 注意:哪边不想要菜单,那么不要添加即可。

    }

    };

    // 菜单点击监听。

    swipeRecyclerView.setOnItemMenuClickListener(mItemMenuClickListener);

    OnItemMenuClickListener mItemMenuClickListener = new OnItemMenuClickListener() {

    @Override

    public void onItemClick(SwipeMenuBridge menuBridge, int position) {

    // 任何操作必须先关闭菜单,否则可能出现Item菜单打开状态错乱。

    menuBridge.closeMenu();

    // 左侧还是右侧菜单:

    int direction = menuBridge.getDirection();

    // 菜单在Item中的Position:

    int menuPosition = menuBridge.getPosition();

    }

    };

    效果图:

    6aa308996238

    image

    6aa308996238

    image

    6aa308996238

    image

    5、RecyclerViewUndoSwipe

    一个可以拖拽和侧滑的UI效果,动画非常炫。

    效果图:

    6aa308996238

    image

    它没有封装成库,是一个效果demo,具体使用方式和实现,可以去看源码

    展开全文
  • 适配器中的代码,就是普通的RecyclerView适配器,我们只需要把删除置顶的两个点击回调,写2个对应删除置顶的方法即可。删除方法,就是list集合删除当前的position,然后notifyDataSetChanged一下就可以了,置顶...

    android:orientation=“vertical”>






    </com.mcxtzhang.swipemenulib.SwipeMenuLayout>

    适配器中的代码,就是普通的RecyclerView适配器,我们只需要把删除、置顶的两个点击回调,写2个对应删除、置顶的方法即可。删除方法,就是list集合删除当前的position,然后notifyDataSetChanged一下就可以了,置顶方法就是list集合,添加当前的position到集合的起始位置。

    class SampleAdapter(val list: ArrayList): RecyclerView.Adapter<SampleAdapter.ViewHolder>() {
    inner class ViewHolder(view:View):RecyclerView.ViewHolder(view){
    val tvName:TextView=view.findViewById(R.id.tvName)
    val btnTop:TextView=view.findViewById(R.id.btnTop)
    val btnDelete:TextView=view.findViewById(R.id.btnDelete)
    }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SampleAdapter.ViewHolder {
    val view=LayoutInflater.from(parent.context).inflate(R.layout.item_sample,parent,false)
    return ViewHolder(view)
    }

    override fun getItemCount()=list.size

    override fun onBindViewHolder(holder: SampleAdapter.ViewHolder, position: Int) {
    holder.tvName.setText(list.get(position))

    //删除按钮
    holder.btnDelete.setOnClickListener {
    onItemClickDelete.invoke(it,position)
    }
    //置顶按钮
    holder.btnTop.setOnClickListener {
    onItemClickTop.invoke(it,position)
    }
    }

    //删除
    fun delete(position: Int){
    list.removeAt(position)
    notifyDataSetChanged()
    }
    //置顶
    fun top(position: Int){
    list.add(0,list.removeAt(position))
    notifyDataSetChanged()
    }

    lateinit var onItemClickDelete: (v: View, pos: Int) -> Unit//删除
    lateinit var onItemClickTop: (v: View, pos: Int) -> Unit//置顶
    }

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>

    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android”
    xmlns:app=“http://schemas.android.com/apk/res-auto”
    xmlns:tools=“http://schemas.android.com/tools”
    android:layout_width=“match_parent”
    android:layout_height=“match_parent”
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_sample"
    android:layout_width=“match_parent”
    android:layout_height=“match_parent”/>

    </androidx.constraintlayout.widget.ConstraintLayout>

    MainAcivity

    class MainActivity : AppCompatActivity() {
    private lateinit var rvSample:RecyclerView
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    rvSample=findViewById(R.id.rv_sample)

    //布局管理器
    val layoutManager=LinearLayoutManager(this)
    layoutManager.orientation=LinearLayoutManager.VERTICAL
    rvSample.layoutManager=layoutManager

    val list=ArrayList()
    //集合添加数据

    展开全文
  • Android实现QQ的侧滑置顶删除本博客向大家介绍Android实现QQ侧滑(删除置顶等)功能。主要包括Android实现QQ侧滑(删除置顶等)功能。本博客里面的全部依赖于Android里面的原生控件,不需要依赖于第三方架包来实现...

    Android实现QQ的侧滑置顶、删除

    本博客向大家介绍Android实现QQ侧滑(删除、置顶等)功能。主要包括Android实现QQ侧滑(删除、置顶等)功能。本博客里面的全部依赖于Android里面的原生控件,不需要依赖于第三方架包来实现。

    1.效果图展示

    2.代码实现

    目标结构

    布局文件activity_main.xml

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:orientation="vertical"

    android:layout_height="match_parent"

    tools:context=".MainActivity">

    android:id="@+id/line1"

    android:layout_width="match_parent"

    android:layout_height="match_parent"/>

    布局文件item.xml

    android:layout_width="match_parent"

    android:layout_height="match_parent">

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:scrollbars="none">

    android:id="@+id/line0"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:gravity="center">

    android:layout_width="75dp"

    android:layout_height="75dp"

    android:src="@mipmap/touxiang" />

    android:id="@+id/title"

    android:layout_width="0dp"

    android:layout_height="wrap_content"

    android:layout_weight="1"

    android:gravity="center_vertical"

    android:paddingLeft="15dp"

    android:text=""

    android:textSize="15dp" />

    android:id="@+id/tv_zhidin"

    android:layout_width="wrap_content"

    android:layout_height="match_parent"

    android:background="#bfbfbf"

    android:gravity="center"

    android:paddingLeft="15dp"

    android:paddingTop="10dp"

    android:paddingRight="15dp"

    android:paddingBottom="10dp"

    android:text="置顶"

    android:textColor="#fff" />

    android:id="@+id/tv_shanchu"

    android:layout_width="wrap_content"

    android:layout_height="match_parent"

    android:background="#f00"

    android:gravity="center"

    android:paddingLeft="15dp"

    android:paddingTop="10dp"

    android:paddingRight="15dp"

    android:paddingBottom="10dp"

    android:text="删除"

    android:textColor="#fff" />

    自定义控件BaseHorizontalScrollView.java

    package com.example.qqclient;

    import android.content.Context;

    import android.util.AttributeSet;

    import android.view.MotionEvent;

    import android.widget.HorizontalScrollView;

    public class BaseHorizontalScrollView extends HorizontalScrollView {

    private float mOffsetX,mOffsetY; //横纵偏移

    private float mLastPostX,mLastPostY; //上次落点

    private int mInterval;

    public BaseHorizontalScrollView(Context context, AttributeSet attrs) {

    super(context, attrs);

    }

    @Override

    public boolean onInterceptHoverEvent(MotionEvent event) {

    boolean result;

    switch (event.getAction()){

    case MotionEvent.ACTION_DOWN:

    mOffsetX=0.0F;

    mOffsetY=0.0F;

    mLastPostX=event.getX();

    mLastPostY=event.getY();

    result=super.onInterceptHoverEvent(event);

    break;

    default://其余动作

    float thisPosX=event.getX();

    float thisPosY=event.getY();

    mOffsetX+=Math.abs(thisPosX-mLastPostX);//X轴偏差

    mLastPostY+=Math.abs(thisPosY-mLastPostY);//Y轴偏差

    mLastPostX=thisPosX;

    mLastPostY=thisPosY;

    if (mOffsetX

    result=true;

    }else{

    result=false;

    }

    break;

    }

    return result;

    }

    }

    4.适配器MyAdapter.java

    package com.example.qqclient;

    import android.content.Context;

    import android.view.LayoutInflater;

    import android.view.View;

    import android.view.ViewGroup;

    import android.widget.BaseAdapter;

    import android.widget.LinearLayout;

    import android.widget.TextView;

    import java.util.ArrayList;

    import java.util.List;

    public class MyAdapter extends BaseAdapter {

    List list=new ArrayList<>();

    Context context;

    public void set(List list) {

    this.list = list;

    notifyDataSetChanged();

    }

    public MyAdapter(Context context) {

    this.context = context;

    }

    @Override

    public int getCount() {

    return list.size();

    }

    @Override

    public Object getItem(int i) {

    return list.get(i);

    }

    @Override

    public long getItemId(int i) {

    return i;

    }

    @Override

    public View getView(final int i, View view, ViewGroup viewGroup) {

    View view1 = LayoutInflater.from(context).inflate(R.layout.item, null);

    ViewHolder holder = new ViewHolder(view1);

    LinearLayout.LayoutParams linearParams = (LinearLayout.LayoutParams) holder.title.getLayoutParams();

    linearParams.width = MainActivity.widthPixels;// 控件的宽强制设置

    holder.title.setLayoutParams(linearParams); //使设置好的布局参数应用到控件

    holder.title.setText(list.get(i));

    holder.tv_shanchu.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View view) {

    list.remove(i);

    notifyDataSetChanged();

    }

    });

    holder.tv_zhidin.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View view) {

    String title1=list.get(i);

    list.remove(i);

    list.add(0,title1);

    notifyDataSetChanged();

    }

    });

    return view1;

    }

    public static

    class ViewHolder {

    public View rootView;

    public TextView title;

    public TextView tv_zhidin;

    public TextView tv_shanchu;

    public LinearLayout line0;

    public ViewHolder(View rootView) {

    this.rootView = rootView;

    this.title = (TextView) rootView.findViewById(R.id.title);

    this.tv_zhidin = (TextView) rootView.findViewById(R.id.tv_zhidin);

    this.tv_shanchu = (TextView) rootView.findViewById(R.id.tv_shanchu);

    this.line0 = (LinearLayout) rootView.findViewById(R.id.line0);

    }

    }

    }

    主文件MainActivity.java

    package com.example.qqclient;

    import android.os.Bundle;

    import android.view.Display;

    import android.widget.ListView;

    import androidx.appcompat.app.AppCompatActivity;

    import java.util.ArrayList;

    public class MainActivity extends AppCompatActivity {

    private ListView line1;

    //获得屏幕的宽度

    public static int widthPixels=0;

    MyAdapter adapter;

    private ArrayList list=new ArrayList<>();

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    initView();

    //获得屏幕宽度

    Display display = getWindowManager().getDefaultDisplay();

    widthPixels = display.getWidth()-45;

    initDate();

    }

    private void initDate() {

    list.add("小明");

    list.add("小红");

    list.add("小亮");

    list.add("小花");

    adapter=new MyAdapter(MainActivity.this);

    adapter.set(list);

    line1.setAdapter(adapter);

    }

    private void initView() {

    line1 = (ListView) findViewById(R.id.line1);

    }

    }

    展开全文
  • 在项目开发中常常会遇到这种需求,自己写吧 水平不够,自定义view绘制不是太好....import android.content.Context; import android.graphics.Rect; import android.support.annotation.Nullable; ...

    在项目开发中常常会遇到这种需求,自己写吧 水平不够,自定义view绘制不是太好.多番查找资料和网上百度以后,终于实现了效果,废话不说了,看代码.

    第一步:这是一个工具类代码较多:建议粘贴

    import android.content.Context;
    import android.graphics.Rect;
    import android.support.annotation.Nullable;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.VelocityTracker;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.view.ViewGroup;
    import android.widget.Scroller;

    /**

    • Created by ${王栋栋}on 2019/08/21.
    • ASUS current user system login name
      */

    public class SlideRecyclerView extends RecyclerView {

    private static final String TAG = "SlideRecyclerView";
    private static final int INVALID_POSITION = -1; // 触摸到的点不在子View范围内
    private static final int INVALID_CHILD_WIDTH = -1;  // 子ItemView不含两个子View
    private static final int SNAP_VELOCITY = 600;   // 最小滑动速度
    
    private VelocityTracker mVelocityTracker;   // 速度追踪器
    private int mTouchSlop; // 认为是滑动的最小距离(一般由系统提供)
    private Rect mTouchFrame;   // 子View所在的矩形范围
    private Scroller mScroller;
    private float mLastX;   // 滑动过程中记录上次触碰点X
    private float mFirstX, mFirstY; // 首次触碰范围
    private boolean mIsSlide;   // 是否滑动子View
    private ViewGroup mFlingView;   // 触碰的子View
    private int mPosition;  // 触碰的view的位置
    private int mMenuViewWidth;    // 菜单按钮宽度
    
    public SlideRecyclerView(Context context) {
        this(context, null);
    }
    
    public SlideRecyclerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public SlideRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mScroller = new Scroller(context);
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        int x = (int) e.getX();
        int y = (int) e.getY();
        obtainVelocity(e);
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!mScroller.isFinished()) {  // 如果动画还没停止,则立即终止动画
                    mScroller.abortAnimation();
                }
                mFirstX = mLastX = x;
                mFirstY = y;
                mPosition = pointToPosition(x, y);  // 获取触碰点所在的position
                if (mPosition != INVALID_POSITION) {
                    View view = mFlingView;
                    // 获取触碰点所在的view
                    mFlingView = (ViewGroup) getChildAt(mPosition - ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition());
                    // 这里判断一下如果之前触碰的view已经打开,而当前碰到的view不是那个view则立即关闭之前的view,此处并不需要担动画没完成冲突,因为之前已经abortAnimation
                    if (view != null && mFlingView != view && view.getScrollX() != 0) {
                        view.scrollTo(0, 0);
                    }
                    // 这里进行了强制的要求,RecyclerView的子ViewGroup必须要有2个子view,这样菜单按钮才会有值,
                    // 需要注意的是:如果不定制RecyclerView的子View,则要求子View必须要有固定的width。
                    // 比如使用LinearLayout作为根布局,而content部分width已经是match_parent,此时如果菜单view用的是wrap_content,menu的宽度就会为0。
                    if (mFlingView.getChildCount() == 2) {
                        mMenuViewWidth = mFlingView.getChildAt(1).getWidth();
                    } else {
                        mMenuViewWidth = INVALID_CHILD_WIDTH;
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                mVelocityTracker.computeCurrentVelocity(1000);
                // 此处有俩判断,满足其一则认为是侧滑:
                // 1.如果x方向速度大于y方向速度,且大于最小速度限制;
                // 2.如果x方向的侧滑距离大于y方向滑动距离,且x方向达到最小滑动距离;
                float xVelocity = mVelocityTracker.getXVelocity();
                float yVelocity = mVelocityTracker.getYVelocity();
                if (Math.abs(xVelocity) > SNAP_VELOCITY && Math.abs(xVelocity) > Math.abs(yVelocity)
                        || Math.abs(x - mFirstX) >= mTouchSlop
                        && Math.abs(x - mFirstX) > Math.abs(y - mFirstY)) {
                    mIsSlide = true;
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                releaseVelocity();
                break;
        }
        return super.onInterceptTouchEvent(e);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        if (mIsSlide && mPosition != INVALID_POSITION) {
            float x = e.getX();
            obtainVelocity(e);
            switch (e.getAction()) {
                case MotionEvent.ACTION_DOWN:   // 因为没有拦截,所以不会被调用到
                    break;
                case MotionEvent.ACTION_MOVE:
                    // 随手指滑动
                    if (mMenuViewWidth != INVALID_CHILD_WIDTH) {
                        float dx = mLastX - x;
                        if (mFlingView.getScrollX() + dx <= mMenuViewWidth
                                && mFlingView.getScrollX() + dx > 0) {
                            mFlingView.scrollBy((int) dx, 0);
                        }
                        mLastX = x;
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    if (mMenuViewWidth != INVALID_CHILD_WIDTH) {
                        int scrollX = mFlingView.getScrollX();
                        mVelocityTracker.computeCurrentVelocity(1000);
                        // 此处有两个原因决定是否打开菜单:
                        // 1.菜单被拉出宽度大于菜单宽度一半;
                        // 2.横向滑动速度大于最小滑动速度;
                        // 注意:之所以要小于负值,是因为向左滑则速度为负值
                        if (mVelocityTracker.getXVelocity() < -SNAP_VELOCITY) {    // 向左侧滑达到侧滑最低速度,则打开
                            mScroller.startScroll(scrollX, 0, mMenuViewWidth - scrollX, 0, Math.abs(mMenuViewWidth - scrollX));
                        } else if (mVelocityTracker.getXVelocity() >= SNAP_VELOCITY) {  // 向右侧滑达到侧滑最低速度,则关闭
                            mScroller.startScroll(scrollX, 0, -scrollX, 0, Math.abs(scrollX));
                        } else if (scrollX >= mMenuViewWidth / 2) { // 如果超过删除按钮一半,则打开
                            mScroller.startScroll(scrollX, 0, mMenuViewWidth - scrollX, 0, Math.abs(mMenuViewWidth - scrollX));
                        } else {    // 其他情况则关闭
                            mScroller.startScroll(scrollX, 0, -scrollX, 0, Math.abs(scrollX));
                        }
                        invalidate();
                    }
                    mMenuViewWidth = INVALID_CHILD_WIDTH;
                    mIsSlide = false;
                    mPosition = INVALID_POSITION;
                    releaseVelocity();  // 这里之所以会调用,是因为如果前面拦截了,就不会执行ACTION_UP,需要在这里释放追踪
                    break;
            }
            return true;
        } else {
            // 此处防止RecyclerView正常滑动时,还有菜单未关闭
            closeMenu();
            // Velocity,这里的释放是防止RecyclerView正常拦截了,但是在onTouchEvent中却没有被释放;
            // 有三种情况:1.onInterceptTouchEvent并未拦截,在onInterceptTouchEvent方法中,DOWN和UP一对获取和释放;
            // 2.onInterceptTouchEvent拦截,DOWN获取,但事件不是被侧滑处理,需要在这里进行释放;
            // 3.onInterceptTouchEvent拦截,DOWN获取,事件被侧滑处理,则在onTouchEvent的UP中释放。
            releaseVelocity();
        }
        return super.onTouchEvent(e);
    }
    
    private void releaseVelocity() {
        if (mVelocityTracker != null) {
            mVelocityTracker.clear();
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
    }
    
    private void obtainVelocity(MotionEvent event) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
    }
    
    public int pointToPosition(int x, int y) {
        int firstPosition = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
        Rect frame = mTouchFrame;
        if (frame == null) {
            mTouchFrame = new Rect();
            frame = mTouchFrame;
        }
    
        final int count = getChildCount();
        for (int i = count - 1; i >= 0; i--) {
            final View child = getChildAt(i);
            if (child.getVisibility() == View.VISIBLE) {
                child.getHitRect(frame);
                if (frame.contains(x, y)) {
                    return firstPosition + i;
                }
            }
        }
        return INVALID_POSITION;
    }
    
    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            mFlingView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }
    
    /**
     * 将显示子菜单的子view关闭
     * 这里本身是要自己来实现的,但是由于不定制item,因此不好监听器点击事件,因此需要调用者手动的关闭
     */
    public void closeMenu() {
        if (mFlingView != null && mFlingView.getScrollX() != 0) {
            mFlingView.scrollTo(0, 0);
        }
    }
    

    }

    第二步:在你需要的Activity和Fragnent中定义RecyclerView

    我这里自己的包名: 到时改成你们自己的 不然肯定没反应
    <com.example.haiyue.myapplication.utils.SlideRecyclerView
    android:id="@+id/proposal_rv"
    android:layout_width=“match_parent”
    android:layout_height=“match_parent”></com.example.haiyue.myapplication.utils.SlideRecyclerView>

    第三步:就是写自己的适配器了

    import android.content.Context;
    import android.graphics.Color;
    import android.support.annotation.NonNull;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;

    import com.example.haiyue.myapplication.R;
    import com.example.haiyue.myapplication.bean.JianYiBean;

    import java.util.ArrayList;

    /**

    • Created by ASUSon 2019/08/15.
      */

    public class JianYiAdapter extends RecyclerView.Adapter<JianYiAdapter.ViewHolder> {

    private Context context;
    private ArrayList<JianYiBean> list;
    
    
    public JianYiAdapter(Context context, ArrayList<JianYiBean> list) {
        this.context = context;
        this.list = list;
    
    }
    @NonNull
    @Override
    public JianYiAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.jianyiitem,parent,false);
        ViewHolder holder=new ViewHolder(view);
        return holder;
    }
    
    @Override
    public void onBindViewHolder(@NonNull JianYiAdapter.ViewHolder holder, final int position) {
        JianYiBean jianYiBean = list.get(position);
        holder.title.setText(jianYiBean.getTitle());
        holder.date.setText(jianYiBean.getDate());
        if ("不予接收".equals(jianYiBean.getState())){
            holder.state.setTextColor(Color.parseColor("#D52619"));
            holder.state.setBackgroundResource(R.drawable.jianyi2);
            holder.state.setText(jianYiBean.getState());
        }
        if ("办理失败".equals(jianYiBean.getState())){
            holder.state.setTextColor(Color.parseColor("#D52619"));
            holder.state.setBackgroundResource(R.drawable.jianyi2);
            holder.state.setText(jianYiBean.getState());
        }
        holder.state.setText(jianYiBean.getState());
    
       holder.itemView.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               if (onClickListener!=null){
                   onClickListener.onClick(position);
               }
           }
       });
    
    }
    public OnClickListener onClickListener;
    
    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }
    
    public interface OnClickListener{
        void onClick(int position);
    }
    public void remove(int adapterPosition) {
        list.remove(adapterPosition);
        notifyItemRemoved(adapterPosition);
    }
    
    public void setTop(int adapterPosition) {
        JianYiBean bean = list.get(adapterPosition);
        list.remove(bean);
        list.add(0, bean);
        notifyItemMoved(adapterPosition, 0);
    }
    @Override
    public int getItemCount() {
        return list.size();
    }
    
    
    
    public class ViewHolder extends RecyclerView.ViewHolder {
    
    
        TextView title,date,state;
        public ViewHolder(View itemView) {
            super(itemView);
            title=itemView.findViewById(R.id.jianyi_title);
            date=itemView.findViewById(R.id.jianyi_date);
            state=itemView.findViewById(R.id.jianyi_commit);
    
        }
    }
    

    }

    最后粘出自己的item布局 你们自己写就好 有点丑将就看吧

    <?xml version="1.0" encoding="utf-8"?>









                </LinearLayout>
        </LinearLayout>
    
    
    
        <LinearLayout
            android:layout_marginTop="@dimen/dp_10"
            android:orientation="horizontal"
            android:layout_width="128dp"
            android:layout_height="match_parent">
                <TextView
                    android:id="@+id/jianyi_zhiding"
                    android:text="置顶"
                    android:background="#eaeaea"
                    android:textSize="@dimen/sp_16"
                    android:textColor="#222222"
                    android:gravity="center"
                    android:textAlignment="center"
                    android:layout_width="64dp"
                    android:layout_height="match_parent" />
                <TextView
                    android:id="@+id/jianyi_delete"
                    android:text="删除"
                    android:background="#D52619"
                    android:textSize="@dimen/sp_16"
                    android:gravity="center"
                    android:textColor="#FFFFFF"
                    android:textAlignment="center"
                    android:layout_width="64dp"
                    android:layout_height="match_parent" />
        </LinearLayout>
    

    然后看效果图 这是在模拟器上的效果

    在这里插入图片描述

    展开全文
  • 侧滑recyclerView的置顶删除

    千次阅读 2017-10-18 14:23:03
    主要是实现侧滑操作,通过ViewDragHelper来实现侧滑置顶删除
  • Android listView item侧滑实现删除置顶功能
  • 比如说QQ聊天列表侧滑就会出现“置顶”、“标为已读”、“删除”等按钮。这篇博文将用ViewDragHelper这个神器来实现侧滑效果。 好了,话说的那么多,先来看看我们实现的效果图吧: 先来看一下ListView的item的slip_...
  • Android中仿QQ侧滑删除功能的实现

    千次阅读 2018-04-19 16:55:40
    背景 参考 ...我体验了好多的app,感觉删除的功能还是QQ的侧滑删除最适合我的习惯。查找了github上的开源优秀项目,找了一个使用起来比较简单的框架,下面来实现。 参考 Android 仿QQ侧滑...
  • 今天项目需求,需要条目可以侧滑删除功能,所以想到了使用Recyclerview的条目侧滑删除功能,然后看了一下网上很多这种例子,然后就借鉴了一下网上其他大神写的博客,自己也简单的写了demo。  先上一个效果图给大家...
  • 实现的效果 引入第三方依赖,详细...Unit//删除 lateinit var onItemClickTop: (v: View, pos: Int) -> Unit//置顶 } item_sample.xml条目布局 这里就使用到我们刚刚引入的依赖 <?xml version="1.0" encoding="utf-8"?> ...
  • Android 侧滑删除之SwipeDelMenuLayout

    千次阅读 2018-08-13 14:06:27
    前段时间在git上get到SwipeDelMenuLayout侧滑删除,不依赖ListView或者RecyclerView,只要在item中即可,无耦合性。 效果图: 用法: 在build.gradle中配置: dependencies { compile '...
  • 今天要介绍的这个库叫做 SwipeDelMenuLayout 1 史上最简单侧滑菜单,0耦合,支持任意ViewGroup ...首先看下效果侧滑删除库github地址使用方法如下:1 导入依赖库allprojects { repositories { .... maven { url
  • 高仿QQ侧滑效果,实现置顶删除功能,完美适用于ListView,至于RecyclerView正在研究,效果有些问题。 本侧滑很简单,只有右侧的侧滑,并没有其他酷炫的功能,希望给大家一个提示思路,如果需求简单的话可以自己照...
  • 对于侧滑删除已经是见惯不惯的了,我也一直有写类似QQ那样的侧滑删除控件的想法,虽然研究一段时间的自定义View,然对自定义ViewGroup实战还是较少,并且侧滑删除还要考虑大量的事件分发机制,比如如何处理子控件与...
  • 仿QQ侧滑删除效果图1.自定义listviewpublic class DragDelListView extends ListView {private boolean moveable=false;private boolean closed=true;private float mDownX,mDownY;private int mTouchPosition,old...
  • android ListView的item侧滑删除

    千次阅读 2017-01-17 18:27:06
    主要功能就是ListView的item可以侧滑,出来一个删除按钮,点击delete就删除该item。这是一个相对比较综合的例子,来看看动手之前需要准备哪些知识。 1. 对自定义View要有一定的知识基础 2. 事件的拦截以及反拦截...
  • 今天给大家分享是如何在RecyclerView实现全选,ItemTouchHelper实现侧滑删除,拖拽功能。比较基础。关于RecyclerView的强大,就不多说了。在Android L SDK发布的新API中最有意思的就是RecyclerView 和 CardView了, ...
  • 在练习android时,想在Linearlayout内放一图片,使其图片置顶,预期效果是这样的:但xml代码imageview写成这样后,android:layout_width="match_parent"android:layout_height="wrap_content"android:src="@drawable...
  • RecyclerView的各种效果实现。 实现效果: 侧滑删除(带自动校位滑动效果); 右滑出现选择框; 一键全选。
  • android:text="置顶" android:textColor="@android:color/white"/> android:id="@+id/btnUnRead" android:layout_width="120dp" android:layout_height="match_parent" android:background="#ecd50a" ...
  • Android ViewDragHelper实现 侧滑删除效果

    千次阅读 2017-04-16 11:00:53
    效果图事件传递机制带码 SwipeDeleteItem.java 自定义拖拽控件 public class SwipeDeleteItem extends FrameLayout { private ViewDragHelper viewDragHelper; private View contentView; private View deleteView...
  • Android仿QQ侧滑(删除置顶等)功能

    千次阅读 2016-12-13 09:29:06
    "删除" android:textColor = "@android:color/white" android:textSize = "20sp" /> LinearLayout > < LinearLayout android:layout_width = "match_parent" android:layout_height = "wrap_...
  • RecyclerView的侧滑删除置顶等实现

    千次阅读 2017-06-21 11:51:50
    项目中需要这个效果,是仿QQ的,资料参考: ... RecyclerView的Activity: ..."删除:" ...//如果删除时,不使用mAdapter....//置顶: holder.btnTop.setOnClickListener( new View.OnClickListener() { @Override ...
  • Android自定义ViewGroup】不一样的轮子,巧用类变量解决冲突,像IOS那样简单的使用侧滑删除,一个控件搞定Android item侧滑删除菜单。 包含且不仅包含以下功能: 1 侧滑拉出菜单。 2 点击除了这个item的其他位置,...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 310
精华内容 124
关键字:

android侧滑删除置顶