Swipe Menu for List View – Review of SwipeMenuListView library

Recently I found couple of applications that have that nice feature when you swipe item on list view you get menu with additional options that you can click and perform an action . I checked out Android Arsenal to see what libraries are already available for this functionality. I found two interesting implementations : SwipeMenuListView and SwipeListView. In this article I shall show you how you can use this first one and discuss little bit what I liked and disliked in this implementation. Latter one I shall leave for another article.

For SwipeMenuListView you can find source code on a GitHub, also you can find some demo code. I modified little bit this demo code so that I can test it and present it in this article. First let us start with importing this library into our project. This is pretty simple, all you need to do is checkout the project, take all classes from the package com.baoyz.swipemenulistview, create same package in your project and copy these classes. That’s all, no need for any additional configuration.

 

Now, how we are going to use this library in our project? First of all, we shall create main layout that will just have SimpleMenuListView tag inside:

<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   tools:context=".MainActivity"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent">

   <com.baoyz.swipemenulistview.SwipeMenuListView
      android:id="@+id/listView"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:scrollbars="vertical"/>

</LinearLayout>

This is pretty simple, if you look at the implementation of class com.baoyz.swipemenulistview.SwipeMenuListView you shall see that it extends ListView class, this means that all attributes of the tag ListView should be applicable for this implementation, but I have not found any attributes that are custom for this component. for purpose of presentation we shall create one more layout that will be used for each row in a list view, later we shall define adapter and use this layout.


<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="wrap_content"
   android:padding="8dp" >

   <ImageView
      android:id="@+id/image_view"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:src="@drawable/ic_launcher" />

   <TextView
      android:id="@+id/item_label"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerVertical="true"
      android:layout_marginLeft="10sp"
      android:layout_toRightOf="@+id/image_view"
      android:text="name"
      android:textColor="@android:color/black"
      android:textSize="18sp" />
</RelativeLayout>

To make use of this layout we need custom adapter:


public class CustomArrayAdapter extends ArrayAdapter<String>{
   protected LayoutInflater inflater;
   protected int layout;

   public CustomArrayAdapter(Activity activity, int resourceId, List<String> objects){
      super(activity, resourceId, objects);
      layout = resourceId;
      inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   }

   @Override
   public View getView(int position, View convertView, ViewGroup parent) {
      View v = inflater.inflate(layout, parent, false);
      TextView tv = (TextView)v.findViewById(R.id.item_label);
      tv.setText(getItem(position));
      return v;
   }
}

And finally let us see how main activity looks like:

public class MainActivity extends ActionBarActivity {
   @Override
   protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);

   setContentView(R.layout.activity_main);
   SwipeMenuListView listView = (SwipeMenuListView)findViewById(R.id.listView);
   final List<String> list = new ArrayList<>();
   list.add("Test 1");
   list.add("Test 2");
   list.add("Test 3");
   final CustomArrayAdapter adapter = new CustomArrayAdapter(this, R.layout.list_item, list);
   listView.setAdapter(adapter);
   SwipeMenuCreator creator = new SwipeMenuCreator() {

      @Override
      public void create(SwipeMenu menu) {
         //create an action that will be showed on swiping an item in the list
         SwipeMenuItem item1 = new SwipeMenuItem(
            getApplicationContext());
         item1.setBackground(new ColorDrawable(Color.DKGRAY));
         // set width of an option (px)
         item1.setWidth(200);
         item1.setTitle("Action 1");
         item1.setTitleSize(18);
         item1.setTitleColor(Color.WHITE);
         menu.addMenuItem(item1);

         SwipeMenuItem item2 = new SwipeMenuItem(
            getApplicationContext());
         // set item background
         item2.setBackground(new ColorDrawable(Color.RED));
         item2.setWidth(200);
         item2.setTitle("Action 2");
         item2.setTitleSize(18);
         item2.setTitleColor(Color.WHITE);
         menu.addMenuItem(item2);
      }
   };
   //set MenuCreator
   listView.setMenuCreator(creator);
   // set SwipeListener
   listView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {

      @Override
      public void onSwipeStart(int position) {
         // swipe start
      }

      @Override
      public void onSwipeEnd(int position) {
         // swipe end
      }
   });

   listView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {

      @Override
      public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
         String value = adapter.getItem(position);
         switch (index) {
         case 0:
            Toast.makeText(getApplicationContext(), "Action 1 for "+ value , Toast.LENGTH_SHORT).show();
            break;
         case 1:
            Toast.makeText(getApplicationContext(), "Action 2 for "+ value , Toast.LENGTH_SHORT).show();
            break;
         }
         return false;
      }});

    }
}

First part of method onCreate represents setting the layout, fetching the SwipeMenuListView from defined layout, defining list of values for items in the list view and instantiating adapter for SwipeMenuListView. Second partof the code defines SwipeMenuCreator. For this class you have to ovrerride createMenu method that has a parameter of SwipeMenu class. SwipeMenu represents a list of items defined as SwipeMenuItems (options in the menu that represent actions), this menu is showed once you swipe an item of a list view. For each SwipeMenuItem you can define: id, icon, background, title, title color, title size and width. Width is defined in px so in the example on GitHub authors provided a method dp2px that you can use.

After you set MenuCreator, next is to define and set OnSwipeListener for SwipeMenuListView. OnSwipeListener is an interface that has two methods defined: onSwipeStart and onSwipeEnd where you can override and define certain actions,  in this example we have left them empty.

Final step in setting up SwipeMenuListView is to set OnMenuItemClickListener. In this listener you are defining actions that are to be executed on selection of each item in the swipe menu. All what is needed here is to override method onMenuItemClick. This method provides as a parameter index that identifies item that is clicked and position of the item from SwipeMenuListView. Once you define this listener everything is ready and should work perfectly fine. Below you can see an screenshot of application we described here.

swipeapp

Now what I would like to see as enhancement of this project/library is that we can define our menu items using xml layout file.N, looking at the limitations on this library there are some that can be solved in future releases, one of them is a number of  items and width of and item you can have in the swipe menu, in a way it is limited by the width of your screen, so if list of items in swipe menu go beyond the border of the screen after swipe, you will not be able to select them. In that way, another enhancement that I would like to see here is that once swipe menu is opened you are able to swipe trough the menu list and position yourself on a item you want to select.

Next time we shall look at another library that provides same functionality.

Posted in Android Development Tagged with: , , ,
17 comments on “Swipe Menu for List View – Review of SwipeMenuListView library
  1. siddhu says:

    gud evng sir
    for 3 listview iems it works perfectly.when we want to perform 20 listview items i got position problem plz tell me how to overcome this problem.

    • Dorde Popovic says:

      What do you mean by position problem (what is happening exactly)? Also post a part of your code that you believe it is making problem.

      • unique shakya says:

        I have the same issue… for eg:

        items.add(new Item(“Item 1″,”First Item on the list”,”abc”,”Item 1.4″,”Item 1.5″));
        items.add(new Item(“Item 2″,”Second Item on the list”,”xyz”,”item 2.4″,”item 2.5″));
        items.add(new Item(“Item 3″,”Third Item on the list”,”qwe”,”item 3.4″,”item 3.5″));
        items.add(new Item(“Item 4″,”Forth Item on the list”,”qwe”,”item 4.4″,”item 4.5″));
        items.add(new Item(“Item 5″,”Fifth Item on the list”,”qwe”,”item 5.4″,”item 5.5″));
        items.add(new Item(“Item 6″,”Sixth Item on the list”,”qwe”,”item 6.4″,”item 6.5″));
        items.add(new Item(“Item 7″,”Seventh Item on the list”,”qwe”,”item 7.4″,”item 7.5″));

        this is the array list… but in the application, the position of these items are random and also some of the items disappear as well.. Can you help me??

  2. Ranyele Amorim says:

    Hello!
    Very good your tutorial! I’m just a problem in the presentation of the lines, when I use the com.baoyz.swipemenulistview.SwipeMenuListView view the text and the image of the lines is repeated. I’ll post a picture to illustrate what I mean. Do you know if there is a bug that? When I use the common ListView not have this problem.

    Thank you for your attention.

    Link to the image: Left ListView – Right SwipeMenuListView
    https://peoplewaytecnologia-my.sharepoint.com/personal/ramorim_peopleway_com_br/_layouts/15/guestaccess.aspx?guestaccesstoken=PoC0cHOf9ya9PurOgXa8TXTX0w7NPvEC4Q3xPWrqikk%3d&docid=0355700484af54e699d9be5c86093b78c

    • Dorde Popovic says:

      Can you post some of your code, it will be easier to check the problem.

      • Ranyele Amorim says:

        Hi!
        Thx for attention!

        All code here
        activity_main.xml

        Activity
        protected Usuario usuario;
        /**
        * O DAO do Usuário.
        */
        protected UsuarioDAO usuarioDAO;
        /**

        /**
        * A lista de empresas.
        *
        */
        private SwipeMenuListView listEmpresas;

        /** O BO da mensagem
        private MensagemBO mensagemBO;
        */

        /**
        * O BO da empresa
        */
        private EmpresaBO empresaBO;
        /**
        * Lista de empresa temporaria utilizada para mudar de ‘recentes’ para
        * ‘todos’ e vice-versa
        */
        private List empresasTemp;
        /**
        * A lista completa de empresas
        */
        private List empresas;
        /**
        * O Comparator que ordena por quantidade de PA.
        */
        private Comparator comparatorEmpresaPorPa;
        /**
        * O Comparator que ordena por ultimo acesso
        */
        private Comparator comparatorEmpresaUltimoAcesso;
        /**
        * O Adapter da lista de todas as empresas
        */
        private EmpresasAdapter empresasAdapterTodos;
        /**
        * O Adapter da lista das empresas recentemente acessadas
        */
        private EmpresasAdapter empresasAdapterRecentes;
        /**
        * O Adapter da lista das empresas favoritas
        */
        private EmpresasAdapter empresasAdapterFavoritos;

        private BroadcastReceiver mBroadcastReceiver;
        private ProgressBar progressCarregamentoLista;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, “onCreate(Bundle savedInstanceState)”);
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        mainContext = this;

        abas = (LinearLayout) findViewById(R.id.layoutBotoes);
        /*
        O campo utilizado para busca na lista de empresas
        */
        EditText editBusca = (EditText) findViewById(R.id.editBusca);
        listEmpresas = (SwipeMenuListView) findViewById(R.id.listEmpresas);// (SwipeMenuListView)
        progressCarregamentoLista = (ProgressBar) findViewById(R.id.progressCarregamento);

        // Atualiza a lista de Empresas
        empresaBO = new EmpresaBO(this);

        comparatorEmpresaPorPa = new ComparatorEmpresaPorPa();
        comparatorEmpresaUltimoAcesso = new ComparatorEmpresaUltimoAcesso();

        usuarioDAO = new UsuarioDAO(this);
        usuario = usuarioDAO.getUsuario();
        usuarioDAO.fechar();

        empresas = empresaBO.buscarTodos();
        empresasTemp = empresas;

        // Primeira ordenção da lista ordena por PA.
        Collections.sort(empresasTemp, comparatorEmpresaPorPa);

        // Configura a busca nas lista de empresas
        editBusca.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        empresasAdapterTodos.getFilter().filter(s);
        empresasAdapterRecentes.getFilter().filter(s);
        empresasAdapterFavoritos.getFilter().filter(s);

        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
        int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
        });

        // configura os adapters para a listagem
        empresasAdapterTodos = new EmpresasAdapter(this, empresasTemp);
        empresasAdapterRecentes = new EmpresasAdapter(this, new ArrayList());
        empresasAdapterFavoritos = new EmpresasAdapter(this, new ArrayList());

        // Criacao do botao lateral da listEmpresas para o historico
        SwipeMenuCreator creator = new SwipeMenuCreator() {

        @Override
        public void create(SwipeMenu menu) {
        // create “open” item
        SwipeMenuItem historicoItem = new SwipeMenuItem(
        getApplicationContext());
        // set item background
        historicoItem.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,
        0xCE)));
        // set item width
        historicoItem.setWidth(dp2px(90));
        // set item title
        historicoItem.setTitle(“Historico”);
        // set item title fontsize
        historicoItem.setTitleSize(18);
        // set item title font color
        historicoItem.setTitleColor(Color.WHITE);
        historicoItem.setIcon(R.drawable.ic_menu_recent_history);
        // add to menu
        menu.addMenuItem(historicoItem);

        }
        };
        listEmpresas.setMenuCreator(creator);
        listEmpresas.setAdapter(empresasAdapterTodos);
        listEmpresas.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
        switch (index) {
        case 0:

        carregarHistorico(position);
        break;

        }
        // false : close the menu; true : not close the menu
        return false;
        }
        });

        // Inicia o chat com a empresa selecionada.
        listEmpresas.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView parent, View view, int position, long id) {
        Log.i(CATEGORIA, “Iniciando Chat com:” + id + “(id da lista)”);
        iniciarChat(position, false);
        }
        });
        }

  3. santhosh says:

    I need to implement swiping from both the sides to show different menu options. How can I do this? Please advice. Thanks.

  4. KrishnaKanth says:

    How can I add a custom view as a menu item. I have a layout(xml file). I want to show that as menu when user swipes the list row. Is it possible ?

    • Dorde Popovic says:

      I think I mentioned at the end of this article that this is currently a limitation to have your custom layout as option menu that shows up after you swipe element. Maybe there is a newer version now of this library. Please check.

  5. Rohan Patel says:

    Do I need to purchase license to use this library in my commercial android application.

  6. Atul Shinde says:

    how can i hide previously opened item and open the new one in a single swipe or touchEvent

    • Dorde Popovic says:

      Not sure that this is possible in this library.

    • Anfer says:

      You can do this by setting “setOnItemClickListener” to swipeListView and override onItemClick.
      add the follwing code inside onItemClick
      swipeListView.smoothOpenMenu(position);

      This will open the new item and close the previously opened.

  7. pragya says:

    Can you provide a code of deleting an element in swipe list view?

    • Jayce Mico Dignadice says:

      adapter.remove(adapter.getItem(position));
      adapter.notifyDataSetChanged();

      Hope this will help 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe for Newsletter

Categories