高仿 美團 向左滑動刪除條目
來源:程序員人生 發布時間:2015-05-27 07:56:49 閱讀次數:3111次
1、效果圖

2、功能實現
2.1 布局結構
<?xml version="1.0" encoding="UTF⑻"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="80dip"
android:background="#FF5555" >
<TextView
android:id="@+id/tv_show_info"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="10dip"
android:gravity="right|center_vertical"
android:padding="15dip"
android:text="向左滑動刪除"
android:textColor="#FFFFFF" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="#00FFFFFF" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="#FFFFFF" >
<TextView
android:id="@+id/list_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:padding="15dip"
android:text="ad"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
在這里使用了FrameLayout布局,它的第1個孩子TextView是顯示的文字,當向左滑動時,它的字體大小漸漸變大,透明度也漸漸變清晰,向右滑動時則相反,文字終究被隱藏。第2個孩子里面有用了1個LinearLayout并且它為透明,由于當view移動時移動的是其子View,如果不加LinearLayout那末全部布局向左滑動,看不到下面的字。
2.2 需要用到的類
首先需要繼承ListView對其進行擴大,思路就是根據用戶按下時的坐標獲得當前item的位置position,在根據位置獲得其對應的view項,繼而操作view使其移動。
其次,有轉動自然想到使用Scroller類,可使布局能夠向左滑動,在這里為了方便加入了GestureDetector手勢辨認類。
最后,重寫computeScroll方法使其完成轉動動畫。
android.widget.Scroller.startScroll(int startX, int
startY, int dx, int dy, int duration) 前面兩個參數轉動時的開始坐標,dx為正數時向左滑動,為負數時向右滑動。
2.3 實現
package com.example.customui.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Scroller;
import com.example.customui.util.Logger;
public class SwipeListView extends ListView {
/**
* 手勢辨認
*/
private GestureDetector mGestureDetector;
/**
* 滑動類
*/
private Scroller mScroller;
/**
* 需要移動的view
*/
private View currentMoveView;
private int downX;
private int downY;
/**
* 將手指按下時的坐標轉換成listview的item的位置
*/
private int slidePosition;
/**
* 是不是在滑動
*/
private boolean isSlide;
//快速滑動
// private boolean isFling;
private int mTouchSlop;
/**
* 屏幕寬度
*/
private int screenWidth;
/**
* listview item
*/
private ViewGroup viewGroup;
private static final int SNAP_VELOCITY = 600;
public SwipeListView(Context context) {
super(context);
init(context);
}
public SwipeListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
mScroller = new Scroller(context);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
screenWidth = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
mGestureDetector = new GestureDetector(context,new OnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
if (isSlide && currentMoveView!=null) {
if (listener!=null) {
listener.scroll(currentMoveView.getScrollX(), viewGroup);
}
currentMoveView.scrollBy((int)distanceX, 0);
}
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// if (isSlide && (e2.getX()-e1.getX())<0) {
// isFling = true;
// Logger.getLogger().i("==============> 快速滑動"+(e2.getX()-e1.getX()));
// }
return false;
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
});
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
Logger.getLogger().i("--------dispatchTouchEvent down--------> ");
if (!mScroller.isFinished() || isSlide) {
return super.dispatchTouchEvent(event);
}
downX = (int) event.getX();
downY = (int) event.getY();
Logger.getLogger().i("-------------downX= "+downX);
slidePosition = pointToPosition(downX, downY);
// 無效的position, 不做任何處理;isSlide避免多個手指按下時影響isFling的值,致使被刪除
if (slidePosition == AdapterView.INVALID_POSITION) {
return super.dispatchTouchEvent(event);
}
// 獲得我們點擊的item view
viewGroup = (ViewGroup) getChildAt(slidePosition - getFirstVisiblePosition());
//需要1定的view
currentMoveView = viewGroup.getChildAt(1);
break;
}
case MotionEvent.ACTION_MOVE:{
int x = (int) (event.getX()-downX);
int y = (int) (event.getY() -downY);
// Logger.getLogger().i("-------------x= "+x+" y= "+y+" mTouchSlop:"+mTouchSlop);
if (Math.abs(x)>mTouchSlop && Math.abs(x)>Math.abs(y) && x<0 ) {
isSlide = true;
}
break;
}
}
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
mGestureDetector.onTouchEvent(ev);
if (isSlide) {
if (!mScroller.isFinished()) {
return true;
}
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:{
downX = (int) ev.getX();
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:{
/*if (isFling || isRemoveItem()) {
if (isFling && this.listener!=null ) {
Logger.getLogger().i("滑動刪除。。");
this.listener.removeItem(slidePosition);
}else*/
if (isRemoveItem() && this.listener!=null) {
this.listener.removeItem(slidePosition);
mScroller.startScroll(currentMoveView.getScrollX(), 0,screenWidth, 0,Math.abs(300));
}else {
int delta = currentMoveView.getScrollX();
mScroller.startScroll(currentMoveView.getScrollX(), 0,-delta, 0,Math.abs(500));
}
postInvalidate();
}
}
return true;
}
return super.onTouchEvent(ev);
}
@Override
public void computeScroll() {
// 調用startScroll的時候scroller.computeScrollOffset()返回true,
if (mScroller.computeScrollOffset()) {
// 讓ListView item根據當前的轉動偏移量進行轉動
currentMoveView.scrollTo(mScroller.getCurrX(), 0);
postInvalidate();
// 轉動動畫結束的時候調用回調接口
if (mScroller.isFinished()) {
currentMoveView.scrollTo(0, 0);
if (this.listener!=null && isSlide) {
this.listener.scrollFinish();
}
isSlide = false;
}
}
}
private boolean isRemoveItem(){
if (currentMoveView.getScrollX()>screenWidth/2) {
return true;
}
return false;
}
private RemoveItemListViewListener listener;
public void setRemoveItemListViewListener(RemoveItemListViewListener listener){
this.listener = listener;
}
public interface RemoveItemListViewListener{
public void removeItem(int pos);
public void scroll(float scrollX,View view);
public void scrollFinish();
}
}
2.4 activity代碼
通過轉動的距離來設置textview的字體大小和透明度。
package com.example.customui.activity;
import java.util.ArrayList;
import java.util.List;
import android.R.integer;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.example.customui.BaseActivity;
import com.example.customui.R;
import com.example.customui.adapter.CommonAdapter;
import com.example.customui.adapter.ViewHolder;
import com.example.customui.util.DensityUtil;
import com.example.customui.util.Logger;
import com.example.customui.view.SwipeListView;
import com.example.customui.view.SwipeListView.RemoveItemListViewListener;
public class SwipeListViewActivity extends BaseActivity {
private SwipeListView mListView;
private List<String> dataSourceList;
private ArrayAdapter mAdapter;
private int screenWidth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.swipe_listview_main);
mListView = (SwipeListView) findViewById(R.id.lv_data);
screenWidth = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth();
dataSourceList = new ArrayList<String>();
for (int i = 0; i < 20; i++) {
dataSourceList.add("item "+i);
}
mAdapter = new ArrayAdapter(getApplicationContext(), R.layout.list_view_item,R.id.list_item,dataSourceList);
mListView.setAdapter(mAdapter);
mListView.setRemoveItemListViewListener(new RemoveItemListViewListener() {
private TextView textView;
@Override
public void removeItem(int pos) {
position = pos;
}
@Override
public void scroll(float scrollX, View view) {
if (textView==null) {
textView = (TextView) view.findViewById(R.id.tv_show_info);
}
int fontSize=1;
float alpha=0.0f;
if (scrollX>screenWidth/3) {
alpha=1.0f;
fontSize=maxFontSize;
}else {
alpha = scrollX/(screenWidth/3);
fontSize = (int) (alpha * maxFontSize);
}
textView.setAlpha(alpha);
textView.setTextSize(fontSize);
}
@Override
public void scrollFinish() {
textView=null;
if (position>=0) {
Logger.getLogger().i("----------------------->刪除的位置: "+position);
dataSourceList.remove(position);
mAdapter.notifyDataSetChanged();
position= ⑴;
}
}
});
}
private int position=⑴;
private int maxFontSize=22;
}
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈