Android 之 SwipeLayout 的基本使用

yellowleopard 发布于1年前 阅读13518次
0 条评论

 

swipelayout的 项目地址

使用方法( 以listview作为例子):

Step 1 添加项目依赖

项目依赖如下:

在你的app中的build.gradle文件中添加以下依赖

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
//swipeLayout
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile "com.daimajia.swipelayout:library:1.2.0@aar"
    compile 'com.daimajia.easing:library:1.0.0@aar'
    compile 'com.daimajia.androidanimations:library:1.1.2@aar'
    compile 'com.nineoldandroids:library:2.4.0'
}

注意:

compile 'com.daimajia.androidanimations:library:1.1.2@aar'  
 compile'com.nineoldandroids:library:2.4.0'  
 

这两个库的引用是滑动bottomView所需要依赖的。

Step 2 添加swipeLayout的xml文件

首先创建一个swipelayout作为列表项(listview_item)的布局

swipelayout由两部分view组成:surfaceView 和 bottomView

Android 之 SwipeLayout 的基本使用  

图中左边是surfaceView,右边被滑动出来的是bottomView

Tips:

  1. surfaceView应当写在此view中的最后,其余的都是bottomView

  2. 在你的bottomView中最好使用layout_gravity这个属性

xml模版格式:

<?xml version="1.0" encoding="utf-8"?>
<com.daimajia.swipe.SwipeLayout android:id="@+id/swipe"
                                xmlns:android="http://schemas.android.com/apk/res/android"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content">


    <!-- Bottom View Start-->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="@color/red"
        android:orientation="horizontal"
        android:padding="4dp"
        android:weightSum="1">

    <!--some view in it-->

    </LinearLayout>
    <!-- Bottom View End-->


    <!--surfaceView Start-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <!--some view in it-->

    </LinearLayout>
    <!--surfaceView End-->

</com.daimajia.swipe.SwipeLayout>

Example:

<?xml version="1.0" encoding="utf-8"?>
<com.daimajia.swipe.SwipeLayout android:id="@+id/swipe"
                                xmlns:android="http://schemas.android.com/apk/res/android"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content">


    <!-- Bottom View Start-->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:background="@color/red"
        android:orientation="horizontal"
        android:padding="4dp"
        android:weightSum="1">

        <TextView
            android:id="@+id/tv_cancel_favorite"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="取消收藏"
            android:textColor="@color/white"
            android:textSize="14sp"/>
    </LinearLayout>
    <!-- Bottom View End-->


    <!--surfaceView Start-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:orientation="horizontal"
            android:paddingLeft="10dp">

            <TextView
                android:id="@+id/tv_station_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center_vertical"
                android:text="@string/text_station_title"
                android:textColor="@color/popup_title_gray"
                android:textSize="16sp"/>

            <ImageView
                android:id="@+id/iv_pop_openImage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="6dp"
                android:src="@mipmap/station_open_up"
                android:visibility="gone"/>

            <ImageView
                android:id="@+id/iv_pop_freeImage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="4dp"
                android:gravity="center_vertical"
                android:src="@mipmap/station_free_park"
                android:visibility="gone"/>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:paddingLeft="10dp">

            <ImageView
                android:id="@+id/iv_navi_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:src="@drawable/address"/>

            <TextView
                android:id="@+id/tv_pop_distance"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="6dp"
                android:layout_marginTop="10dp"
                android:text="@string/text_station_distance"
                android:textColor="@color/popup_distance_gray"
                android:textSize="13sp"/>

            <View
                android:layout_width="1dp"
                android:layout_height="15dp"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="10dp"
                android:background="@color/div_line"/>

            <TextView
                android:id="@+id/tv_pop_address"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:layout_marginTop="10dp"
                android:singleLine="true"
                android:text="@string/text_station_address"
                android:textColor="@color/popup_address_gray"
                android:textSize="13sp"/>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="horizontal"
            android:paddingBottom="6dp"
            android:paddingLeft="10dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/text_station_opentime"
                android:textColor="@color/popup_address_gray"
                android:textSize="13sp"/>

            <TextView
                android:id="@+id/tv_pop_opentime"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:text="@string/text_station_time"
                android:textColor="@color/popup_address_gray"
                android:textSize="13sp"/>
        </LinearLayout>

    </LinearLayout>
    <!--surfaceView End-->

</com.daimajia.swipe.SwipeLayout>

现在你已经创建好的列表项的布局了,要想在activity中让listview使用这个swipelayout你还需要一个listviewAdapter

Step 3 创建swipeLayout的adapter

首先swipelayout的adapter是继承于BaseAdapter,不同的是你不需要重写getView(),取而代之的是你需要重写以下三个方法来代替getView():

//return the `SwipeLayout` resource id in your listview | gridview item layout.
public abstract int getSwipeLayoutResourceId(int position);

//generate a new item layout.
public abstract View generateView(int position, ViewGroup parent);

/*fill values to your item layout returned from `generateView`.
  The position param here is passed from the BaseAdapter's 'getView()*/
public abstract void fillValues(int position, View convertView);

所以最终你在实现ListViewAdapter的时候需要重写6个方法:

  1. public int getSwipeLayoutResourceId (int position)

  2. public View generateView (final int position, ViewGroup parent)

  3. public void fillValues (int position, View convertView)

  4. public int getCount ()

  5. public Object getItem (int position)

  6. public long getItemId (int position)

Tips:

  1. 如果你想绑定监听事件应当在 fillValues() 方法中去实现而不是在 generateView() 方法中!!

    如果你按照该项目作者在github上的demo把bind listener以及fill values的具体实现写在 generateView() 中,则会出现删除item控件错乱的问题。

    问题详见: swipeLayout issue #14 -- github

  2. 为了避免滑动事件在滑回来不与该swipelayout的点击事件冲突,swipelayout的点击事件请使用 swipeLayout.getSurfaceView().setOnClickListener 方法去实现。

    Example:

/**
     * swipeLayout控件的listviewAdapter
     */
    public class FavoriteStationListViewAdapter extends BaseSwipeAdapter {

        private Context mContext;
        private ArrayList<FavoriteStationEntity> dataList;

        private SwipeLayout mSwipeLayout;

        public FavoriteStationListViewAdapter(Context mContext, ArrayList<FavoriteStationEntity> dataList) {
            this.mContext = mContext;
            this.dataList = dataList;
        }

        @Override
        public int getSwipeLayoutResourceId(int position) {
            return R.id.swipe;
        }

        /**
         * 此方法中一定不能绑定监听器和填充数据
         * never bind listeners or fill values, just genertate view here !!
         *
         * @param position
         * @param parent
         * @return
         */
        @Override
        public View generateView(final int position, ViewGroup parent) {

            View v = LayoutInflater.from(mContext).inflate(R.layout.listview_item_favorite_station, null);
            return v;
        }

        @Override
        public void fillValues(final int position, View convertView) {

            favoriteStation = dataList.get(position);

            //填充数据
            TextView stationName = (TextView) convertView.findViewById(R.id.tv_station_name);
            stationName.setText(favoriteStation.getStationName());

            if (favoriteStation.getCompetence() == 0) {//对外开放
                convertView.findViewById(R.id.iv_pop_openImage).setVisibility(View.VISIBLE);
            } else {
                convertView.findViewById(R.id.iv_pop_openImage).setVisibility(View.GONE);
            }

            if (favoriteStation.getParkPrice().equals("免费")) {//免停车费
                convertView.findViewById(R.id.iv_pop_freeImage).setVisibility(View.VISIBLE);
            } else {
                convertView.findViewById(R.id.iv_pop_freeImage).setVisibility(View.GONE);
            }

            TextView stationAddress = (TextView) convertView.findViewById(R.id.tv_pop_address);
            stationAddress.setText(favoriteStation.getAddress());

            TextView openTime = (TextView) convertView.findViewById(R.id.tv_pop_opentime);
            openTime.setText(favoriteStation.getServiceStartTime() + "--" + favoriteStation.getServiceEndTime());

            TextView stationDistance = (TextView) convertView.findViewById(R.id.tv_pop_distance);
            stationDistance.setText(favoriteStation.getDistance());


            mSwipeLayout = (SwipeLayout) convertView.findViewById(getSwipeLayoutResourceId(position));
            //绑定监听事件
            mSwipeLayout.addSwipeListener(new SimpleSwipeListener() {
                @Override
                public void onOpen(SwipeLayout layout) {
                    YoYo.with(Techniques.Tada).duration(500).delay(100).playOn(layout.findViewById(R.id.tv_cancel_favorite));
                }
            });

            /**
             * 用getSurfaceView()可以防止滑回与点击事件冲突
             */
            mSwipeLayout.getSurfaceView().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {//跳转到充电站详情

                    favoriteStation = dataList.get(position);
                    Log.d("favoriteActivity", "favoriteActivity--position--->" + position);
                    Log.d("favoriteActivity", "favoriteActivity--stationName--->" + favoriteStation.getStationName());
                    int stationId = favoriteStation.getStationId();
                    Intent intentStationDetail = new Intent().putExtra("stationId", stationId);
                    intentStationDetail.setClass(FavoriteActivity.this, StationDetailActivity.class);
                    startActivity(intentStationDetail);
                }
            });

            convertView.findViewById(R.id.tv_cancel_favorite).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {//bottomView点击事件 取消收藏站点

                    favoriteStation = dataList.get(position);
                    Log.d("favoriteActivity", "favoriteActivity--cancelStationName--->" + favoriteStation.getStationName());
                    mFavoritePresenter.cancelFavorite(favoriteStation.getId());
                    mSwipeLayout.close();

                }
            });
        }

        @Override
        public int getCount() {
            Log.d("dataListSize", "dataListSize--->" + dataList.size());
            return dataList.size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

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

至此,我们已经写好了listview_item布局,listview的adapter。最后看一下在activity中如何使用这个滑动控件。

Step 4 使用swipeLayout

在activity中使用swipelayout

Example:

根据需要在 onCreate() 或者 onResume() 中使用

favoriteListLv = (ListView) findViewById(R.id.lv_favorite_station);
favoriteStaionListAdapter = new FavoriteStationListViewAdapter(FavoriteActivity.this,
                favoriteStationList);
favoriteStaionListAdapter.setMode(Attributes.Mode.Single);
favoriteListLv.setAdapter(favoriteStaionListAdapter);

以上就是swipelayout的基本用法,当然还有很多可以设置的地方需要到作者的github上去学习, 项目地址 ,swipelayout这个view还可以用在gridview、recyclerView等等

如果你想跟我继续讨论swipeLayout,我的微博地址,欢迎给我私信(≧▽≦o)

需要 登录 后回复方可回复, 如果你还没有账号你可以 注册 一个帐号。