栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android App中ListView仿QQ实现滑动删除效果的要点解析

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android App中ListView仿QQ实现滑动删除效果的要点解析

本来准备在ListView的每个Item的布局上设置一个隐藏的Button,当滑动的时候显示。但是因为每次只要存在一个Button,发现每个Item上的Button相互间不好控制。所以决定继承ListView然后结合PopupWindow。
首先是布局文件:
delete_btn.xml:这里只需要一个Button

 
 
   

主布局文件:activity_main.xml,ListView的每个Item的样式直接使用了系统的android.R.layout.simple_list_item_1

 
 
   
   
 
 

接下来看看QQListView的实现:

package com.example.listviewitemslidedeletebtnshow; 
 
import android.content.Context; 
import android.util.AttributeSet; 
import android.view.Gravity; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewConfiguration; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.ListView; 
import android.widget.PopupWindow; 
 
public class QQListView extends ListView 
{ 
 
  private static final String TAG = "QQlistView"; 
 
  // private static final int VELOCITY_SANP = 200; 
  // private VelocityTracker mVelocityTracker; 
   
  private int touchSlop; 
 
   
  private boolean isSliding; 
 
   
  private int xDown; 
   
  private int yDown; 
   
  private int xMove; 
   
  private int yMove; 
 
  private LayoutInflater mInflater; 
 
  private PopupWindow mPopupWindow; 
  private int mPopupWindowHeight; 
  private int mPopupWindowWidth; 
 
  private Button mDelBtn; 
   
  private DelButtonClickListener mListener; 
 
   
  private View mCurrentView; 
 
   
  private int mCurrentViewPos; 
 
   
  public QQListView(Context context, AttributeSet attrs) 
  { 
    super(context, attrs); 
 
    mInflater = LayoutInflater.from(context); 
    touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 
 
    View view = mInflater.inflate(R.layout.delete_btn, null); 
    mDelBtn = (Button) view.findViewById(R.id.id_item_btn); 
    mPopupWindow = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT, 
 LinearLayout.LayoutParams.WRAP_CONTENT); 
     
    mPopupWindow.getContentView().measure(0, 0); 
    mPopupWindowHeight = mPopupWindow.getContentView().getMeasuredHeight(); 
    mPopupWindowWidth = mPopupWindow.getContentView().getMeasuredWidth(); 
  } 
 
  @Override 
  public boolean dispatchTouchEvent(MotionEvent ev) 
  { 
    int action = ev.getAction(); 
    int x = (int) ev.getX(); 
    int y = (int) ev.getY(); 
    switch (action) 
    { 
 
    case MotionEvent.ACTION_DOWN: 
      xDown = x; 
      yDown = y; 
       
      if (mPopupWindow.isShowing()) 
      { 
 dismissPopWindow(); 
 return false; 
      } 
      // 获得当前手指按下时的item的位置 
      mCurrentViewPos = pointToPosition(xDown, yDown); 
      // 获得当前手指按下时的item 
      View view = getChildAt(mCurrentViewPos - getFirstVisiblePosition()); 
      mCurrentView = view; 
      break; 
    case MotionEvent.ACTION_MOVE: 
      xMove = x; 
      yMove = y; 
      int dx = xMove - xDown; 
      int dy = yMove - yDown; 
       
      if (xMove < xDown && Math.abs(dx) > touchSlop && Math.abs(dy) < touchSlop) 
      { 
 // Log.e(TAG, "touchslop = " + touchSlop + " , dx = " + dx + 
 // " , dy = " + dy); 
 isSliding = true; 
      } 
      break; 
    } 
    return super.dispatchTouchEvent(ev); 
  } 
 
  @Override 
  public boolean onTouchEvent(MotionEvent ev) 
  { 
    int action = ev.getAction(); 
     
    if (isSliding) 
    { 
      switch (action) 
      { 
      case MotionEvent.ACTION_MOVE: 
 
 int[] location = new int[2]; 
 // 获得当前item的位置x与y 
 mCurrentView.getLocationOnScreen(location); 
 // 设置popupWindow的动画 
 mPopupWindow.setAnimationStyle(R.style.popwindow_delete_btn_anim_style); 
 mPopupWindow.update(); 
 mPopupWindow.showAtLocation(mCurrentView, Gravity.LEFT | Gravity.TOP, 
     location[0] + mCurrentView.getWidth(), location[1] + mCurrentView.getHeight() / 2 
  - mPopupWindowHeight / 2); 
 // 设置删除按钮的回调 
 mDelBtn.setonClickListener(new onClickListener() 
 { 
   @Override 
   public void onClick(View v) 
   { 
     if (mListener != null) 
     { 
mListener.clickHappend(mCurrentViewPos); 
mPopupWindow.dismiss(); 
     } 
   } 
 }); 
 // Log.e(TAG, "mPopupWindow.getHeight()=" + mPopupWindowHeight); 
 
 break; 
      case MotionEvent.ACTION_UP: 
 isSliding = false; 
 
      } 
      // 相应滑动期间屏幕itemClick事件,避免发生冲突 
      return true; 
    } 
 
    return super.onTouchEvent(ev); 
  } 
 
   
  private void dismissPopWindow() 
  { 
    if (mPopupWindow != null && mPopupWindow.isShowing()) 
    { 
      mPopupWindow.dismiss(); 
    } 
  } 
 
  public void setDelButtonClickListener(DelButtonClickListener listener) 
  { 
    mListener = listener; 
  } 
 
  interface DelButtonClickListener 
  { 
    public void clickHappend(int position); 
  } 
 
} 

代码注释写得很详细,简单说一下,在dispatchTouchEvent中设置当前是否响应用户滑动,然后在onTouchEvent中判断是否响应,如果响应则popupWindow以动画的形式展示出来。当然屏幕上如果存在PopupWindow则屏幕ListView的滚动与Item的点击,以及从右到左滑动时屏幕Item的click事件。
接下来是MainActivity.java,这里代码很简单不做介绍了。

package com.example.listviewitemslidedeletebtnshow; 
 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.Toast; 
 
import com.example.listviewitemslidedeletebtnshow.QQListView.DelButtonClickListener; 
 
public class MainActivity extends Activity 
{ 
  private QQListView mListView; 
  private ArrayAdapter mAdapter; 
  private List mDatas; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) 
  { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
 
    mListView = (QQListView) findViewById(R.id.id_listview); 
    // 不要直接Arrays.asList 
    mDatas = new ArrayList(Arrays.asList("HelloWorld", "Welcome", "Java", "Android", "Servlet", "Struts", 
 "Hibernate", "Spring", "HTML5", "Javascript", "Lucene")); 
    mAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, mDatas); 
    mListView.setAdapter(mAdapter); 
 
    mListView.setDelButtonClickListener(new DelButtonClickListener() 
    { 
      @Override 
      public void clickHappend(final int position) 
      { 
 Toast.makeText(MainActivity.this, position + " : " + mAdapter.getItem(position), 1).show(); 
 mAdapter.remove(mAdapter.getItem(position)); 
      } 
    }); 
 
    mListView.setonItemClickListener(new onItemClickListener() 
    { 
      @Override 
      public void onItemClick(AdapterView parent, View view, int position, long id) 
      { 
 Toast.makeText(MainActivity.this, position + " : " + mAdapter.getItem(position), 1).show(); 
      } 
    }); 
  } 
} 

效果图如下:楼主使用asm.jar以及gifcamera截的gif,由于button的动画很短感觉截图效果很卡不流畅,大家有什么好的截图,还望推荐。有兴趣的还是下载源码看看效果i。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/162676.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号