最近遇到这个需求,下面给大家推荐两办法都是自定义控件一个是继承了HorizontalScrollView的另一个是继承了LinearLayout
那么先说下第一个,首先实现滑动出现删除菜单就一定会需要监听触摸事件,比起继承view来算我们还是用带有滑动的HorizontalScrollView更加方便。
好了首先说下item就是SlidingButtonView 就是自定义的View,继承水平滚动条
<?xml version="1.0" encoding="utf-8"?>
<viewpage.yundong.com.huadongdelete.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"
/>
<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="#DD000000"
android:background="@drawable/btn_click_black_havebackground"
/>
</RelativeLayout>
</RelativeLayout>
</viewpage.yundong.com.huadongdelete.SlidingButtonView>
自定义view
package viewpage.yundong.com.huadongdelete;
/**
* Created by MJJ on 2015/7/25.
*/
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.TextView;
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:
if (mIonSlidingButtonListener!=null){
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);
//这里设置动画使删除按钮貌似后面冒出来的
Log.e("显示记录",l+"====="+mScrollWidth);
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 openMenu()
{
if (isOpen){
return;
}
this.smoothScrollTo(mScrollWidth, 0);
isOpen = true;
mIonSlidingButtonListener.onMenuIsOpen(this);
}
/**
* 关闭菜单
*/
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);
}
}
好了下面就需要适配器来进行配合了
package viewpage.yundong.com.huadongdelete;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by MJJ on 2015/7/25.
*/
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> implements SlidingButtonView.IonSlidingButtonListener {
private Context mContext;
private IonSlidingViewClickListener mIDeleteBtnClickListener;
private List<String> mDatas = new ArrayList<String>();
private SlidingButtonView mMenu = null;
public Adapter(Context context) {
mContext = context;
mIDeleteBtnClickListener = (IonSlidingViewClickListener) context;
for (int i = 0; i < 30; 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);
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_Delete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int n = holder.getLayoutPosition();
mIDeleteBtnClickListener.onDeleteBtnCilck(v, n);
}
});
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
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_Delete;
public TextView textView;
public ViewGroup layout_content;
public MyViewHolder(View itemView) {
super(itemView);
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);
((SlidingButtonView) itemView).setSlidingButtonListener(Adapter.this);
}
}
public void addData(int position) {
mDatas.add(position, "添加项");
notifyItemInserted(position);
}
public void removeData(int position){
mDatas.remove(position);
notifyItemRemoved(position);
}
/**
* 删除菜单打开信息接收
*/
@Override
public void onMenuIsOpen(View view) {
mMenu = (SlidingButtonView) view;
}
/**
* 滑动或者点击了Item监听
* @param slidingButtonView
*/
@Override
public void onDownOrMove(SlidingButtonView slidingButtonView) {
if(menuIsOpen()){
if(mMenu != slidingButtonView){
closeMenu();
}
}
}
/**
* 关闭菜单
*/
public void closeMenu() {
mMenu.closeMenu();
mMenu = null;
}
/**
* 判断是否有菜单打开
*/
public Boolean menuIsOpen() {
if(mMenu != null){
Log.i("asd","mMenu不为null");
return true;
}
Log.i("asd","mMenu为null");
return false;
}
public interface IonSlidingViewClickListener {
void onItemClick(View view,int position);
void onDeleteBtnCilck(View view,int position);
}
}
最后简单的调用就好了,因为我连数据源都在适配器了,直接就可以按下面运行看到效果了。
package viewpage.yundong.com.huadongdelete;
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.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity implements Adapter.IonSlidingViewClickListener {
private RecyclerView mRecyclerView;
private Adapter mAdapter;
private final String TAG = "test";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
setAdapter();
}
private void initView(){
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
}
private void setAdapter(){
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(mAdapter = new Adapter(this));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
}
@Override
public void onItemClick(View view, int position) {
Log.i(TAG,"点击项:"+position);
}
@Override
public void onDeleteBtnCilck(View view, int position) {
Log.i(TAG,"删除项:"+position);
mAdapter.removeData(position);
}
}
最后这里有个获取屏幕宽度的工具类也给你们吧 就不给源码连接了
package viewpage.yundong.com.huadongdelete;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.WindowManager;
/**
* Created by MJJ 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());
}
/**
* 获得屏幕宽度
*
* @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 ;
}
/**
* 获得屏幕高度
*
* @param context
* @return
*/
public static int getScreenHeight(Context context)
{
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE );
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics( outMetrics);
return outMetrics .heightPixels ;
}
}
嗯嗯这就第一个方式,另一种有空子再写吧0.0