SwipeMenuListView的簡單使用

這幾天在學習開源項目SwipeMenuListView的簡單使用,之因此說是「幾天」,是由於在導入項目到Android-studio的過程當中出現了各類各樣的問題,我是直接打開的它裏面的Demo,可是會出現各類錯誤,彷佛並非一個完整的Project,發現沒有app目錄。在網上看各類教程,也大都是要你把它的類庫直接複製一份到本身的項目中去,可是既然Android-studio支持直接使用依賴,爲何那麼多人仍是那麼麻煩的去複製文件到本身的項目中呢?java

答案就是:做者並無把最新的依賴添加進去,可是網上卻幾乎沒有幾我的指出來,這才致使本身反覆在這裏折騰(畢竟這是個下載量很大的開源項目啊,爲何都沒幾我的指出來呢?)做者提供的Demo裏使用了一個BaseSwipListAdapter,代碼以下:android

class AppAdapter extends BaseSwipListAdapter {...}

若是咱們直接也這樣寫的話,會報錯,告訴咱們該類找不到,那些添加了依賴的同窗能夠在jar包中打開看下,看看裏面是否是真的缺乏了BaseSwipListAdapter 這個類(使用依賴的話裏面有不少bug,刪除一條項目只有在咱們將Menu拉回來的時候纔會真正刪除掉)
下面來說下具體怎麼導入而且使用SwipeMenuListView:git

1.導入SwipeMenuListView

咱們能夠從github上下載開源項目SwipeMenuListView的源碼
https://github.com/baoyongzha...github

在此也附上它的依賴,不過在此處並不會用到:app

dependencies {
    compile 'com.baoyz.swipemenulistview:library:1.3.0'
}

這裏咱們在項目中新建一個包,名字爲:ide

com.baoyz.swipemenulistview

(這裏咱們包的名字最好不要改變,不然裏面一些導入的類也要改變路徑),而後將目錄佈局

SwipeMenuListView-master\library\src\main\java\com\baoyz\swipemenulistview\

下面的文件複製到咱們新建的包裏面:學習

clipboard.png

clipboard.png

(這裏爲了方便直接運行,咱們直接將Demo裏的文件、資源等也逐一的複製到了咱們的目錄項目中,可是記得要在清單文件中爲activity進行配置)this

2.SwipeMenuListView的具體使用

這裏咱們先粘貼下Demo中的示例(部分地方有修改),SimpleActivity.javaspa

package com.qc.administrator.myswipedemo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.baoyz.swipemenulistview.BaseSwipListAdapter;
import com.baoyz.swipemenulistview.SwipeMenu;
import com.baoyz.swipemenulistview.SwipeMenuCreator;
import com.baoyz.swipemenulistview.SwipeMenuItem;
import com.baoyz.swipemenulistview.SwipeMenuListView;

import java.util.List;

/**
 * SwipeMenuListView
 * Created by baoyz on 15/6/29.
 */
public class SimpleActivity extends Activity {

    private List<ApplicationInfo> mAppList;
    private AppAdapter mAdapter;
    private SwipeMenuListView mListView;

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

        mAppList = getPackageManager().getInstalledApplications(0);

        mListView = (SwipeMenuListView) findViewById(R.id.listView);

        mAdapter = new AppAdapter();
        mListView.setAdapter(mAdapter);

        // 第1步:設置建立器,而且在其中生成咱們須要的菜單項,將其添加進菜單中
        SwipeMenuCreator creator = new SwipeMenuCreator() {

            @Override
            public void create(SwipeMenu menu) {
                // 建立「打開」項
                SwipeMenuItem openItem = new SwipeMenuItem(
                        getApplicationContext());
                openItem.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,
                        0xCE)));
                openItem.setWidth(dp2px(90));
                openItem.setTitle("Open");
                openItem.setTitleSize(18);
                openItem.setTitleColor(Color.WHITE);
                // 將建立的菜單項添加進菜單中
                menu.addMenuItem(openItem);

                // 建立「刪除」項
                SwipeMenuItem deleteItem = new SwipeMenuItem(
                        getApplicationContext());
                deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,
                        0x3F, 0x25)));
                deleteItem.setWidth(dp2px(90));
                deleteItem.setIcon(R.drawable.ic_delete);
                // 將建立的菜單項添加進菜單中
                menu.addMenuItem(deleteItem);
            }
        };
        // 爲ListView設置建立器
        mListView.setMenuCreator(creator);

        // 第2步:爲ListView設置菜單項點擊監聽器,來監聽菜單項的點擊事件
        mListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
                //position:列表項的下標。如:0,1,2,3,4,...
                //index:菜單項的下標。如:0,1,2,3,4,...
                ApplicationInfo item = mAppList.get(position);
                switch (index) {
                    case 0:
                        // open
                        open(item);
                        break;
                    case 1:
                        // delete
//                    delete(item);
                        mAppList.remove(position);
                        //通知監聽者數據集發生改變,更新ListView界面
                        mAdapter.notifyDataSetChanged();
                        break;
                }
                // true:其餘已打開的列表項的菜單狀態將保持原樣,不會受到其餘列表項的影響而自動收回
                // false:已打開的列表項的菜單將自動收回
                return false;
            }
        });

        // 設置側滑監聽器,監聽側滑開始和側滑結束
        // 注意:當咱們將一個已經側滑出來的菜單從新收回去的時候並不會調用onSwipeStart方法,
        // 可是結束的時候依然會調用onSwipeEnd方法
        mListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {

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

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

        // 設置監聽Menu狀態改變的監聽器(Menu的打開和關閉)
        mListView.setOnMenuStateChangeListener(new SwipeMenuListView.OnMenuStateChangeListener() {
            @Override
            public void onMenuOpen(int position) {
            }

            @Override
            public void onMenuClose(int position) {
            }
        });

        // other setting
//        listView.setCloseInterpolator(new BounceInterpolator());

        // 設置列表項長點擊的監聽器
        mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view,
                                           int position, long id) {
                Toast.makeText(getApplicationContext(), position + " long click", Toast.LENGTH_SHORT).show();
                return false;
            }
        });

    }

    //刪除一個應用,在這裏並無被調用,由於這會卸載相應的app
    private void delete(ApplicationInfo item) {
        try {
            Intent intent = new Intent(Intent.ACTION_DELETE);
            intent.setData(Uri.fromParts("package", item.packageName, null));
            startActivity(intent);
        } catch (Exception e) {
        }
    }

    // 打開app
    private void open(ApplicationInfo item) {
        // Intent.ACTION_MAIN:做爲主進入點啓動,並不指望得到數據
        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        //根據傳進來的ApplicationInfo item設置要解析的應用的包名
        resolveIntent.setPackage(item.packageName);
        //根據指定的Intent解析出對應的應用中全部的activity的信息
        List<ResolveInfo> resolveInfoList = getPackageManager()
                .queryIntentActivities(resolveIntent, 0);
        if (resolveInfoList != null && resolveInfoList.size() > 0) {
            //ResolveInfo:返回依據IntentFilter解析出來的Intent所返回的信息。
            //此部分對應於從AndroidManifest.xml中<意圖>標籤收集信息。
            //解析出來的第一個爲主activity的信息
            ResolveInfo resolveInfo = resolveInfoList.get(0);
            String activityPackageName = resolveInfo.activityInfo.packageName;
            String className = resolveInfo.activityInfo.name;

            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            ComponentName componentName = new ComponentName(
                    activityPackageName, className);

            intent.setComponent(componentName);
            startActivity(intent);
        }
    }

    class AppAdapter extends BaseSwipListAdapter {

        @Override
        public int getCount() {
            return mAppList.size();
        }

        @Override
        public ApplicationInfo getItem(int position) {
            return mAppList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                //夾在金列表項的佈局item_list_app.xml
                convertView = View.inflate(getApplicationContext(),
                        R.layout.item_list_app, null);
                new ViewHolder(convertView);
            }
            ViewHolder holder = (ViewHolder) convertView.getTag();
            // 獲取手機所有應用的信息
            ApplicationInfo item = getItem(position);
            // 加載應用的圖標
            holder.iv_icon.setImageDrawable(item.loadIcon(getPackageManager()));
            // 加載應用的標題
            holder.tv_name.setText(item.loadLabel(getPackageManager()));
            // 爲圖標設置點擊事件監聽器(彈出一個toast)
            holder.iv_icon.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(SimpleActivity.this, "iv_icon_click", Toast.LENGTH_SHORT).show();
                }
            });
            // 爲應用名字設置點擊監聽器(彈出一個toast)
            holder.tv_name.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(SimpleActivity.this,"iv_icon_click",Toast.LENGTH_SHORT).show();
                }
            });
            return convertView;
        }

        class ViewHolder {
            ImageView iv_icon;
            TextView tv_name;

            //根據傳進來的convertView建立ViewHolder,而且將其設置爲convertView的Tag
            public ViewHolder(View view) {
                iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
                tv_name = (TextView) view.findViewById(R.id.tv_name);
                view.setTag(this);
            }
        }

        //這裏咱們能夠根據列表項的位置來設置某項是否容許側滑
        //(此處咱們設置的是當下標爲偶數項的時候不容許側滑)
        @Override
        public boolean getSwipEnableByPosition(int position) {
            if(position % 2 == 0){
                return false;
            }
            return true;
        }
    }

    // 將dp轉換爲px
    private int dp2px(int value) {
        // 第一個參數爲咱們待轉的數據的單位,此處爲 dp(dip)
        // 第二個參數爲咱們待轉的數據的值的大小
        // 第三個參數爲這次轉換使用的顯示量度(Metrics),它提供屏幕顯示密度(density)和縮放信息
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value,
                getResources().getDisplayMetrics());
    }
    //另外一種將dp轉換爲px的方法
    private int dp2px(float value){
        final float scale = getResources().getDisplayMetrics().density;
        return (int)(value*scale + 0.5f);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_left) {
            //這裏咱們能夠經過mListView的setSwipeDirection方法來設置SwipeMenuListView的滑動方向
            mListView.setSwipeDirection(SwipeMenuListView.DIRECTION_LEFT);
            return true;
        }
        if (id == R.id.action_right) {
            mListView.setSwipeDirection(SwipeMenuListView.DIRECTION_RIGHT);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

具體步驟:

1.添加布局代碼

在咱們須要使用該效果的佈局文件中添加以下代碼:

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

2.生成一個菜單建立器

生成一個菜單建立器,在其中生成菜單項,而且將其添加進菜單中,此處的菜單爲咱們側滑具體的列表項以後顯示出來的視圖,以下圖:

clipboard.png

代碼:

SwipeMenuCreator creator = new SwipeMenuCreator() {

            @Override
            public void create(SwipeMenu menu) {
                // 建立「打開」項
                SwipeMenuItem openItem = new SwipeMenuItem(
                        getApplicationContext());
                openItem.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,
                        0xCE)));
                openItem.setWidth(dp2px(90));
                openItem.setTitle("Open");
                openItem.setTitleSize(18);
                openItem.setTitleColor(Color.WHITE);
                // 將建立的菜單項添加進菜單中
                menu.addMenuItem(openItem);

                // 建立「刪除」項
                SwipeMenuItem deleteItem = new SwipeMenuItem(
                        getApplicationContext());
                deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9,
                        0x3F, 0x25)));
                deleteItem.setWidth(dp2px(90));
                deleteItem.setIcon(R.drawable.ic_delete);
                // 將建立的菜單項添加進菜單中
                menu.addMenuItem(deleteItem);
            }
        };

而後爲列表設置建立器:

mListView.setMenuCreator(creator);

3.爲ListView設置菜單項點擊監聽器,監聽菜單項的點擊事件

mListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
            //position:列表項的下標。如:0,1,2,3,4,...
            //index:菜單項的下標。如:0,1,2,3,4,...
            @Override
            public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {//具體實現}

4.設置側滑監聽器(若是有須要的話)

設置側滑監聽器,監聽側滑開始和側滑結束。
注意:當咱們將一個已經側滑出來的菜單從新收回去的時候並不會調用onSwipeStart方法,可是結束的時候依然會調用onSwipeEnd方法

mListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {

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

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

5.設置監聽Menu狀態改變的監聽器(Menu的打開和關閉)

mListView.setOnMenuStateChangeListener(new SwipeMenuListView.OnMenuStateChangeListener() {
            @Override
            public void onMenuOpen(int position) {
            }

            @Override
            public void onMenuClose(int position) {
            }
        });

6.爲咱們的ListView設置適配器

咱們的適配器能夠繼承自BasseAdapter,也能夠繼承自該開源項目提供的一個適配器類BaseSwipListAdapter,並重寫其中的方法

7.設置具體的某個列表項是否容許側滑

@Override
    public boolean getSwipEnableByPosition(int position) {
        if(position % 2 == 0){
            return false;
        }
        return true;
    }

這裏做者設置的是當爲偶數項的時候不容許側滑(返回值爲false)

8.dp轉px方法

// 將dp轉換爲px
    private int dp2px(int value) {
        // 第一個參數爲咱們待轉的數據的單位,此處爲 dp(dip)
        // 第二個參數爲咱們待轉的數據的值的大小
        // 第三個參數爲這次轉換使用的顯示量度(Metrics),它提供屏幕顯示密度(density)和縮放信息
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value,
                getResources().getDisplayMetrics());
    }
    //另外一種將dp轉換爲px的方法
    private int dp2px(float value){
        final float scale = getResources().getDisplayMetrics().density;
        return (int)(value*scale + 0.5f);
    }

9.設置側滑的方向(也決定了Menu的出現位置)

//設置向左滑動出現Menu
mListView.setSwipeDirection(SwipeMenuListView.DIRECTION_LEFT);
//設置向右滑動出現Menu
mListView.setSwipeDirection(SwipeMenuListView.DIRECTION_RIGHT);

10.設置列表項顯示不一樣的Menu

其實咱們可讓列表項顯示不一樣的Menu,咱們能夠經過重寫BaseAdapter的getItemViewType(int position)和 getViewTypeCount()方法,而後在菜單建立器SwipeMenuCreator中根據傳進去的SwipeMenu的getViewType()的值來決定生成怎樣的Menu

文章最後附上原做者Demo中DifferentMenuActivity.java的代碼供參考:

/**
 * SwipeMenuListView
 * Created by baoyz on 15/6/29.
 */
public class DifferentMenuActivity  extends Activity {

    private List<ApplicationInfo> mAppList;
    private AppAdapter mAdapter;

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

        mAppList = getPackageManager().getInstalledApplications(0);

        SwipeMenuListView listView = (SwipeMenuListView) findViewById(R.id.listView);
        mAdapter = new AppAdapter();
        listView.setAdapter(mAdapter);

        // step 1. create a MenuCreator
        SwipeMenuCreator creator = new SwipeMenuCreator() {

            @Override
            public void create(SwipeMenu menu) {
                // Create different menus depending on the view type
                switch (menu.getViewType()) {
                    case 0:
                        createMenu1(menu);
                        break;
                    case 1:
                        createMenu2(menu);
                        break;
                    case 2:
                        createMenu3(menu);
                        break;
                }
            }

            private void createMenu1(SwipeMenu menu) {
                SwipeMenuItem item1 = new SwipeMenuItem(
                        getApplicationContext());
                item1.setBackground(new ColorDrawable(Color.rgb(0xE5, 0x18,
                        0x5E)));
                item1.setWidth(dp2px(90));
                item1.setIcon(R.drawable.ic_action_favorite);
                menu.addMenuItem(item1);
                SwipeMenuItem item2 = new SwipeMenuItem(
                        getApplicationContext());
                item2.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,
                        0xCE)));
                item2.setWidth(dp2px(90));
                item2.setIcon(R.drawable.ic_action_good);
                menu.addMenuItem(item2);
            }

            private void createMenu2(SwipeMenu menu) {
                SwipeMenuItem item1 = new SwipeMenuItem(
                        getApplicationContext());
                item1.setBackground(new ColorDrawable(Color.rgb(0xE5, 0xE0,
                        0x3F)));
                item1.setWidth(dp2px(90));
                item1.setIcon(R.drawable.ic_action_important);
                menu.addMenuItem(item1);
                SwipeMenuItem item2 = new SwipeMenuItem(
                        getApplicationContext());
                item2.setBackground(new ColorDrawable(Color.rgb(0xF9,
                        0x3F, 0x25)));
                item2.setWidth(dp2px(90));
                item2.setIcon(R.drawable.ic_action_discard);
                menu.addMenuItem(item2);
            }

            private void createMenu3(SwipeMenu menu) {
                SwipeMenuItem item1 = new SwipeMenuItem(
                        getApplicationContext());
                item1.setBackground(new ColorDrawable(Color.rgb(0x30, 0xB1,
                        0xF5)));
                item1.setWidth(dp2px(90));
                item1.setIcon(R.drawable.ic_action_about);
                menu.addMenuItem(item1);
                SwipeMenuItem item2 = new SwipeMenuItem(
                        getApplicationContext());
                item2.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,
                        0xCE)));
                item2.setWidth(dp2px(90));
                item2.setIcon(R.drawable.ic_action_share);
                menu.addMenuItem(item2);
            }
        };
        // set creator
        listView.setMenuCreator(creator);

        // step 2. listener item click event
        listView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {
                ApplicationInfo item = mAppList.get(position);
                switch (index) {
                    case 0:
                        // open
                        break;
                    case 1:
                        // delete
//                    delete(item);
                        mAppList.remove(position);
                        mAdapter.notifyDataSetChanged();
                        break;
                }
                return false;
            }
        });

    }

    class AppAdapter extends BaseAdapter {

        @Override
        public int getCount() {
            return mAppList.size();
        }

        @Override
        public ApplicationInfo getItem(int position) {
            return mAppList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public int getViewTypeCount() {
            // menu type count
            return 3;
        }

        @Override
        public int getItemViewType(int position) {
            // current menu type
            return position % 3;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = View.inflate(getApplicationContext(),
                        R.layout.item_list_app, null);
                new ViewHolder(convertView);
            }
            ViewHolder holder = (ViewHolder) convertView.getTag();
            ApplicationInfo item = getItem(position);
            holder.iv_icon.setImageDrawable(item.loadIcon(getPackageManager()));
            holder.tv_name.setText(item.loadLabel(getPackageManager()));
            return convertView;
        }

        class ViewHolder {
            ImageView iv_icon;
            TextView tv_name;

            public ViewHolder(View view) {
                iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
                tv_name = (TextView) view.findViewById(R.id.tv_name);
                view.setTag(this);
            }
        }
    }

    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                getResources().getDisplayMetrics());
    }
}
相關文章
相關標籤/搜索