您的位置:首页 > 移动开发 > Android开发

Android开发之RecyclerView的侧滑删除

2017-03-28 17:32 309 查看
现在RecyclerView基本已经取代了ListView和GridView,今天对其进行一个侧滑删除的小结。第一次尝试使用gif图制作:http://gif.55.la/,先上效果图:



1,先要在app/build.gradle文件中添加如下代码:

compile 'com.android.support:recyclerview-v7:25.2.0'


2,布局文件

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.gyq.recyclerviewdelete.MainActivity">

<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:background="#EEEEEE"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:overScrollMode="never"/>

</RelativeLayout>


layout_item.xml

<?xml version="1.0" encoding="utf-8"?>
<com.gyq.recyclerviewdelete.view.SlidingButtonView 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
android:id="@+id/tv_delete"
android:layout_height="match_parent"
android:layout_width="80dp"
android:gravity="center"
android:layout_toRightOf="@+id/layout_content"
android:text="删 除"
android:background="@drawable/btn_click_red_havebackground"
android:textColor="#DDFFFFFF"
/>
<LinearLayout
android:id="@+id/layout_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center_vertical"
android:src="@drawable/dog"/>
<TextView
android:id="@+id/text"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="center_vertical"
android:textSize="30sp"
android:textColor="#DD000000"
android:background="@drawable/btn_click_black_havebackground"
/>
</LinearLayout>

</RelativeLayout>
</com.gyq.recyclerviewdelete.view.SlidingButtonView>


注释:布局中用到的drawable文件,如下:

btn_click_black_havebackground.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="@android:color/white"/>
</shape>
</item>
<item >
<shape >
<solid android:color="#22000000"/>
</shape>
</item>
</layer-list>
</item>
<item >
<shape >
<solid android:color="@android:color/white"/>
</shape>
</item>
</selector>


btn_click_red_havebackground.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 android:color="#FF0000"/>
</shape>
</item>
</selector>


2,自定义view

package com.gyq.recyclerviewdelete.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.TextView;

import com.gyq.recyclerviewdelete.R;

/**
* Created by gyq on 2017/3/27 17:01
*/
public class SlidingButtonView extends HorizontalScrollView {
private TextView mTextView_Delete;

private int mScrollWidth;

private IonSlidingButtonListener mIonSlidingButtonListener;

private Boolean isOpen = false;
private Boolean once = false;

public SlidingButtonView(Context context) {
this(context, null);
}

public SlidingButtonView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}

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

this.setOverScrollMode(OVER_SCROLL_NEVER);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

if(!once){
mTextView_Delete = (TextView) findViewById(R.id.tv_delete);
once = true;
}

}

@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();
// Log.i("asd", "mScrollWidth:" + mScrollWidth);
}

}

@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);
}

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
mTextView_Delete.setTranslationX(l - mScrollWidth);
}

/**
* 按滚动条被拖动距离判断关闭或打开菜单
*/
public void changeScrollx(){
if(getScrollX() >= (mScrollWidth/2)){
this.smoothScrollTo(mScrollWidth, 0);
isOpen = true;
mIonSlidingButtonListener.onMenuIsOpen(this);
}else{
this.smoothScrollTo(0, 0);
isOpen = false;
}
}

/**
* 关闭菜单
*/
public void closeMenu()
{
if (!isOpen){
return;
}
this.smoothScrollTo(0, 0);
isOpen = false;
}

public void setSlidingButtonListener(IonSlidingButtonListener listener){
mIonSlidingButtonListener = listener;
}

public interface IonSlidingButtonListener{
void onMenuIsOpen(View view);
void onDownOrMove(SlidingButtonView slidingButtonView);
}
}


4,适配器

package com.gyq.recyclerviewdelete.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.gyq.recyclerviewdelete.R;
import com.gyq.recyclerviewdelete.utils.Utils;
import com.gyq.recyclerviewdelete.view.SlidingButtonView;

import java.util.ArrayList;
import java.util.List;

/**
* Created by gyq on 2017/3/27 15:44
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.SimpleHolder> implements SlidingButtonView.IonSlidingButtonListener {
private Context mContext;
private List<String> mDatas = new ArrayList<>();

private IonSlidingViewClickListener mIDeleteBtnClickListener;

private SlidingButtonView mMenu;

public RecyclerAdapter(Context context) {
mContext = context;

for (int i = 0; i < 10; i++) {
mDatas.add(i+".世界最可爱的小狗");
}
}

@Override
public SimpleHolder onCreateViewHolder(ViewGroup parent, int viewType) {
/*if (mContext == null) {
mContext = parent.getContext();
}*/
View view = LayoutInflater.from(mContext).inflate(R.layout.layout_item, parent, false);
return new SimpleHolder(view);
}

@Override
public void onBindViewHolder(final SimpleHolder holder, int position) {
holder.mText.setText(mDatas.get(position));

holder.layout_content.getLayoutParams().width = Utils.getScreenWidth(mContext);

holder.mText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mContext,",,,,....",Toast.LENGTH_SHORT).show();
//判断是否有删除菜单打开
if (menuIsOpen()) {
closeMenu();//关闭菜单
} else {
int n = holder.getLayoutPosition();
mIDeleteBtnClickListener.onItemClick(view, n);
}
}
});

holder.tv_Delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(mContext,",,,,....ddddd",Toast.LENGTH_SHORT).show();
int n = holder.getLayoutPosition();

mIDeleteBtnClickListener.onDeleteBtnCilck(view,n);
}
});
}

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

class SimpleHolder extends  RecyclerView.ViewHolder {
public TextView tv_Delete;
public TextView mText;
public LinearLayout layout_content;
public SimpleHolder(View itemView) {
super(itemView);

tv_Delete = (TextView)itemView.findViewById(R.id.tv_delete);

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

layout_content = (LinearLayout)itemView.findViewById(R.id.layout_content);

((SlidingButtonView)itemView).setSlidingButtonListener(RecyclerAdapter.this);
}

}

public void addData(int position) {
mDatas.add(position, "添加项");
notifyItemInserted(position);
}

public void removeData(int position){
mDatas.remove(position);
notifyDataSetChanged();

}

@Override
public void onMenuIsOpen(View view) {
mMenu = (SlidingButtonView) view;
}

@Override
public void onDownOrMove(SlidingButtonView slidingDeleteView) {
if(menuIsOpen()){
if(mMenu != slidingDeleteView){
closeMenu();
}
}
}

/**
* 关闭菜单
*/
public void closeMenu() {
mMenu.closeMenu();
mMenu = null;

}
/**
* 判断是否有菜单打开
*/
public Boolean menuIsOpen() {
if(mMenu != null){
return true;
}
return false;
}

public void setOnSlidListener(IonSlidingViewClickListener listener) {
mIDeleteBtnClickListener = listener;
}

public interface IonSlidingViewClickListener {
void onItemClick(View view,int position);
void onDeleteBtnCilck(View view,int position);
}
}


5,MainActivity.class

package com.gyq.recyclerviewdelete;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;

import com.gyq.recyclerviewdelete.adapter.RecyclerAdapter;

public class MainActivity extends AppCompatActivity implements RecyclerAdapter.IonSlidingViewClickListener {
private RecyclerView mRecyclerView;
private RecyclerAdapter mAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initView();

mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

updateUI();

}

private void updateUI() {
if (mAdapter == null) {
mAdapter = new RecyclerAdapter(this);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}else {
mAdapter.notifyDataSetChanged();
}

mAdapter.setOnSlidListener(this);
}

private void initView() {
mRecyclerView = (RecyclerView)findViewById(R.id.recycler_view);

}

@Override
public void onItemClick(View view, int position) {
Toast.makeText(MainActivity.this,"......" + position,Toast.LENGTH_SHORT).show();
}

@Override
public void onDeleteBtnCilck(View view, int position) {
mAdapter.removeData(position);

}
}


6,工具类:

package com.gyq.recyclerviewdelete.utils;

import android.content.Context;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.WindowManager;

/**
* Created by gyq on 2015/7/25.
*/
public class Utils {

/**
* dpתpx
* @param context
* @param dp
* @return
*/
public static int dp2px(Context context,float dp)
{
return (int ) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dp, context.getResources().getDisplayMetrics());
}

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 ;
}
}


结束语:这个小demo,我发现几点小问题;就是在item的布局里面,如果内容的宽度改为wrap_content,会出现拖出来删除,然后点击(拖不)回不去。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: