RecyclerView 左滑(仿QQ左滑删除)
来源:互联网 发布:为知笔记导出 苹果 编辑:程序博客网 时间:2024/05/07 19:10
一、效果图
二、实现步骤
1.添加依赖库
(Android/Gradle Scripts/build.gradle(Module:app))
compile 'com.android.support:recyclerview-v7:26.+'/* 版本号与 compile 'com.android.support:appcompat-v7:26.+',此句版本号为26.+ */
2.RecyclerView布局
(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:background="#EEEEEE" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:overScrollMode="never" /></RelativeLayout>
3.设置颜色选择器
(orange_background.xml)
<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"> <layer-list > <item > <shape > <solid android:color="#f49405"/> </shape> </item> <item > <shape > <solid android:color="#22000000"/> </shape> </item> </layer-list> </item> <item > <shape > <solid android:color="#f49405"/> </shape> </item></selector>
(app/res/drawable/pink_background.xml)
<?xml version="1.0" encoding="utf-8"?><!--颜色选择器--><selector xmlns:android="http://schemas.android.com/apk/res/android"> <!--按定“删除”按钮时该按钮显示的颜色:红色--> <item android:state_pressed="true"> <layer-list > <item > <shape > <solid android:color="#FF0000"/> </shape> </item> <item > <shape > <solid android:color="#22000000"/> </shape> </item> </layer-list> </item> <!--“删除”按钮直接看上去的颜色:粉红色--> <item > <shape > <!--solid 实心,即填充--> <solid android:color="#ff0080"/> </shape> </item></selector>
(app/res/drawable/white_background.xml)
<?xml version="1.0" encoding="utf-8"?><!--selector 颜色选择器--><selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- state_pressed="true/false"点击。true 表示点击状态下使用,false表示非点击状态下使用。--> <item android:state_pressed="true"> <layer-list > <item > <shape > <solid android:color="@android:color/white"/> </shape> </item> <item > <shape > <!--solid 实心,即填充--> <solid android:color="#22000000"/> </shape> </item> </layer-list> </item> <item > <shape > <solid android:color="@android:color/white"/> </shape> </item></selector>
4.item布局
(layout_item.xml)
<?xml version="1.0" encoding="utf-8"?><!--item布局,自定义View--><com.example.textdemo.LeftSlideView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="100dp" android:background="@android:color/white" android:layout_marginBottom="1dp"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <!--"设置","删除"按钮使用了TextView而不是Button,是因为5.0以上版本使用Button会显示在上层产出错误显示--> <TextView android:id="@+id/tv_set" android:layout_height="106dp" android:layout_width="80dp" android:gravity="center" android:layout_toRightOf="@+id/layout_content" android:text="设置" android:textSize="25dp" android:background="@drawable/orange_background" android:textColor="#DDFFFFFF" /> <TextView android:id="@+id/tv_delete" android:layout_height="match_parent" android:layout_width="80dp" android:gravity="center" android:layout_toRightOf="@+id/tv_set" android:text="删 除" android:textSize="25dp" android:background="@drawable/pink_background" android:textColor="#DDFFFFFF" /> <RelativeLayout android:id="@+id/layout_content" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text" android:layout_height="match_parent" android:layout_width="match_parent" android:textSize="50dp" android:textColor="#dde65b05" android:background="@drawable/white_background" /> </RelativeLayout> </RelativeLayout></com.example.textdemo.LeftSlideView>
5.自定义View
(LeftSlideView.java)
/*** 自定义View,继承水平滚动条*/public class LeftSlideView extends HorizontalScrollView { private TextView mTextView_Set;//设置按钮 private TextView mTextView_Delete;//删除按钮 private int mScrollWidth;//记录滚动条可以滚动的距离 private Boolean once = false;//在onMeasure中只执行一次的判断 private Boolean isOpen = false;//记录按钮菜单是否打开,默认关闭false private IonSlidingButtonListener mIonSlidingButtonListener;//自定义的接口,用于传达滑动事件等 /** * 1.构造方法 */ public LeftSlideView(Context context) { super(context, null); } public LeftSlideView(Context context, AttributeSet attrs) { super(context, attrs, 0); } public LeftSlideView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.setOverScrollMode(OVER_SCROLL_NEVER); } //2.在onMeasure中先取得作为“设置”、“删除”按钮的TextView @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (!once) { mTextView_Delete = (TextView) findViewById(com.example.textdemo.R.id.tv_delete); mTextView_Set = (TextView) findViewById(com.example.textdemo.R.id.tv_set); once = true; } } //3.在onLayout中使Item在每次变更布局大小时回到初始位置,并且获取滚动条的可移动距离 @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); if (changed) { this.scrollTo(0, 0); //获取水平滚动条可以滑动的范围,即右侧“设置”、“删除”按钮的总宽度 mScrollWidth = mTextView_Delete.getWidth() + mTextView_Set.getWidth(); } } //4.滑动监听,按滑动的距离大小控制菜单开关 @Override public boolean onTouchEvent(MotionEvent ev) { int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN://按下 case MotionEvent.ACTION_MOVE://移动 mIonSlidingButtonListener.onDownOrMove(this); break; case MotionEvent.ACTION_UP://松开 case MotionEvent.ACTION_CANCEL: changeScrollx(); return true; default: break; } return super.onTouchEvent(ev); } /** * 5. * @param l * @param t * @param oldl * @param oldt */ @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); //改变view的在x轴方向的位置 mTextView_Set.setTranslationX(1); } /** * 6.按滚动条被拖动距离判断关闭或打开菜单 * getScrollX() view的左上角相对于母视图的左上角的X轴偏移量 * smoothScrollTo(x, y); 参数:相对于ScrollView左上角的位置来说,你要移动的位置 */ public void changeScrollx() { if (getScrollX() >= (mScrollWidth / 2)) { this.smoothScrollTo(mScrollWidth, 0); isOpen = true; mIonSlidingButtonListener.onMenuIsOpen(this); } else { this.smoothScrollTo(0, 0); isOpen = false; } } /** * 7.打开菜单 */ public void openMenu() { if (isOpen) { return; } this.smoothScrollTo(mScrollWidth, 0);//相对于原来没有滑动的位置x轴方向偏移了mScrollWidth,y轴方向没有变化。 isOpen = true; mIonSlidingButtonListener.onMenuIsOpen(this); } /** * 8.关闭菜单 */ public void closeMenu() { if (!isOpen) { return; } this.smoothScrollTo(0, 0);//相对于原来没有滑动的位置,x轴方向、y轴方向都没有变化,即回到原来的位置了。 isOpen = false; } /** * 9.接口定义及注册方法 */ public void setSlidingButtonListener(IonSlidingButtonListener listener) { mIonSlidingButtonListener = listener; } public interface IonSlidingButtonListener { //该方法在Adapter中实现 void onMenuIsOpen(View view);//判断菜单是否打开 void onDownOrMove(LeftSlideView leftSlideView);//滑动或者点击了Item监听 }}
6.设置内容布局的宽为屏幕宽度的工具类
(Utils.java)
public class Utils { public static int dp2px(Context context, float dp) { return (int ) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); } /** * 获得屏幕宽度 * * @param context * @return */ public static int getScreenWidth(Context context) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE ); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics( outMetrics); return outMetrics .widthPixels ; }}
7.适配器Adapter
(Adapter.java)
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> implements LeftSlideView.IonSlidingButtonListener { private Context mContext; private List<String> mDatas = new ArrayList<String>(); private IonSlidingViewClickListener mIDeleteBtnClickListener; private IonSlidingViewClickListener mISetBtnClickListener; private LeftSlideView mMenu = null; public Adapter(Context context) { mContext = context; mIDeleteBtnClickListener = (IonSlidingViewClickListener) context; mISetBtnClickListener = (IonSlidingViewClickListener) context; for (int i = 0; i < 10; i++) { mDatas.add(i + ""); } } @Override public int getItemCount() { return mDatas.size(); } @Override public void onBindViewHolder(final MyViewHolder holder, int position) { holder.textView.setText(mDatas.get(position)); //设置内容布局的宽为屏幕宽度 holder.layout_content.getLayoutParams().width = Utils.getScreenWidth(mContext); //item正文点击事件 holder.textView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //判断是否有删除菜单打开 if (menuIsOpen()) { closeMenu();//关闭菜单 } else { int n = holder.getLayoutPosition(); mIDeleteBtnClickListener.onItemClick(v, n); } } }); //左滑设置点击事件 holder.btn_Set.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { int n = holder.getLayoutPosition(); mISetBtnClickListener.onSetBtnCilck(view, n); } }); //左滑删除点击事件 holder.btn_Delete.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { int n = holder.getLayoutPosition(); mIDeleteBtnClickListener.onDeleteBtnCilck(view, n); } }); } @Override public MyViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) { //获取自定义View的布局(加载item布局) View view = LayoutInflater.from(mContext).inflate(R.layout.layout_item, arg0, false); MyViewHolder holder = new MyViewHolder(view); return holder; } class MyViewHolder extends RecyclerView.ViewHolder { public TextView btn_Set; public TextView btn_Delete; public TextView textView; public ViewGroup layout_content; public MyViewHolder(View itemView) { super(itemView); btn_Set = (TextView) itemView.findViewById(R.id.tv_set); btn_Delete = (TextView) itemView.findViewById(R.id.tv_delete); textView = (TextView) itemView.findViewById(R.id.text); layout_content = (ViewGroup) itemView.findViewById(R.id.layout_content); ((LeftSlideView) itemView).setSlidingButtonListener(Adapter.this); } } /** * 删除item * @param position */ public void removeData(int position) { mDatas.remove(position); notifyItemRemoved(position); } /** * 删除菜单打开信息接收 */ @Override public void onMenuIsOpen(View view) { mMenu = (LeftSlideView) view; } /** * 滑动或者点击了Item监听 * * @param leftSlideView */ @Override public void onDownOrMove(LeftSlideView leftSlideView) { if (menuIsOpen()) { if (mMenu != leftSlideView) { closeMenu(); } } } /** * 关闭菜单 */ public void closeMenu() { mMenu.closeMenu(); mMenu = null; } /** * 判断菜单是否打开 * * @return */ public Boolean menuIsOpen() { if (mMenu != null) { return true; } return false; } /** * 注册接口的方法:点击事件。在Mactivity.java实现这些方法。 */ public interface IonSlidingViewClickListener { void onItemClick(View view, int position);//点击item正文 void onDeleteBtnCilck(View view, int position);//点击“删除” void onSetBtnCilck(View view, int position);//点击“设置” }}
8.MainActivity.java
public class MainActivity extends AppCompatActivity implements Adapter.IonSlidingViewClickListener { private RecyclerView mRecyclerView; private Adapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(com.example.textdemo.R.layout.activity_main); mRecyclerView = (RecyclerView) findViewById(com.example.textdemo.R.id.recyclerview); //设置布局管理器 mRecyclerView.setLayoutManager(new LinearLayoutManager(this));//设置布局管理器 mRecyclerView.setAdapter(mAdapter = new Adapter(this));//设置适配器 mRecyclerView.setItemAnimator(new DefaultItemAnimator());//设置控制Item增删的动画 } /** * item正文的点击事件 * * @param view * @param position */ @Override public void onItemClick(View view, int position) { //点击item正文的代码逻辑 } /** * item的左滑设置 * * @param view * @param position */ @Override public void onSetBtnCilck(View view, int position) { //“设置”点击事件的代码逻辑 Toast.makeText(MainActivity.this, "请设置", Toast.LENGTH_LONG).show(); } /** * item的左滑删除 * * @param view * @param position */ @Override public void onDeleteBtnCilck(View view, int position) { mAdapter.removeData(position); }}
9.屏蔽多点触控,否则左滑时可以同时左滑多条item。
(app/res/values/styles.xml)
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:windowEnableSplitTouch" >false </item> <item name="android:splitMotionEvents" >false </item> </style></resources>
阅读全文
1 0
- RecyclerView 左滑(仿QQ左滑删除)
- RecyclerView 左滑(仿QQ左滑删除)
- 仿QQ左滑删除
- 仿QQ左滑删除
- 仿QQ左滑删除
- 简单ListView仿QQ左滑删除
- 仿QQ列表左滑删除效果
- 仿QQ左滑打开或删除
- RecyclerView仿QQ消息列表左滑弹出菜单,标记已读和删除
- RecyclerView仿ios左滑删除的轻量级实现
- Android仿QQ左滑删除置顶ListView
- 仿QQ消息列表的左滑置顶与删除
- 仿QQ左滑删除功能实现分析(一)-预告
- 仿QQ左滑删除功能实现分析(二)-SwipeListView
- listview左滑删除和置顶(仿QQ)
- QQListview左滑删除,经典案例,高仿QQ左滑,动画效果,自定义!!
- recyclerview的使用,左滑删除
- RecyclerView的item左滑删除
- [NOIP模拟赛]天文观测
- Kafka学习笔记:在zookeeper中考察kafka目录结构
- 1163: 亲和串(字符串)
- php PDO 方式操作数据库小结
- 听说你也想做用户体验设计师?
- RecyclerView 左滑(仿QQ左滑删除)
- 俞敏洪:人与人的差距是怎么拉开的?
- android内存回收问题
- 闭包和面向对象设计
- 给产品经理的10条良心建议
- 修改后的php万年历
- @SPI 学习
- 1.2 数据类型和基本输入/输出
- 关于date类的三部曲