注:前些日子看到在http://www.apkbus.com/forum.php?mod=viewthread&tid=158139&extra=page%3D22的代碼,感受效果不錯,遂向其學習而寫以下代碼,爲其精簡版,沒有樓主的例子完美。以此記錄,來記錄學習歷程,以備後用。php
先上圖:android
在這寫下本身的思路:app
首先是個listview,但該listview的item左滑的時候,就會出現如圖效果。想到應該是自定義的listview,複寫其OnTouchEvent方法。那每一個listview的item的滑動又是怎麼實現的呢?是的,您猜的沒錯,用的是scroller。ide
listitem的每一個item的xml:post
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/view_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
</LinearLayout>
<RelativeLayout
android:id="@+id/holder"
android:layout_width="120dp"
android:layout_height="match_parent"
android:clickable="true"
android:background="@drawable/holder_bg">
<TextView
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/del_icon_normal"
android:layout_centerInParent="true"
android:gravity="center"
android:textColor="@color/floralwhite"
android:text="刪除" />
</RelativeLayout>
</merge>
學習
slideview類:ui
package com.ryg.slideview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;
public class SlideView extends LinearLayout {
private static final String TAG = "SlideView";
private Context mContext;
private LinearLayout mViewContent;
private RelativeLayout mHolder;
private Scroller mScroller;
private int mHolderWidth = 120;
private int mLastX = 0;
private int mLastY = 0;
private static final int TAN = 2;
public SlideView(Context context) {
super(context);
initView();
}
public SlideView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
private void initView() {
mContext = getContext();
mScroller = new Scroller(mContext);
setOrientation(LinearLayout.HORIZONTAL);
View.inflate(mContext, R.layout.slide_view_merge, this);
mViewContent = (LinearLayout) findViewById(R.id.view_content);
mHolderWidth = Math.round(TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, mHolderWidth, getResources()
.getDisplayMetrics()));
// TypedValue.COMPLEX_UNIT_PX,時在不一樣手機上的數值都是同樣的,仍是原來數據120.
//
/*
* mHolderWidth = Math.round(TypedValue.applyDimension(
* TypedValue.COMPLEX_UNIT_PX, mHolderWidth, getResources()
* .getDisplayMetrics()));
*/
// TypedValue.COMPLEX_UNIT_DIP在不一樣手機上顯示的是不一樣的,是獨立於設備的。
// 在公司e6機器上顯示的是180,在lg上顯示240
System.out.println("轉化後的mHolderWidth is " + mHolderWidth);
}
public void setButtonText(CharSequence text) {
((TextView) findViewById(R.id.delete)).setText(text);
}
public void setContentView(View view) {
mViewContent.addView(view);
}
public void onRequireTouchEvent(MotionEvent event) {
// 注意執行順序,每次不一樣的action都要執行int x=event.getX();和mLastX=x;
// 注意此處的event。getX.越靠左的點x座標越小,越靠右,x的座標越大。
int x = (int) event.getX();
int y = (int) event.getY();
System.out.println("event.getX is " + x + "event.getY is --" + y);
// 該處方法是得到滑動了多少距離,根據打印的log。當滑動了180時就再也不滑動了
int scrollX = getScrollX();
System.out.println("滑動了多少距離" + scrollX);
Log.d(TAG, "x=" + x + " y=" + y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
System.out.println("----------down down down down ");
break;
case MotionEvent.ACTION_MOVE:
System.out.println("-----------move move move ");
int deltaX = x - mLastX;
int deltaY = y - mLastY;
System.out.println("----move deltaX is" + deltaX);
if (Math.abs(deltaX) < Math.abs(deltaY) * TAN) {
break;
}
// 注意這一步的處理,使用的減號
int newScrollX = scrollX - deltaX;
System.out.println("--------newScroll is" + newScrollX);
if (deltaX != 0) {
// 此處爲若是復原向右滑則滑動到初始狀態,不然滑動到最左
if (newScrollX < 0) {
newScrollX = 0;
} else if (newScrollX > mHolderWidth) {
newScrollX = mHolderWidth;
}
// scrollTo的參數x,若爲負數則向右滾動,若爲正數則向左滾動
this.scrollTo(newScrollX, 0);
}
break;
case MotionEvent.ACTION_UP:
System.out.println("------------up");
newScrollX = 0;
// 若是已經滑動le0.75倍的距離,則直接滑動到目的地,不然滑動回原來的位置
if (scrollX - mHolderWidth * 0.75 > 0) {
newScrollX = mHolderWidth;
}
this.smoothScrollTo(newScrollX, 0);
break;
default:
break;
}
mLastX = x;
mLastY = y;
System.out.println("---------last x -----" + mLastX);
}
private void smoothScrollTo(int destX, int destY) {
// 緩慢滾動到指定位置
// 返回滾動的view的左邊界
int scrollX = getScrollX();
// 在該例子中,當向左滑動時此處的scrollX是正數
System.out.println("scrollX is" + scrollX);
// getScrollX是獲得總共滑動的距離,一定爲正數
int delta = destX - scrollX;
// startScroll中的參數xofferset若是爲正數則向左滑動,yofferset若是爲正數則向上滑動
mScroller.startScroll(scrollX, 0, delta, 0, Math.abs(delta) * 3);
invalidate();
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
}
this
如今能夠看下listview的適配器中每一個item的視圖是怎麼組織的spa
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
SlideView slideView = (SlideView) convertView;
if (slideView == null) {
View itemView = mInflater.inflate(R.layout.list_item, null);
slideView = new SlideView(MainActivity.this);
slideView.setContentView(itemView);
holder = new ViewHolder(slideView);
// slideView.setOnSlideListener(MainActivity.this);
slideView.setTag(holder);
} else {
holder = (ViewHolder) slideView.getTag();
}
MessageItem item = mMessageItems.get(position);
item.slideView = slideView;
holder.icon.setImageResource(item.iconRes);
holder.title.setText(item.title);
holder.msg.setText(item.msg);
holder.time.setText(item.time);
holder.deleteHolder.setOnClickListener(MainActivity.this);
return slideView;
}
.net
爲何merge標籤會有這種效果呢,仍是不是很明白。若是將merge標籤換爲framelayout則不會有這種視圖效果。疑問中。
菜鳥帖子,勿噴。
源碼地址:http://download.csdn.net/detail/u010095768/7186465