国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android自定義控件仿QQ抽屜效果

2019-10-23 18:33:44
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

其實(shí)網(wǎng)上類(lèi)似的實(shí)現(xiàn)已經(jīng)很多了,原理也并不難,只是網(wǎng)上各種demo運(yùn)行下來(lái),多少都有一些問(wèn)題。折騰了半天,決定自己實(shí)現(xiàn)一個(gè)。

首先我們看看實(shí)現(xiàn)效果:

Android,QQ,抽屜

對(duì)比網(wǎng)上各類(lèi)demo,這次要實(shí)現(xiàn)的主要表現(xiàn)在以下幾點(diǎn):

1.側(cè)滑顯示抽屜view
2.側(cè)滑抽屜隱藏view控件點(diǎn)擊事件
3.單擊任意item隱藏顯示的抽屜view
4.滑動(dòng)list隱藏顯示的抽屜view
5.增加SwipeLayout點(diǎn)擊事件和Swipe touch事件判斷處理
6.優(yōu)化快速劃開(kāi)多個(gè)抽屜隱藏view時(shí)多個(gè)SwipeLayout滑動(dòng)狀態(tài)判斷處理,僅顯示最后一個(gè)滑動(dòng)的抽屜隱藏view,隱藏前面所有打開(kāi)的抽屜view(快速滑動(dòng)時(shí),可能存在多個(gè)抽屜view打開(kāi)情況,網(wǎng)上找的幾個(gè)demo主要問(wèn)題都集中在這一塊)

實(shí)現(xiàn)原理

其實(shí)單就一個(gè)SwipeLayout的實(shí)現(xiàn)原理來(lái)講的話(huà),還是很簡(jiǎn)單的,實(shí)際上單個(gè)SwipeLayout隱藏抽屜狀態(tài)時(shí),應(yīng)該是這樣的:

Android,QQ,抽屜

也就是說(shuō),最初的隱藏狀態(tài),實(shí)際上是將hide view區(qū)域layout到conten view的右邊,達(dá)到隱藏效果,而后顯示則是根據(jù)拖拽的x值變化來(lái)動(dòng)態(tài)的layout 2個(gè)view,從而達(dá)到一個(gè)滑動(dòng)抽屜效果。
當(dāng)然,直接重寫(xiě)view的onTouchEvent來(lái)動(dòng)態(tài)的layout 2個(gè)view是可以實(shí)現(xiàn)我們需要的效果的,但是有更好的方法來(lái)實(shí)現(xiàn),就是同過(guò)ViewDragHelper。
ViewDragHelper是google官方提供的一個(gè)專(zhuān)門(mén)用于手勢(shì)分析處理的類(lèi),關(guān)于ViewDragHelper的基本使用,網(wǎng)上有一大堆的資源。具體的ViewDragHelper介紹以及基本使用方法,本文就不重復(fù)造輪子了,此處推薦鴻洋大神的一篇微博:Android ViewDragHelper完全解析 自定義ViewGroup神器。

具體實(shí)現(xiàn)

下面我們開(kāi)始具體的實(shí)現(xiàn)。
布局比較簡(jiǎn)單,這里就不貼代碼了,最后會(huì)貼上本demo的完整代碼地址。

首先我們實(shí)現(xiàn)一個(gè)繼承FrameLayout的自定義SwipeLauout,重寫(xiě)onFinishInflate方法:
這里我們只允許SwipeLayout設(shè)置2個(gè)子View,ContentLayout是繼承LinearLayout的自定義layout,后面會(huì)講到這個(gè),此處先略過(guò);

 @Override protected void onFinishInflate() {  super.onFinishInflate();  if (getChildCount() != 2) {   throw new IllegalStateException("Must 2 views in SwipeLayout");  }  contentView = getChildAt(0);  hideView = getChildAt(1);  if (contentView instanceof ContentLayout)   ((ContentLayout) contentView).setSwipeLayout(this);  else {   throw new IllegalStateException("content view must be an instanceof FrontLayout");  } }

接著重寫(xiě)onSizeChanged,onLayout,onInterceptTouchEvent方法:

 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {  super.onSizeChanged(w, h, oldw, oldh);  hideViewHeight = hideView.getMeasuredHeight();  hideViewWidth = hideView.getMeasuredWidth();  contentWidth = contentView.getMeasuredWidth(); } @Override protected void onLayout(boolean changed, int left, int top, int right,       int bottom) {  // super.onLayout(changed, left, top, right, bottom);  contentView.layout(0, 0, contentWidth, hideViewHeight);  hideView.layout(contentView.getRight(), 0, contentView.getRight()    + hideViewWidth, hideViewHeight); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) {  boolean result = viewDragHelper.shouldInterceptTouchEvent(ev);  //  Log.e("SwipeLayout", "-----onInterceptTouchEvent-----");  return result; }

然后是比較關(guān)鍵的,重寫(xiě)onTouchEvent方法以及ViewDragHelper.Callback回調(diào),我們定了一個(gè)enum來(lái)判斷SwipeLayout的三種狀態(tài)。在onViewPositionChanged中,有2種方法實(shí)現(xiàn)content view和hide view的伴隨移動(dòng),一種是直接offset view的橫向變化量,還有一種就是直接通過(guò)layout的方式,兩種方式都可以。

 public enum SwipeState {  Open, Swiping, Close; } @Override public boolean onTouchEvent(MotionEvent event) {  //  Log.e("SwipeLayout", "-----onTouchEvent-----");  switch (event.getAction()) {   case MotionEvent.ACTION_DOWN:    downX = event.getX();    downY = event.getY();    break;   case MotionEvent.ACTION_MOVE:    // 1.獲取x和y方向移動(dòng)的距離    float moveX = event.getX();    float moveY = event.getY();    float delatX = moveX - downX;// x方向移動(dòng)的距離    float delatY = moveY - downY;// y方向移動(dòng)的距離    if (Math.abs(delatX) > Math.abs(delatY)) {     // 表示移動(dòng)是偏向于水平方向,那么應(yīng)該SwipeLayout應(yīng)該處理,請(qǐng)求listview不要攔截     this.requestDisallowInterceptTouchEvent(true);    }    // 更新downX,downY    downX = moveX;    downY = moveY;    break;   case MotionEvent.ACTION_UP:    break;  }  viewDragHelper.processTouchEvent(event);  return true; } private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {  @Override  public boolean tryCaptureView(View child, int pointerId) {   return child == contentView || child == hideView;  }  @Override  public int getViewHorizontalDragRange(View child) {   return hideViewWidth;  }  @Override  public int clampViewPositionHorizontal(View child, int left, int dx) {   if (child == contentView) {    if (left > 0)     left = 0;    if (left < -hideViewWidth)     left = -hideViewWidth;   } else if (child == hideView) {    if (left > contentWidth)     left = contentWidth;    if (left < (contentWidth - hideViewWidth))     left = contentWidth - hideViewWidth;   }   return left;  }  @Override  public void onViewPositionChanged(View changedView, int left, int top,           int dx, int dy) {   super.onViewPositionChanged(changedView, left, top, dx, dy);   if (changedView == contentView) {    // 如果手指滑動(dòng)deleteView,那么也要講橫向變化量dx設(shè)置給contentView    hideView.offsetLeftAndRight(dx);   } else if (changedView == hideView) {    // 如果手指滑動(dòng)contentView,那么也要講橫向變化量dx設(shè)置給deleteView    contentView.offsetLeftAndRight(dx);   }   //   if (changedView == contentView) {   //    // 手動(dòng)移動(dòng)deleteView   //    hideView.layout(hideView.getLeft() + dx,   //      hideView.getTop() + dy, hideView.getRight() + dx,   //      hideView.getBottom() + dy);   //   } else if (hideView == changedView) {   //    // 手動(dòng)移動(dòng)contentView   //    contentView.layout(contentView.getLeft() + dx,   //      contentView.getTop() + dy, contentView.getRight() + dx,   //      contentView.getBottom() + dy);   //   }   //實(shí)時(shí)更新當(dāng)前狀態(tài)   updateSwipeStates();   invalidate();  }  @Override  public void onViewReleased(View releasedChild, float xvel, float yvel) {   super.onViewReleased(releasedChild, xvel, yvel);   //根據(jù)用戶(hù)滑動(dòng)速度處理開(kāi)關(guān)   //xvel: x方向滑動(dòng)速度   //yvel: y方向滑動(dòng)速度   //   Log.e("tag", "currentState = " + currentState);   //   Log.e("tag", "xvel = " + xvel);   if (xvel < -200 && currentState != SwipeState.Open) {    open();    return;   } else if (xvel > 200 && currentState != SwipeState.Close) {    close();    return;   }   if (contentView.getLeft() < -hideViewWidth / 2) {    // 打開(kāi)    open();   } else {    // 關(guān)閉    close();   }  } };

open(),close()實(shí)現(xiàn)

 

 public void open() {  open(true); } public void close() {  close(true); } /**  * 打開(kāi)的方法  *  * @param isSmooth 是否通過(guò)緩沖動(dòng)畫(huà)的形式設(shè)定view的位置  */ public void open(boolean isSmooth) {  if (isSmooth) {   viewDragHelper.smoothSlideViewTo(contentView, -hideViewWidth,     contentView.getTop());   ViewCompat.postInvalidateOnAnimation(SwipeLayout.this);  } else {   contentView.offsetLeftAndRight(-hideViewWidth);//直接偏移View的位置   hideView.offsetLeftAndRight(-hideViewWidth);//直接偏移View的位置   //   contentView.layout(-hideViewWidth, 0, contentWidth - hideViewWidth, hideViewHeight);//直接通過(guò)坐標(biāo)擺放   //   hideView.layout(contentView.getRight(), 0, hideViewWidth, hideViewHeight);//直接通過(guò)坐標(biāo)擺放   invalidate();  } } /**  * 關(guān)閉的方法  *  * @param isSmooth true:通過(guò)緩沖動(dòng)畫(huà)的形式設(shè)定view的位置  *     false:直接設(shè)定view的位置  */ public void close(boolean isSmooth) {  if (isSmooth) {   viewDragHelper.smoothSlideViewTo(contentView, 0, contentView.getTop());   ViewCompat.postInvalidateOnAnimation(SwipeLayout.this);  } else {   contentView.offsetLeftAndRight(hideViewWidth);   hideView.offsetLeftAndRight(hideViewWidth);   invalidate();   //contentView.layout(0, 0, contentWidth, hideViewHeight);//直接通過(guò)坐標(biāo)擺放   //hideView.layout(contentView.getRight(), 0, hideViewWidth, hideViewHeight);//直接通過(guò)坐標(biāo)擺放  } }

此上基本實(shí)現(xiàn)了單個(gè)SwipeLayout的抽屜滑動(dòng)效果,但是將此SwipeLayout作為一個(gè)item布局設(shè)置給一個(gè)listView的時(shí)候,還需要做許多的判斷。

由于listView的重用機(jī)制,我們這里并未針對(duì)listview做任何處理,所以一旦有一個(gè)item的SwipeLayout的狀態(tài)是打開(kāi)狀態(tài),不可避免的其它也必然有幾個(gè)是打開(kāi)狀態(tài),所以我們這里需要根據(jù)檢測(cè)listView的滑動(dòng),當(dāng)listView滑動(dòng)時(shí),關(guān)閉SwipeLayout。既然需要在外部控制SwipeLayout的開(kāi)關(guān),我們先定義一個(gè)SwipeLayoutManager用于管理SwipeLayout的控制。

public class SwipeLayoutManager { //記錄打開(kāi)的SwipeLayout集合 private HashSet<SwipeLayout> mUnClosedSwipeLayouts = new HashSet<SwipeLayout>(); private SwipeLayoutManager() { } private static SwipeLayoutManager mInstance = new SwipeLayoutManager(); public static SwipeLayoutManager getInstance() {  return mInstance; } /**  * 將一個(gè)沒(méi)有關(guān)閉的SwipeLayout加入集合  * @param layout  */ public void add(SwipeLayout layout) {  mUnClosedSwipeLayouts.add(layout); } /**  * 將一個(gè)沒(méi)有關(guān)閉的SwipeLayout移出集合  * @param layout  */ public void remove(SwipeLayout layout){  mUnClosedSwipeLayouts.remove(layout); } /**  * 關(guān)閉已經(jīng)打開(kāi)的SwipeLayout  */ public void closeUnCloseSwipeLayout() {  if(mUnClosedSwipeLayouts.size() == 0){   return;  }  for(SwipeLayout l : mUnClosedSwipeLayouts){   l.close(true);  }  mUnClosedSwipeLayouts.clear(); } /**  * 關(guān)閉已經(jīng)打開(kāi)的SwipeLayout  */ public void closeUnCloseSwipeLayout(boolean isSmooth) {  if(mUnClosedSwipeLayouts.size() == 0){   return;  }  for(SwipeLayout l : mUnClosedSwipeLayouts){   l.close(isSmooth);  }  mUnClosedSwipeLayouts.clear(); }}

這樣就可以監(jiān)聽(tīng)listView的滑動(dòng),然后在listView滑動(dòng)的時(shí)候,關(guān)閉所有的抽屜View。

 listView.setOnScrollListener(new OnScrollListener() {   @Override   public void onScrollStateChanged(AbsListView view, int scrollState) {    swipeLayoutManager.closeUnCloseSwipeLayout();   }   @Override   public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {   }  });

考慮到大多數(shù)時(shí)候,在我們打開(kāi)抽屜View和關(guān)閉抽屜View的時(shí)候,外部需要知道SwipeLayout的狀態(tài)值,所以我們需要在SwipeLayout中增加幾個(gè)接口,告訴外部當(dāng)前SwipeLayout的狀態(tài)值:

SwipeLayout.java

---------------- private void updateSwipeStates() {  SwipeState lastSwipeState = currentState;  SwipeState swipeState = getCurrentState();  if (listener == null) {   try {    throw new Exception("please setOnSwipeStateChangeListener first!");   } catch (Exception e) {    e.printStackTrace();   }   return;  }  if (swipeState != currentState) {   currentState = swipeState;   if (currentState == SwipeState.Open) {    listener.onOpen(this);    // 當(dāng)前的Swipelayout已經(jīng)打開(kāi),需要讓Manager記錄    swipeLayoutManager.add(this);   } else if (currentState == SwipeState.Close) {    listener.onClose(this);    // 說(shuō)明當(dāng)前的SwipeLayout已經(jīng)關(guān)閉,需要讓Manager移除    swipeLayoutManager.remove(this);   } else if (currentState == SwipeState.Swiping) {    if (lastSwipeState == SwipeState.Open) {     listener.onStartClose(this);    } else if (lastSwipeState == SwipeState.Close) {     listener.onStartOpen(this);     //hideView準(zhǔn)備顯示之前,先將之前打開(kāi)的的SwipeLayout全部關(guān)閉     swipeLayoutManager.closeUnCloseSwipeLayout();     swipeLayoutManager.add(this);    }   }  } else {   currentState = swipeState;  } } /**  * 獲取當(dāng)前控件狀態(tài)  *  * @return  */ public SwipeState getCurrentState() {  int left = contentView.getLeft();  //  Log.e("tag", "contentView.getLeft() = " + left);  //  Log.e("tag", "hideViewWidth = " + hideViewWidth);  if (left == 0) {   return SwipeState.Close;  }  if (left == -hideViewWidth) {   return SwipeState.Open;  }  return SwipeState.Swiping; } private OnSwipeStateChangeListener listener; public void setOnSwipeStateChangeListener(   OnSwipeStateChangeListener listener) {  this.listener = listener; } public View getContentView() {  return contentView; } public interface OnSwipeStateChangeListener {  void onOpen(SwipeLayout swipeLayout);  void onClose(SwipeLayout swipeLayout);  void onStartOpen(SwipeLayout swipeLayout);  void onStartClose(SwipeLayout swipeLayout); }

然后接下來(lái)是寫(xiě)一個(gè)為listView設(shè)置的SwipeAdapter

SwipeAdapter.java

------------public class SwipeAdapter extends BaseAdapter implements OnSwipeStateChangeListener { private Context mContext; private List<String> list; private MyClickListener myClickListener; private SwipeLayoutManager swipeLayoutManager; public SwipeAdapter(Context mContext) {  super();  this.mContext = mContext;  init(); } private void init() {  myClickListener = new MyClickListener();  swipeLayoutManager = SwipeLayoutManager.getInstance(); } public void setList(List<String> list){  this.list = list;  notifyDataSetChanged(); } @Override public int getCount() {  return list.size(); } @Override public Object getItem(int position) {  return list.get(position); } @Override public long getItemId(int position) {  return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) {  if (convertView == null) {   convertView = UIUtils.inflate(R.layout.list_item_swipe);  }  ViewHolder holder = ViewHolder.getHolder(convertView);  holder.tv_content.setText(list.get(position));  holder.tv_overhead.setOnClickListener(myClickListener);  holder.tv_overhead.setTag(position);  holder.tv_delete.setOnClickListener(myClickListener);  holder.tv_delete.setTag(position);  holder.sv_layout.setOnSwipeStateChangeListener(this);  holder.sv_layout.setTag(position);  holder.sv_layout.getContentView().setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    ToastUtils.showToast("item click : " + position);    swipeLayoutManager.closeUnCloseSwipeLayout();   }  });  return convertView; } static class ViewHolder {  TextView tv_content, tv_overhead, tv_delete;  SwipeLayout sv_layout;  public ViewHolder(View convertView) {   tv_content = (TextView) convertView.findViewById(R.id.tv_content);   tv_overhead = (TextView) convertView.findViewById(R.id.tv_overhead);   tv_delete = (TextView) convertView.findViewById(R.id.tv_delete);   sv_layout = (SwipeLayout) convertView.findViewById(R.id.sv_layout);  }  public static ViewHolder getHolder(View convertView) {   ViewHolder holder = (ViewHolder) convertView.getTag();   if (holder == null) {    holder = new ViewHolder(convertView);    convertView.setTag(holder);   }   return holder;  } } class MyClickListener implements View.OnClickListener {  @Override  public void onClick(View v) {   Integer position = (Integer) v.getTag();   switch (v.getId()) {    case R.id.tv_overhead:     //ToastUtils.showToast("position : " + position + " overhead is clicked.");     }     break;    case R.id.tv_delete:     //ToastUtils.showToast("position : " + position + " delete is clicked.");     }     break;    default:     break;   }  } } @Override public void onOpen(SwipeLayout swipeLayout) {  //ToastUtils.showToast(swipeLayout.getTag() + "onOpen."); } @Override public void onClose(SwipeLayout swipeLayout) {  //ToastUtils.showToast(swipeLayout.getTag() + "onClose."); } @Override public void onStartOpen(SwipeLayout swipeLayout) {  //   ToastUtils.showToast("onStartOpen."); } @Override public void onStartClose(SwipeLayout swipeLayout) {  //   ToastUtils.showToast("onStartClose."); }}

此時(shí)已經(jīng)基本實(shí)現(xiàn)了我們需要的大部分功能了,但是當(dāng)我們滑動(dòng)的時(shí)候,又發(fā)現(xiàn)新的問(wèn)題,我們的SwipeLayout和listview滑動(dòng)判斷有問(wèn)題。由于前面我們僅僅是將touch攔截事件簡(jiǎn)簡(jiǎn)單單的丟給了viewDragHelper.shouldInterceptTouchEvent(ev)來(lái)處理,導(dǎo)致SwipeLayout和listview攔截touch事件時(shí)的處理存在一定的問(wèn)題,這里我們要提到一個(gè)知識(shí)點(diǎn):Android view事件的傳遞。
(1)首先由Activity分發(fā),分發(fā)給根View,也就是DecorView(DecorView為整個(gè)Window界面的最頂層View)
(2)然后由根View分發(fā)到子的View

view事件攔截如下圖所示:

Android,QQ,抽屜

view事件的消費(fèi)如下圖所示:

Android,QQ,抽屜

注:以上2張圖借鑒網(wǎng)上總結(jié)的比較經(jīng)典的圖

所以這里我們就要談到一開(kāi)始出現(xiàn)的ContentLayout,主要重寫(xiě)了onInterceptTouchEvent和onTouchEvent。

public class ContentLayout extends LinearLayout { SwipeLayoutInterface mISwipeLayout; public ContentLayout(Context context) {  super(context); } public ContentLayout(Context context, AttributeSet attrs) {  super(context, attrs); } public ContentLayout(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr); } public void setSwipeLayout(SwipeLayoutInterface iSwipeLayout) {  this.mISwipeLayout = iSwipeLayout; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) {//  Log.e("ContentLayout", "-----onInterceptTouchEvent-----");  if (mISwipeLayout.getCurrentState() == SwipeState.Close) {   return super.onInterceptTouchEvent(ev);  } else {   return true;  } } @Override public boolean onTouchEvent(MotionEvent ev) {//  Log.e("ContentLayout", "-----onTouchEvent-----");  if (mISwipeLayout.getCurrentState() == SwipeState.Close) {   return super.onTouchEvent(ev);  } else {   if (ev.getActionMasked() == MotionEvent.ACTION_UP) {    mISwipeLayout.close();   }   return true;  } }}

另外由于在ContentLayout中需要拿到父View SwipeLayout的開(kāi)關(guān)狀態(tài)以及控制SwipeLayout的關(guān)閉,因此在再寫(xiě)一個(gè)接口,用于ContentLayout獲取SwipeLayout的開(kāi)關(guān)狀態(tài)以及更新SwipeLayout。

public interface SwipeLayoutInterface { SwipeState getCurrentState(); void open(); void close();}

然后接著的是完善SwipeLayout的onInterceptTouchEvent,我們?cè)谶@里增加一個(gè)GestureDetectorCompat處理手勢(shì)識(shí)別:

 private void init(Context context) {  viewDragHelper = ViewDragHelper.create(this, callback);  mGestureDetector = new GestureDetectorCompat(context, mOnGestureListener);  swipeLayoutManager = SwipeLayoutManager.getInstance(); } private SimpleOnGestureListener mOnGestureListener = new SimpleOnGestureListener() {  @Override  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {   // 當(dāng)橫向移動(dòng)距離大于等于縱向時(shí),返回true   return Math.abs(distanceX) >= Math.abs(distanceY);  } };  @Override public boolean onInterceptTouchEvent(MotionEvent ev) {  boolean result = viewDragHelper.shouldInterceptTouchEvent(ev) & mGestureDetector.onTouchEvent(ev);  //  Log.e("SwipeLayout", "-----onInterceptTouchEvent-----");  return result; }

如此下來(lái),整個(gè)View不管是上下拖動(dòng),還是SwipeLayout的開(kāi)關(guān)滑動(dòng),都已經(jīng)實(shí)現(xiàn)完成了。最后增加對(duì)應(yīng)overhead,delete以及item的點(diǎn)擊事件,此處完善SwipeAdapter的代碼之后如下。

 class MyClickListener implements View.OnClickListener {  @Override  public void onClick(View v) {   Integer position = (Integer) v.getTag();   switch (v.getId()) {    case R.id.tv_overhead:     //ToastUtils.showToast("position : " + position + " overhead is clicked.");     swipeLayoutManager.closeUnCloseSwipeLayout(false);     if(onSwipeControlListener != null){      onSwipeControlListener.onOverhead(position, list.get(position));     }     break;    case R.id.tv_delete:     //ToastUtils.showToast("position : " + position + " delete is clicked.");     swipeLayoutManager.closeUnCloseSwipeLayout(false);     if(onSwipeControlListener != null){      onSwipeControlListener.onDelete(position, list.get(position));     }     break;    default:     break;   }  } } private OnSwipeControlListener onSwipeControlListener; public void setOnSwipeControlListener(OnSwipeControlListener onSwipeControlListener){  this.onSwipeControlListener = onSwipeControlListener; } /**  * overhead 和 delete點(diǎn)擊事件接口  */ public interface OnSwipeControlListener{  void onOverhead(int position, String itemTitle);  void onDelete(int position, String itemTitle); }

最后貼上MainActivity代碼,此處通過(guò)OnSwipeControlListener接口回調(diào)實(shí)現(xiàn)item的刪除和置頂:

 

public class MainActivity extends Activity implements OnSwipeControlListener { private ListView listView; private List<String> list = new ArrayList<String>(); private SwipeLayoutManager swipeLayoutManager; private SwipeAdapter swipeAdapter; protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  initData();  initView(); } private void initData() {  for (int i = 0; i < 50; i++) {   list.add("content - " + i);  } } private void initView() {  swipeLayoutManager = SwipeLayoutManager.getInstance();  swipeAdapter = new SwipeAdapter(this);  swipeAdapter.setList(list);  listView = (ListView) findViewById(R.id.list_view);  listView.setAdapter(swipeAdapter);  listView.setOnScrollListener(new OnScrollListener() {   @Override   public void onScrollStateChanged(AbsListView view, int scrollState) {    swipeLayoutManager.closeUnCloseSwipeLayout();   }   @Override   public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {   }  });  swipeAdapter.setOnSwipeControlListener(this); } @Override public void onOverhead(int position, String itemTitle) {  setItemOverhead(position, itemTitle); } @Override public void onDelete(int position, String itemTitle) {  removeItem(position, itemTitle); } /**  * 設(shè)置item置頂  *  * @param position  * @param itemTitle  */ private void setItemOverhead(int position, String itemTitle) {  // ToastUtils.showToast("position : " + position + " overhead.");  ToastUtils.showToast("overhead ---" + itemTitle + "--- success.");  String newTitle = itemTitle;  list.remove(position);//刪除要置頂?shù)膇tem  list.add(0, newTitle);//根據(jù)adapter傳來(lái)的Title數(shù)據(jù)在list 0位置插入title字符串,達(dá)到置頂效果  swipeAdapter.setList(list);//重新給Adapter設(shè)置list數(shù)據(jù)并更新  UIUtils.runOnUIThread(new Runnable() {   @Override   public void run() {    listView.setSelection(0);//listview選中第0項(xiàng)item   }  }); } /**  * 刪除item  *  * @param position  * @param itemTitle  */ private void removeItem(int position, String itemTitle) {  //  ToastUtils.showToast("position : " + position + " delete.");  ToastUtils.showToast("delete ---" + itemTitle + "--- success.");  list.remove(position);  swipeAdapter.setList(list);//重新給Adapter設(shè)置list數(shù)據(jù)并更新 }}

至此整個(gè)demo基本完成,本次完成的功能基本能夠直接放到項(xiàng)目中使用。其實(shí)最麻煩的地方就在于view的touch事件攔截和處理,不過(guò)將本demo的log打開(kāi)看一下對(duì)比之后,也就能夠理解整個(gè)傳遞過(guò)程了。

完整demo地址:https://github.com/Horrarndoo/SwipeLayout

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 望谟县| 苗栗市| 洞头县| 泌阳县| 泾川县| 商水县| 东乡族自治县| 当阳市| 神池县| 宝山区| 阳信县| 宁远县| 鸡泽县| 板桥市| 大姚县| 内乡县| 大名县| 樟树市| 额尔古纳市| 调兵山市| 礼泉县| 山西省| 布尔津县| 新密市| 昌江| 穆棱市| 北宁市| 邹城市| 如东县| 漠河县| 康平县| 长葛市| 东阳市| 全椒县| 承德县| 福海县| 潜山县| 红河县| 克拉玛依市| 尼勒克县| 广州市|