1. 程式人生 > >Android仿QQ側滑(刪除、置頂等)功能

Android仿QQ側滑(刪除、置頂等)功能

實現類似QQ滑動出現可操作項的功能,在網上看到有人自定義LinearLayout實現這個效果,但是靈活性有限。此demo使用開源專案SwipeLayout實現該功能。關於SwipeLayout的常用設定和屬性,這裡都做介紹,下面進入正題。

一、效果圖

swipeLayout.gif

二、程式碼片段

  • 主頁佈局和主頁的Java程式碼都和平時使用沒有區別,程式碼沒必要貼出來了。這裡使用的ListView演示,還可以是GridView,ExpandableListView。
  • 最關鍵的程式碼部分,ListView介面卡佈局:
  • <?xml version="1.0" encoding="utf-8"?>
    <com.daimajia.swipe.SwipeLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/swipe" android:layout_width="match_parent" android:layout_height="match_parent" app:drag_edge="right">
    <LinearLayout android:id="@+id/trash" android:layout_width
    ="160dp" android:layout_height="match_parent" android:gravity="center" android:orientation="horizontal" android:tag="Bottom">
    <TextView android:id="@+id/swipe_open" android:layout_width="1dp" android:layout_height="match_parent"
    android:layout_weight="1" android:background="#f55509" android:gravity="center" android:text="開啟" android:textColor="@android:color/white" android:textSize="20sp" />
    <TextView android:id="@+id/swipe_delete" android:layout_width="1dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@android:color/holo_red_dark" android:gravity="center" android:text="刪除" android:textColor="@android:color/white" android:textSize="20sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white" android:gravity="center_vertical" android:orientation="horizontal" android:padding="5dp"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white" android:orientation="vertical" android:paddingLeft="5dp"> <TextView android:id="@+id/tv_nickname" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="17sp" /> <TextView android:id="@+id/tv_msg" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:textSize="15sp" /> </LinearLayout> </LinearLayout> </com.daimajia.swipe.SwipeLayout>

    說明:最外層是我們的SwipeLayout,裡面是兩個LinearLayout,第一層是我們的頁面佈局,第二層是我們的側邊劃出來的佈局。關鍵的屬性這裡有體現:

    app:drag_edge="right"

    此屬性是設定我們的側邊佈局劃出位置,預設是右邊,可以設定左邊、底部、頂部。

  • 介面卡Java程式碼:
  • package com.example.mjj.swipelayoutdemo;
    
    import android.content.Context;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.daimajia.swipe.SwipeLayout;
    import com.daimajia.swipe.adapters.BaseSwipeAdapter;
    
    import java.util.List;
    
    /**
     * Description:介面卡
     * <p>
     * Created by Mjj on 2016/12/12.
     */
    
    public class MySwipeAdapter extends BaseSwipeAdapter implements View.OnClickListener {
    
        private Context context;
        private List<ItemBean> list;
        private final String TAG = "MySwipeAdapter";
    
        public MySwipeAdapter(Context context, List<ItemBean> list) {
            this.context = context;
            this.list = list;
        }
    
        /**
         * 返回SwipeLayout的ID
         *
         * @param position
         * @return
         */
        @Override
        public int getSwipeLayoutResourceId(int position) {
            return R.id.swipe;
        }
    
        /**
         * 繫結佈局
         *
         * @param position
         * @param parent
         * @return
         */
        @Override
        public View generateView(int position, ViewGroup parent) {
            View itemView = View.inflate(context, R.layout.item_swipe, null);
            SwipeLayout swipeLayout = (SwipeLayout) itemView.findViewById(getSwipeLayoutResourceId(position));
    
            // 設定滑動是否可用,預設為true
            swipeLayout.setSwipeEnabled(true);
    
            /**
             * 開啟時呼叫:迴圈呼叫onStartOpen,onUpdate,onHandRelease,onUpdate,onOpen,
             * 關閉時呼叫:onStartClose,onUpdate,onHandRelease,onHandRelease,onUpdate,onClose
             */
            swipeLayout.addSwipeListener(new SwipeLayout.SwipeListener() {
                @Override
                public void onStartOpen(SwipeLayout layout) {
    //                Log.e(TAG, "onStartOpen: ");
                }
    
                @Override
                public void onOpen(SwipeLayout layout) {
    //                Log.e(TAG, "onOpen: ");
                }
    
                @Override
                public void onStartClose(SwipeLayout layout) {
    //                Log.e(TAG, "onStartClose: ");
                }
    
                @Override
                public void onClose(SwipeLayout layout) {
    //                Log.e(TAG, "onClose: ");
                }
    
                @Override
                public void onUpdate(SwipeLayout layout, int leftOffset, int topOffset) {
    //                Log.e(TAG, "onUpdate: ");
                }
    
                @Override
                public void onHandRelease(SwipeLayout layout, float xvel, float yvel) {
    //                Log.e(TAG, "onHandRelease: ");
                }
            });
    
            // 設定為true,在當前一條item(除側滑以外部分)點選時,可收回側滑出來部分,預設為false
            swipeLayout.setClickToClose(true);
    
            // SwipeLayout單擊事件,可替代ListView的OnitemClickListener事件.
            swipeLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    //                Log.e(TAG, "onClick: ");
                }
            });
    
            return itemView;
        }
    
        /**
         * 繫結資料
         *
         * @param position
         * @param convertView
         */
        @Override
        public void fillValues(int position, View convertView) {
            TextView tvNickName = (TextView) convertView.findViewById(R.id.tv_nickname);
            TextView tvMsg = (TextView) convertView.findViewById(R.id.tv_msg);
            TextView tvSwipeOpen = (TextView) convertView.findViewById(R.id.swipe_open);
            TextView tvSwipeDelete = (TextView) convertView.findViewById(R.id.swipe_delete);
            tvNickName.setText(list.get(position).getNickName());
            tvMsg.setText(list.get(position).getMsg());
    
            tvSwipeDelete.setOnClickListener(this);
            tvSwipeOpen.setOnClickListener(this);
        }
    
        @Override
        public int getCount() {
            return list.size();
        }
    
        @Override
        public ItemBean getItem(int i) {
            return list.get(i);
        }
    
        @Override
        public long getItemId(int i) {
            return i;
        }
    
        @Override
        public void onClick(View view) {
            int id = view.getId();
            switch (id) {
                case R.id.swipe_open:
                    // 關閉所有開啟的Swipe的item
                    this.closeAllItems();
                    Toast.makeText(context, "Swipe--Open", Toast.LENGTH_SHORT).show();
                    break;
                case R.id.swipe_delete:
                    this.closeAllItems();
                    Toast.makeText(context, "Swipe--Delete", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
    

    說明:和平時我們寫的介面卡不一樣的是繼承自BaseSwipeAdapter,需要實現的方法除了圖中展示的,還有一個getItemId();再沒有別的。這裡主要解釋下幾個平時沒有見過的方法:

    public int getSwipeLayoutResourceId(int position)

    此方法返回的是我們的SwipeLayout的ID,而不是佈局的ID。

    public View generateView(int position, ViewGroup parent)

    此方法返回的作用是和我們的item佈局進行關聯的,並在這裡設定swipeLayout的相關屬性。

    public void fillValues(int position, View convertView)

    此方法用來給我們的item中的控制元件繫結資料,並根據需要設定事件等操作。

    *三、常用設定介紹*

    1,如果我們的這個介面卡是重用的,而有些時候不需要滑動功能,那麼可以呼叫此方法來控制滑動是否可用。  

    swipeLayout.setSwipeEnabled(true);

    2,當我們的側邊佈局還出來的時候,此時點選該條item,預設是不會收回的,也就是下面程式碼預設是false。

    falseswipeLayout.setClickToClose(true);

    3,如演示,當點選了刪除或者開啟後,劃出來的側邊佈局自動收回了,及時通過下面的屬性closeAllItems()方法控制的。預設是不會收回的。

    this.closeAllItems();

    4,前面已經提到了,我們的側滑出現的位置,如有需求是需要左邊或者右邊,別忘了它:

    app:drag_edge="right"

    *四、使用*

    compile 'com.daimajia.swipelayout:library:1.2.0'

    五、總結
    demo已上傳至github,連結放在了公眾號”code小生”裡,關注檢視。