高仿微信对话列表滑动删除效果
前言
用過微信的都知道。微信對(duì)話列表滑動(dòng)刪除效果是非常不錯(cuò)的,這個(gè)效果我們也能夠有。
思路事實(shí)上非常easy,弄個(gè)ListView。然后里面的每一個(gè)item做成一個(gè)能夠滑動(dòng)的自己定義控件就可以。由于ListView是上下滑動(dòng)而item是左右滑動(dòng),因此會(huì)有滑動(dòng)沖突。或許你須要了解下android中點(diǎn)擊事件的派發(fā)流程,請(qǐng)參考Android源代碼分析-點(diǎn)擊事件派發(fā)機(jī)制。我的解決思路是這種:重寫ListView的onInterceptTouchEvent方法,在move的時(shí)候做推斷,假設(shè)是左右滑動(dòng)就返回false。否則返回true;重寫SlideView(即自己定義item控件)的onTouchEvent方法來處理滑動(dòng)。
整個(gè)思路沒有問題。滑動(dòng)沖突也攻克了,但是ListView無法得到焦點(diǎn)了,也就是ListView無法處理點(diǎn)擊事件了。讓我們回憶下問題出在哪里:我的理解是這種。上述處理滑動(dòng)本身沒有問題,但是有一個(gè)副作用。就是會(huì)讓外層View失去焦點(diǎn)且無法處理點(diǎn)擊事件。
常見的滑動(dòng)沖突場(chǎng)景。比方launcher內(nèi)部嵌入ListView卻是沒有問題的,由于這個(gè)時(shí)候launcher不須要獲得焦點(diǎn),須要獲得焦點(diǎn)的是內(nèi)部的ListView。
因此,上述處理方式對(duì)于外部須要獲得焦點(diǎn)的情況(比方外部是ListView)就不太適合了。于是我就和ttdevs探討,發(fā)現(xiàn)他採用了第二種思路。我從來沒有想過還能夠這樣玩。以下介紹他的思路。
新的思路
不考慮那么復(fù)雜,不採用主流玩法,全部的事件均由外層的ListView做攔截,同一時(shí)候把事件傳遞給SlideView做滑動(dòng),這樣的實(shí)現(xiàn)的確能夠達(dá)到效果,并且代碼非常easy,根本不須要處理什么復(fù)雜的滑動(dòng)沖突。
?
效果
以下分別為微信和高仿效果
?
代碼分析
先看SlideView是怎樣實(shí)現(xiàn)的
看layout xml:
<com.macc.firstsecretary_UI.ListViewCompatandroid:id="@+id/list"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#fff4f7f9"android:cacheColorHint="#00000000"android:divider="#dddbdb"android:dividerHeight="1.0px"android:drawSelectorOnTop="false"android:listSelector="@android:color/transparent"android:scrollbars="none" />
再看com.macc.firstsecretary_UI.ListViewCompat類的代碼:
再看SlideView.java:
OnSlideListener.SLIDE_STATUS_OFF : OnSlideListener.SLIDE_STATUS_ON); } isScroller=true; } break; } default: break; } mLastX = x; mLastY = y; } private void smoothScrollTo(int destX, int destY) { // 緩慢滾動(dòng)到指定位置 int scrollX = getScrollX(); int delta = destX - scrollX; mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3); invalidate(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } }
上述代碼做了非常具體的說明,這就是滑動(dòng)控件的完整代碼,大家要明確的是:你所加入的view都是加在SlideView的子View :?view_content中的,而不是直接加在SlideView中,僅僅有這樣我們才方便做滑動(dòng)效果。
?
?
最后一步我們來看看適配器里面的代碼:
public class Carpa_MySelf_MessageCenterAdapter extends BaseAdapter implements OnSlideListener,OnClickListener{private LayoutInflater inflater;private List<Message> messages;private Context context;private SlideView mSlideView;private int position;//刪除位置數(shù)據(jù)private Handler handler;public Carpa_MySelf_MessageCenterAdapter(Context context,ArrayList<Message> messages,Handler handler){setData(messages);this.context=context;inflater=LayoutInflater.from(context);this.handler=handler;}public void setData(ArrayList<Message> messages){if(messages==null){this.messages=new ArrayList<Message>();}else{this.messages=messages;}}public void setPosition(int position){this.position=position;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn messages.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn messages.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;SlideView slideView = (SlideView) convertView;if (slideView == null) {View itemView = inflater.inflate(R.layout.carpa_myself_message_center_item, null);slideView = new SlideView(context);slideView.setContentView(itemView);holder = new ViewHolder(slideView);slideView.setOnSlideListener(Carpa_MySelf_MessageCenterAdapter.this);slideView.setTag(holder);} else {holder = (ViewHolder) slideView.getTag();}Message msgMessage=messages.get(position);msgMessage.setSlideView(slideView);msgMessage.getSlideView().shrink();String sourceString=msgMessage.getSourceStr();holder.tvContent.setText("內(nèi)容:"+msgMessage.getContentStr());holder.tvTime.setText(UtilTools.fromatDate(msgMessage.getTimeStr()));holder.deleteHolder.setOnClickListener(Carpa_MySelf_MessageCenterAdapter.this);if(sourceString.equals("Traffic")){holder.tvSource.setText("信息來源:66");holder.iView.setBackgroundResource(R.drawable.carpa_wz);}else if(sourceString.equals("DaiJia")){holder.tvSource.setText("信息來源:99");holder.iView.setBackgroundResource(R.drawable.car_deldrive);}else if(sourceString.equals("Nianjian")){holder.tvSource.setText("信息來源:33");holder.iView.setBackgroundResource(R.drawable.car_yearcheck);}else if(sourceString.equals("JiaSZ")){holder.tvSource.setText("信息來源:88");holder.iView.setBackgroundResource(R.drawable.car_zjbl);}else if(sourceString.equals("HKJiaSZ")){holder.tvSource.setText("信息來源:11");holder.iView.setBackgroundResource(R.drawable.car_hongkong);}return slideView;}class ViewHolder {public ImageView iView;public TextView tvSource;public TextView tvTime;public TextView tvContent;public ViewGroup deleteHolder;ViewHolder(View view) {iView=(ImageView)view.findViewById(R.id.message_center_iv);tvSource = (TextView) view.findViewById(R.id.message_center_source);tvTime = (TextView) view.findViewById(R.id.message_center_time);tvContent = (TextView) view.findViewById(R.id.message_center_content);deleteHolder = (ViewGroup)view.findViewById(R.id.holder);}}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif (v.getId() == R.id.holder) {Log.e("info", "onClick v=" + v); // messages.remove(position); // this.notifyDataSetChanged();handler.sendEmptyMessage(Tab_MySelf_MessageCenter.HANDLER_DELETE);}}@Overridepublic void onSlide(View view, int status) {// TODO Auto-generated method stubif (mSlideView != null && mSlideView != view) {mSlideView.shrink();}if (status == SLIDE_STATUS_ON) {mSlideView = (SlideView) view;}}
代碼已貼完成!
僅供參考,謝謝!
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/jzssuanfa/p/6871645.html
總結(jié)
以上是生活随笔為你收集整理的高仿微信对话列表滑动删除效果的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序入门注意
- 下一篇: django【orm操作】