Main XML
private Boolean mIsHorizontal;
public SwipeListView(Context context) {
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.listviewwithswipetoshowsomeitem.MainActivity" >
<com.example.listviewwithswipetoshowsomeitem.SwipeListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/SwipeListViewId" />
</RelativeLayout>
Main Java Class
public class MainActivity extends Activity {
SwipeListView mListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (SwipeListView)findViewById(R.id.SwipeListViewId);
mListView.setAdapter(new SwipeListViewAdapterClass());
}
}
Adapter Class
class SwipeListViewAdapterClass extends BaseAdapter
{
@Override
public int getCount() {
// TODO Auto-generated method stub
return 20;
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(final int position, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
View view = getLayoutInflater().inflate(R.layout.item, null);
View left_item_Layout = (View)view.findViewById(R.id.item_left);
View Right_item_Layout = (View)view.findViewById(R.id.item_right);
TextView Name = (TextView)view.findViewById(R.id.item_left_txt);
TextView Right_Item_Name = (TextView)view.findViewById(R.id.item_right_txt);
Name.setText("Item "+position);
Right_Item_Name.setText("Delete");
LinearLayout.LayoutParams lp1 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
left_item_Layout.setLayoutParams(lp1);
LinearLayout.LayoutParams lp2 = new LayoutParams(300, LayoutParams.MATCH_PARENT);
Right_item_Layout.setLayoutParams(lp2);
Right_Item_Name.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "Delete Button Clicked Position "+position, Toast.LENGTH_SHORT).show();
}
});
return view;
}
}
Adapter Class Row Or listview Row XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<RelativeLayout
android:id="@+id/item_left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/item_left_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:padding="12dp"
android:textColor="#000000" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/item_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#FF0000" >
<TextView
android:padding="20dp"
android:id="@+id/item_right_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:textColor="#FFFFFF" />
</RelativeLayout>
</LinearLayout>
SwipeListView Java Class
public class SwipeListView extends ListView {
private Boolean mIsHorizontal;
private View mPreItemView;
private View mCurrentItemView;
private float mFirstX;
private float mFirstY;
private int mRightViewWidth = 300;
private final int mDuration = 100;
private final int mDurationStep = 10;
private boolean mIsShown;
private boolean mIsFooterCanSwipe = false;
private boolean mIsHeaderCanSwipe = false;
public SwipeListView(Context context) {
super(context);
}
public SwipeListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SwipeListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
float lastX = ev.getX();
float lastY = ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mIsHorizontal = null;
mFirstX = lastX;
mFirstY = lastY;
int motionPosition = pointToPosition((int)mFirstX, (int)mFirstY);
if (motionPosition >= 0) {
View currentItemView = getChildAt(motionPosition - getFirstVisiblePosition());
mPreItemView = mCurrentItemView;
mCurrentItemView = currentItemView;
}
break;
case MotionEvent.ACTION_MOVE:
float dx = lastX - mFirstX;
float dy = lastY - mFirstY;
if (Math.abs(dx) >= 5 && Math.abs(dy) >= 5) {
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (mIsShown && (mPreItemView != mCurrentItemView || isHitCurItemLeft(lastX))) {
System.out.println("1---> hiddenRight");
hiddenRight(mPreItemView);
}
break;
}
return super.onInterceptTouchEvent(ev);
}
private boolean isHitCurItemLeft(float x) {
return x < getWidth() - mRightViewWidth;
}
private boolean judgeScrollDirection(float dx, float dy) {
boolean canJudge = true;
if (Math.abs(dx) > 30 && Math.abs(dx) > 2 * Math.abs(dy)) {
mIsHorizontal = true;
} else if (Math.abs(dy) > 30 && Math.abs(dy) > 2 * Math.abs(dx)) {
mIsHorizontal = false;
} else {
canJudge = false;
}
return canJudge;
}
private boolean judgeFooterView(float posX, float posY) {
// if footer can swipe
if (mIsFooterCanSwipe) {
return true;
}
// footer cannot swipe
int selectPos = pointToPosition((int)posX, (int)posY);
if (selectPos >= (getCount() - getFooterViewsCount())) {
// is footer ,can not swipe
return false;
}
// not footer can swipe
return true;
}
private boolean judgeHeaderView(float posX, float posY) {
// if header can swipe
if (mIsHeaderCanSwipe) {
return true;
}
// header cannot swipe
int selectPos = pointToPosition((int)posX, (int)posY);
if (selectPos >= 0 && selectPos < getHeaderViewsCount()) {
// is header ,can not swipe
return false;
}
// not header can swipe
return true;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
float lastX = ev.getX();
float lastY = ev.getY();
// test footer and header
if (!judgeFooterView(mFirstX, mFirstY) || !judgeHeaderView(mFirstX, mFirstY)) {
return super.onTouchEvent(ev);
}
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
float dx = lastX - mFirstX;
float dy = lastY - mFirstY;
// confirm is scroll direction
if (mIsHorizontal == null) {
if (!judgeScrollDirection(dx, dy)) {
break;
}
}
if (mIsHorizontal) {
if (mIsShown && mPreItemView != mCurrentItemView) {
hiddenRight(mPreItemView);
}
if (mIsShown && mPreItemView == mCurrentItemView) {
dx = dx - mRightViewWidth;
}
// can't move beyond boundary
if (dx < 0 && dx > -mRightViewWidth) {
mCurrentItemView.scrollTo((int)(-dx), 0);
}
return true;
} else {
if (mIsShown) {
hiddenRight(mPreItemView);
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
clearPressedState();
if (mIsShown) {
hiddenRight(mPreItemView);
}
if (mIsHorizontal != null && mIsHorizontal) {
if (mFirstX - lastX > mRightViewWidth / 2) {
showRight(mCurrentItemView);
} else {
hiddenRight(mCurrentItemView);
}
return true;
}
break;
}
return super.onTouchEvent(ev);
}
private void clearPressedState() {
// TODO current item is still has background, issue
mCurrentItemView.setPressed(false);
setPressed(false);
refreshDrawableState();
// invalidate();
}
private void showRight(View view) {
Message msg = new MoveHandler().obtainMessage();
msg.obj = view;
msg.arg1 = view.getScrollX();
msg.arg2 = mRightViewWidth;
msg.sendToTarget();
mIsShown = true;
}
private void hiddenRight(View view) {
if (mCurrentItemView == null) {
return;
}
Message msg = new MoveHandler().obtainMessage();//
msg.obj = view;
msg.arg1 = view.getScrollX();
msg.arg2 = 0;
msg.sendToTarget();
mIsShown = false;
}
@SuppressLint("HandlerLeak")
class MoveHandler extends Handler {
int stepX = 0;
int fromX;
int toX;
View view;
private boolean mIsInAnimation = false;
private void animatioOver() {
mIsInAnimation = false;
stepX = 0;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (stepX == 0) {
if (mIsInAnimation) {
return;
}
mIsInAnimation = true;
view = (View)msg.obj;
fromX = msg.arg1;
toX = msg.arg2;
stepX = (int)((toX - fromX) * mDurationStep * 1.0 / mDuration);
if (stepX < 0 && stepX > -1) {
stepX = -1;
} else if (stepX > 0 && stepX < 1) {
stepX = 1;
}
if (Math.abs(toX - fromX) < 10) {
view.scrollTo(toX, 0);
animatioOver();
return;
}
}
fromX += stepX;
boolean isLastStep = (stepX > 0 && fromX > toX) || (stepX < 0 && fromX < toX);
if (isLastStep) {
fromX = toX;
}
view.scrollTo(fromX, 0);
invalidate();
if (!isLastStep) {
this.sendEmptyMessageDelayed(0, mDurationStep);
} else {
animatioOver();
}
}
}
public int getRightViewWidth() {
return mRightViewWidth;
}
public void setRightViewWidth(int mRightViewWidth) {
this.mRightViewWidth = mRightViewWidth;
}
public void setFooterViewCanSwipe(boolean canSwipe) {
mIsFooterCanSwipe = canSwipe;
}
public void setHeaderViewCanSwipe(boolean canSwipe) {
mIsHeaderCanSwipe = canSwipe;
}
public void setFooterAndHeaderCanSwipe(boolean footer, boolean header) {
mIsHeaderCanSwipe = header;
mIsFooterCanSwipe = footer;
}
}
No comments:
Post a Comment