daimajia / AndroidSwipeLayout

The Most Powerful Swipe Layout!
MIT License
12.38k stars 2.67k forks source link

How to implement only one item swipe at a time (when one item is swiped, others are closed)? #358

Open ionutmarisca opened 8 years ago

ionutmarisca commented 8 years ago

Hello,

I'm using RecyclerView in my project and I added this library to show some options for every item in my list when swiped.

What I want to achieve is the following thing: when I swipe one item, if another one is already swiped, the other one is closed automatically. So I don't want to have two items swiped at a time.

I tried to follow the instructions found in this issue but the information is incomplete (there is no ItemManger, no bindView function for it).

Can someone provide a final working solution for this?

Thank you in advance!

afiqiqmal commented 8 years ago

Add this in your adapter SwipeItemRecyclerMangerImpl mItemManger = new SwipeItemRecyclerMangerImpl(this);

Then add this at the end of your onBindViewHolder mItemManger.bindView(viewHolder.itemView, position);

its work fine on me..

arpitjoshi08 commented 8 years ago

i also getting this issue and i implement this SwipeItemRecyclerMangerImpl mItemManger = new SwipeItemRecyclerMangerImpl(this); mItemManger.bindView(viewHolder.itemView, position);

but getting me issue "java.lang.IllegalArgumentException: adapter should implement the SwipeAdapterInterface" then i implemeted SwipeAdapterInterface with one override method @Override public int getSwipeLayoutResourceId(int i) { return 0; } but still getting this issue "java.lang.IllegalArgumentException: adapter should implement the SwipeAdapterInterface". What should i do?

ionutmarisca commented 8 years ago

@afiqiqmal Thanks for the answer. However, as @arpitjoshi08 stated, after trying to add those lines of code I get an IllegalArgumentException: adapter should implement the SwipeAdapterInterface.

After implementing the SwipeAdapterInterface same error occurs. However, if I try to implement SwipeItemMangerInterface with all of its functions I will no longer get an exception but the expected behavior won't happen as the function closeAllExcept(SwipeLayout) is overridden and I don't know how to exactly implement it.

Can anyone take a look and provide a solution for this issue? Thanks for your support.

arpitjoshi08 commented 8 years ago

now i implemented that SwipeItemMangerInterface with methods but i am getting this issue "java.lang.IllegalStateException: can not find SwipeLayout in target view" on this line mItemManger.bindView(viewHolder.itemView, position);

arpitjoshi08 commented 8 years ago

`

public class adpater extends RecyclerView.Adapter implements SwipeAdapterInterface,SwipeItemMangerInterface {

ArrayList dataList; LayoutInflater inflater; Context context; SwipeItemRecyclerMangerImpl mItemMange;

public adapter(Context context, ArrayList<Bean> dataList) {
    this.context = context;
    inflater = LayoutInflater.from(context);
    this.dataList = dataList;

    mItemMange=new SwipeItemRecyclerMangerImpl(this);
}

public void setNewList(Context context, ArrayList<Bean> dataList) {
    this.context = context;
    this.dataList = dataList;
    notifyDataSetChanged();
    mItemMange=new SwipeItemRecyclerMangerImpl(this);
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.xyz, parent, false);
    MyViewHolder holder = new MyViewHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {

    Bean messageBean = dataList.get(position);
    holder.Name.setText(messageBean.get_name());
    if (messageBean.getMessage_status().equalsIgnoreCase("0")) {
        holder.toggleButton.setText("xu");
        holder.blocked.setBackgroundColor(context.getResources().getColor(R.color.transparent));

    } else {
        holder.toggleButton.setText("ab");
        holder.blocked.setBackgroundColor(context.getResources().getColor(R.color.red));
    }

/* holder.swipeLayout.setSwipeEnabled(false); */

    holder.blockedImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            holder.swipeLayout.open();
        }
    });
    mItemMange.bindView(holder.itemView, position);
}

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

@Override
public int getSwipeLayoutResourceId(int i) {
    return 5;
}

@Override
public void openItem(int i) {

}

@Override
public void closeItem(int i) {

}

@Override
public void closeAllExcept(SwipeLayout swipeLayout) {

}

@Override
public void closeAllItems() {

}

@Override
public List<Integer> getOpenItems() {
    return null;
}

@Override
public List<SwipeLayout> getOpenLayouts() {
    return null;
}

@Override
public void removeShownLayouts(SwipeLayout swipeLayout) {

}

@Override
public boolean isOpen(int i) {
    return false;
}

@Override
public Attributes.Mode getMode() {
    return null;
}

@Override
public void setMode(Attributes.Mode mode) {

}

class MyViewHolder extends RecyclerView.ViewHolder {
    DosisRegularFont Name;
    TextView toggleButton;
    RelativeLayout blocked;
    ImageView blockedImage;
    SwipeLayout swipeLayout;

    public MyViewHolder(View itemView) {
        super(itemView);
        Name = (DosisRegularFont) itemView.findViewById(R.id.x);
        toggleButton = (TextView) itemView.findViewById(R.id.y);
        blocked = (RelativeLayout) itemView.findViewById(R.id.z);
        blockedImage = (ImageView) itemView.findViewById(R.id.a);
        swipeLayout = (SwipeLayout) itemView.findViewById(R.id.b);
    }

}

} ` this is my adapter code .so what should i do changes for proper implementation?

donlingliang commented 7 years ago

getSwipeLayoutResourceId should return the SwipeLayout Id in your ViewHolder. @arpitjoshi08 @ionutmarisca

aptgopal commented 7 years ago

// inside OnBindViewHolder() method, at the very bottom. put this code ItemManger.bindView(holder.itemView, position);

// and then add swipelistener to current swipelayout holder.swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() { @override public void onStartOpen(SwipeLayout layout) { mItemManger.closeAllExcept(layout); } }

This work for my case. The bold one is the key

RakshitSorathiya commented 6 years ago

@aptgopal what is ItemManager class in your above mentioned solution.

jaween commented 6 years ago

Implementing SwipeAdapterInterface leads to an IllegalArgumentException. Looking at the code for SwipeItemMangerImpl, the cause of the exception is that it's really checking if the adapter is an instance of SwipeItemMangerInterface (SwipeAdapterInterface is not).

So trying to implement SwipeItemMangerInterface instead leads to a ClassCastExecption, where SwipeItemManagerImpl tries to cast the adapter to a SwipeAdapterInterface.

Not sure how to proceed with AndroidSwipeLayout.

davischung commented 6 years ago

If you are using RecyclerView and trying to initialize an SwipeItemRecyclerMangerImpl object, you are doing it incorrectly. Instead of extending your CustomRecyclerView as:

public class CustomRecyclerViewAdapter extends RecyclerView.Adapter<CustomRecyclerViewAdapter.ViewHolder>

you should be extending as follow:

public class CustomRecyclerViewAdapter extends RecyclerSwipeAdapter<CustomRecyclerViewAdapter.ViewHolder>

By extending RecyclerSwipeAdapter, SwipeItemRecyclerMangerImpl mItemManger is already be declared in RecyclerSwipeAdapter, and you will be able to use mItemManger.

To achieve only one item swipe at a time you will then need to override the following method:

@Override
    public int getSwipeLayoutResourceId(int position) {
        // Return the SwipeLayout Id in your ViewHolder
        return R.id.swipeLayout;
    }

and add the below codes:

@Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        ...
        ...
        mItemManger.bindView(holder.itemView, position);
        holder.swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() {
            @Override
            public void onStartOpen(SwipeLayout layout) {
                mItemManger.closeAllExcept(layout);
            }

            @Override
            public void onOpen(SwipeLayout layout) {

            }

            @Override
            public void onStartClose(SwipeLayout layout) {

            }

            @Override
            public void onClose(SwipeLayout layout) {

            }

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

            }

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

            }
        });
    }

You are all set!

Lay-Ez commented 4 years ago

Also if all you need is only one single item open at a time you can do everything what davischung said except that part `holder.swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() { @Override public void onStartOpen(SwipeLayout layout) { mItemManger.closeAllExcept(layout); }

        @Override
        public void onOpen(SwipeLayout layout) {

        }

        @Override
        public void onStartClose(SwipeLayout layout) {

        }

        @Override
        public void onClose(SwipeLayout layout) {

        }

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

        }

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

        }
    });`

instead just add mItemManger.setMode(Attributes.Mode.Single); in your constructor