Android 之 SwipeLayout 的基本使用
dartye
8年前
<p>使用方法( 以listview作为例子):</p> <h2><strong>Step 1 添加项目依赖</strong></h2> <p>项目依赖如下:</p> <p>在你的app中的build.gradle文件中添加以下依赖</p> <pre> <code class="language-java">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' }</code></pre> <p>注意:</p> <p>compile 'com.daimajia.androidanimations:library:1.1.2@aar'<br> compile'com.nineoldandroids:library:2.4.0'</p> <p>这两个库的引用是滑动bottomView所需要依赖的。</p> <h2>S<strong>tep 2 添加swipeLayout的xml文件</strong></h2> <p>首先创建一个swipelayout作为列表项(listview_item)的布局</p> <p>swipelayout由两部分view组成:surfaceView 和 bottomView</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/d88d9c7583d1684f305a3b2ec21cdc1f.png"></p> <p>图中左边是surfaceView,右边被滑动出来的是bottomView</p> <p>Tips:</p> <ol> <li> <p>surfaceView应当写在此view中的最后,其余的都是bottomView</p> </li> <li> <p>在你的bottomView中最好使用layout_gravity这个属性</p> </li> </ol> <p>xml模版格式:</p> <pre> <code class="language-java"><?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></code></pre> <p>Example:</p> <pre> <code class="language-java"><?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></code></pre> <p>现在你已经创建好的列表项的布局了,要想在activity中让listview使用这个swipelayout你还需要一个listviewAdapter</p> <h2><strong>Step 3 创建swipeLayout的adapter</strong></h2> <p>首先swipelayout的adapter是继承于BaseAdapter,不同的是你不需要重写getView(),取而代之的是你需要重写以下三个方法来代替getView():</p> <pre> <code class="language-java">//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);</code></pre> <p>所以最终你在实现ListViewAdapter的时候需要重写6个方法:</p> <ol> <li>public int <strong>getSwipeLayoutResourceId</strong> (int position)</li> <li>public View <strong>generateView</strong> (final int position, ViewGroup parent)</li> <li>public void <strong>fillValues</strong> (int position, View convertView)</li> <li>public int <strong>getCount</strong> ()</li> <li>public Object <strong>getItem</strong> (int position)</li> <li>public long <strong>getItemId</strong> (int position)</li> </ol> <p>Tips:</p> <ol> <li> <p>如果你想绑定监听事件应当在 fillValues() 方法中去实现而不是在 generateView() 方法中!!</p> <p>如果你按照该项目作者在github上的demo把bind listener以及fill values的具体实现写在 generateView() 中,则会出现删除item控件错乱的问题。</p> </li> <li> <p>为了避免滑动事件在滑回来不与该swipelayout的点击事件冲突,swipelayout的点击事件请使用 swipeLayout.getSurfaceView().setOnClickListener 方法去实现。</p> <p>Example:</p> </li> </ol> <pre> <code class="language-java">/** * 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; } }</code></pre> <p>至此,我们已经写好了listview_item布局,listview的adapter。最后看一下在activity中如何使用这个滑动控件。</p> <h2><strong>Step 4 使用swipeLayout</strong></h2> <p>在activity中使用swipelayout</p> <p>Example:</p> <p>根据需要在 onCreate() 或者 onResume() 中使用</p> <pre> <code class="language-java">favoriteListLv = (ListView) findViewById(R.id.lv_favorite_station); favoriteStaionListAdapter = new FavoriteStationListViewAdapter(FavoriteActivity.this, favoriteStationList); favoriteStaionListAdapter.setMode(Attributes.Mode.Single); favoriteListLv.setAdapter(favoriteStaionListAdapter);</code></pre> <p>以上就是swipelayout的基本用法,当然还有很多可以设置的地方,swipelayout这个view还可以用在gridview、recyclerView等等</p> <p> </p> <p>来自:http://jngoogle.farbox.com/post/android/view/swipelayoutde-ji-ben-shi-yong</p> <p> </p>