最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android App中ListView仿QQ實(shí)現(xiàn)滑動(dòng)刪除效果的要點(diǎn)解析

 更新時(shí)間:2016年04月26日 16:15:52   作者:鴻洋_  
這篇文章主要介紹了Android App中ListView仿QQ實(shí)現(xiàn)滑動(dòng)刪除效果的要點(diǎn)解析,重點(diǎn)是要判斷手勢(shì)按下的位置坐標(biāo),需要的朋友可以參考下

本來(lái)準(zhǔn)備在ListView的每個(gè)Item的布局上設(shè)置一個(gè)隱藏的Button,當(dāng)滑動(dòng)的時(shí)候顯示。但是因?yàn)槊看沃灰嬖谝粋€(gè)Button,發(fā)現(xiàn)每個(gè)Item上的Button相互間不好控制。所以決定繼承ListView然后結(jié)合PopupWindow。
首先是布局文件:
delete_btn.xml:這里只需要一個(gè)Button

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:orientation="vertical" > 
   <Button  
    android:id="@+id/id_item_btn" 
    android:layout_width="60dp" 
    android:singleLine="true" 
    android:layout_height="wrap_content" 
    android:text="刪除" 
    android:background="@drawable/d_delete_btn" 
    android:textColor="#ffffff" 
    android:paddingLeft="15dp" 
    android:paddingRight="15dp" 
    android:layout_alignParentRight="true" 
    android:layout_centerVertical="true" 
    android:layout_marginRight="15dp" 
    /> 
</LinearLayout> 

主布局文件:activity_main.xml,ListView的每個(gè)Item的樣式直接使用了系統(tǒng)的android.R.layout.simple_list_item_1

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  xmlns:tools="http://schemas.android.com/tools" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" > 
 
  <com.example.listviewitemslidedeletebtnshow.QQListView 
    android:id="@+id/id_listview" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" > 
  </com.example.listviewitemslidedeletebtnshow.QQListView> 
 
</RelativeLayout> 

接下來(lái)看看QQListView的實(shí)現(xiàn):

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; 
  /** 
   * 用戶(hù)滑動(dòng)的最小距離 
   */ 
  private int touchSlop; 
 
  /** 
   * 是否響應(yīng)滑動(dòng) 
   */ 
  private boolean isSliding; 
 
  /** 
   * 手指按下時(shí)的x坐標(biāo) 
   */ 
  private int xDown; 
  /** 
   * 手指按下時(shí)的y坐標(biāo) 
   */ 
  private int yDown; 
  /** 
   * 手指移動(dòng)時(shí)的x坐標(biāo) 
   */ 
  private int xMove; 
  /** 
   * 手指移動(dòng)時(shí)的y坐標(biāo) 
   */ 
  private int yMove; 
 
  private LayoutInflater mInflater; 
 
  private PopupWindow mPopupWindow; 
  private int mPopupWindowHeight; 
  private int mPopupWindowWidth; 
 
  private Button mDelBtn; 
  /** 
   * 為刪除按鈕提供一個(gè)回調(diào)接口 
   */ 
  private DelButtonClickListener mListener; 
 
  /** 
   * 當(dāng)前手指觸摸的View 
   */ 
  private View mCurrentView; 
 
  /** 
   * 當(dāng)前手指觸摸的位置 
   */ 
  private int mCurrentViewPos; 
 
  /** 
   * 必要的一些初始化 
   * 
   * @param context 
   * @param attrs 
   */ 
  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); 
    /** 
     * 先調(diào)用下measure,否則拿不到寬和高 
     */ 
    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; 
      /** 
       * 如果當(dāng)前popupWindow顯示,則直接隱藏,然后屏蔽ListView的touch事件的下傳 
       */ 
      if (mPopupWindow.isShowing()) 
      { 
        dismissPopWindow(); 
        return false; 
      } 
      // 獲得當(dāng)前手指按下時(shí)的item的位置 
      mCurrentViewPos = pointToPosition(xDown, yDown); 
      // 獲得當(dāng)前手指按下時(shí)的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; 
      /** 
       * 判斷是否是從右到左的滑動(dòng) 
       */ 
      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(); 
    /** 
     * 如果是從右到左的滑動(dòng)才相應(yīng) 
     */ 
    if (isSliding) 
    { 
      switch (action) 
      { 
      case MotionEvent.ACTION_MOVE: 
 
        int[] location = new int[2]; 
        // 獲得當(dāng)前item的位置x與y 
        mCurrentView.getLocationOnScreen(location); 
        // 設(shè)置popupWindow的動(dòng)畫(huà) 
        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); 
        // 設(shè)置刪除按鈕的回調(diào) 
        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; 
 
      } 
      // 相應(yīng)滑動(dòng)期間屏幕itemClick事件,避免發(fā)生沖突 
      return true; 
    } 
 
    return super.onTouchEvent(ev); 
  } 
 
  /** 
   * 隱藏popupWindow 
   */ 
  private void dismissPopWindow() 
  { 
    if (mPopupWindow != null && mPopupWindow.isShowing()) 
    { 
      mPopupWindow.dismiss(); 
    } 
  } 
 
  public void setDelButtonClickListener(DelButtonClickListener listener) 
  { 
    mListener = listener; 
  } 
 
  interface DelButtonClickListener 
  { 
    public void clickHappend(int position); 
  } 
 
} 

代碼注釋寫(xiě)得很詳細(xì),簡(jiǎn)單說(shuō)一下,在dispatchTouchEvent中設(shè)置當(dāng)前是否響應(yīng)用戶(hù)滑動(dòng),然后在onTouchEvent中判斷是否響應(yīng),如果響應(yīng)則popupWindow以動(dòng)畫(huà)的形式展示出來(lái)。當(dāng)然屏幕上如果存在PopupWindow則屏幕ListView的滾動(dòng)與Item的點(diǎn)擊,以及從右到左滑動(dòng)時(shí)屏幕Item的click事件。
接下來(lái)是MainActivity.java,這里代碼很簡(jiǎn)單不做介紹了。

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<String> mAdapter; 
  private List<String> 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<String>(Arrays.asList("HelloWorld", "Welcome", "Java", "Android", "Servlet", "Struts", 
        "Hibernate", "Spring", "HTML5", "Javascript", "Lucene")); 
    mAdapter = new ArrayAdapter<String>(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的動(dòng)畫(huà)很短感覺(jué)截圖效果很卡不流暢,大家有什么好的截圖,還望推薦。有興趣的還是下載源碼看看效果i。

2016426161603799.gif (360×617)

相關(guān)文章

  • Flutter實(shí)現(xiàn)底部導(dǎo)航欄創(chuàng)建詳解

    Flutter實(shí)現(xiàn)底部導(dǎo)航欄創(chuàng)建詳解

    ConvexBottomBar是一個(gè)底部導(dǎo)航欄組件,用于展現(xiàn)凸起的TAB效果,支持多種內(nèi)置樣式與動(dòng)畫(huà)交互。本文將利用ConvexBottomBar創(chuàng)建漂亮的底部導(dǎo)航欄,感興趣的可以學(xué)習(xí)一下
    2022-01-01
  • Android中的Bitmap序列化失敗的解決方法

    Android中的Bitmap序列化失敗的解決方法

    這篇文章主要介紹了Android中的Bitmap序列化失敗的解決方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-11-11
  • Android消息循環(huán)機(jī)制源碼深入理解

    Android消息循環(huán)機(jī)制源碼深入理解

    這篇文章主要介紹了Android消息循環(huán)機(jī)制源碼深入理解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • Android登錄時(shí)密碼保護(hù)功能

    Android登錄時(shí)密碼保護(hù)功能

    這篇文章主要為大家詳細(xì)介紹了Android登錄時(shí)密碼保護(hù)功能的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Flutter實(shí)現(xiàn)webview與原生組件組合滑動(dòng)的示例代碼

    Flutter實(shí)現(xiàn)webview與原生組件組合滑動(dòng)的示例代碼

    這篇文章主要介紹了Flutter實(shí)現(xiàn)webview與原生組件組合滑動(dòng)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Android中的xml解析介紹

    Android中的xml解析介紹

    大家好,本篇文章主要講的是Android中的xml解析介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下
    2022-01-01
  • Android Handler的postDelayed()關(guān)閉的方法及遇到問(wèn)題

    Android Handler的postDelayed()關(guān)閉的方法及遇到問(wèn)題

    這篇文章主要介紹了Android Handler的postDelayed()關(guān)閉的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Android編程實(shí)現(xiàn)監(jiān)控apk安裝,卸載,替換的方法

    Android編程實(shí)現(xiàn)監(jiān)控apk安裝,卸載,替換的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)監(jiān)控apk安裝,卸載,替換的方法,涉及Android基于Intent監(jiān)控apk狀態(tài)的功能實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2016-01-01
  • Android實(shí)現(xiàn)刮刮樂(lè)示例分析

    Android實(shí)現(xiàn)刮刮樂(lè)示例分析

    本文實(shí)現(xiàn)了Android刮刮樂(lè)示例分析,刮獎(jiǎng)在生活中常常見(jiàn)到,網(wǎng)上現(xiàn)在也有各種各樣的抽獎(jiǎng)活動(dòng),下面我們就要實(shí)現(xiàn)一個(gè)刮刮樂(lè)程序。
    2016-10-10
  • Android日期選擇器實(shí)現(xiàn)年月日三級(jí)聯(lián)動(dòng)

    Android日期選擇器實(shí)現(xiàn)年月日三級(jí)聯(lián)動(dòng)

    這篇文章主要為大家詳細(xì)介紹了Android日期選擇器實(shí)現(xiàn)年月日三級(jí)聯(lián)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評(píng)論

彩票| 五大连池市| 溧阳市| 郎溪县| 临西县| 河池市| 霍林郭勒市| 富宁县| 红安县| 巴林右旗| 宜阳县| 五原县| 巴林右旗| 富宁县| 北流市| 神池县| 黄梅县| 樟树市| 延寿县| 西丰县| 景洪市| 抚顺市| 临漳县| 鹿邑县| 锦州市| 东山县| 石门县| 延吉市| 莆田市| 西平县| 青田县| 隆尧县| 安陆市| 琼结县| 成武县| 沈丘县| 太保市| 宁安市| 阳朔县| 大同县| 鲜城|