Android UI设计: 仿ios,仿qq实现Listview侧滑出现按钮

老规矩先看效果图:
Android UI设计: 仿ios,仿qq实现Listview侧滑出现按钮_第1张图片

这个代码很常见,网上大牛已经做过好几遍了,但是本着学习的态度,去研究了下别人写的代码。发现有好几种实现方法。最为流行的一种是使用Scroller实现滑动,然后按钮的实现有三种方法。
1. 一种是全部用java类继承一个viewgroup来动态生成listviewitem.这样灵活性很高,但是技巧性也高。
2. 一种是整个listviewitem用xml编写,然后inflate进去。这样写的好处是可以复用,而且只需要adapter重写view, 但是按钮和内容是固定的,不能轻松的实现QQ好友那种,有时候是删除,有时候是置顶,有时候是标记什么的、多种按钮结合
3. 为此我试着把基本listviewitem和按钮xml分开写,写成2个布局,然后用一个linerlayout动态合成起来。这样在扩展的时候可以写多组按钮布局,然后动态判断合成,更容易实现多种类按钮的方法。
4.完成工程在我的github里面:
戳戳戳:https://github.com/younfor/DragListView
下面是核心源码:

package com.draglistview;


import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.widget.ListView;

/** * * @author https://github.com/younfor * */
public class DragDelListView extends ListView {

    //是否可以拖动
    private boolean moveable=false;
    //是否全部关闭
    private boolean closed=true;
    private float mDownX,mDownY;
    private int mTouchPosition,oldPosition=-1;
    private DragDelItem mTouchView,oldView;
    private Context context;
    public DragDelListView(Context context) {
        super(context);
        init(context);
    }
    public DragDelListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }
    public DragDelListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    private void init(Context context) {
        this.context=context;
    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //获取点击的position
            mTouchPosition = pointToPosition((int) ev.getX(), (int) ev.getY());
            //获取点击的view (是可见范围里面的)
            mTouchView=(DragDelItem)getChildAt(mTouchPosition - getFirstVisiblePosition());
            //获取点击的地方
            mDownX = ev.getX();
            mDownY=ev.getY();
            //点击的是同一个或者全部初始
            if(oldPosition==mTouchPosition ||closed)
            {
                //可以移动
                moveable=true;
                mTouchView.mDownX =(int)mDownX;
            }else
            {
                moveable=false;
                if(oldView!=null)
                {   //旧的归位
                    oldView.smoothCloseMenu();
                }
            }
            oldPosition=mTouchPosition;
            oldView=mTouchView;
            break;
        case MotionEvent.ACTION_MOVE:
            //判断是否侧滑
            if (Math.abs(mDownX-ev.getX()) < Math.abs(mDownY-ev.getY()) * dp2px(2)) {  
                break;  
            }  
            if (moveable) 
            {
                int dis = (int) (mTouchView.mDownX -ev.getX());
                //此时方向会变
                if(mTouchView.state==mTouchView.STATE_OPEN)
                    dis+=mTouchView.mMenuView.getWidth();
                mTouchView.swipe(dis);
                ev.setAction(MotionEvent.ACTION_CANCEL);
            }

            break;
        case MotionEvent.ACTION_UP:

            if (moveable) 
            {
                if ((mTouchView.mDownX -ev.getX()) > (mTouchView.mMenuView.getWidth()/2)) {
                    // open
                    mTouchView.smoothOpenMenu();
                    closed=false;
                } else {
                    // close
                    mTouchView.smoothCloseMenu();
                    closed=true;
                }
                ev.setAction(MotionEvent.ACTION_CANCEL);
            }
            break;
        }
        return super.onTouchEvent(ev);
    }

    //将dp转换为px
    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                getContext().getResources().getDisplayMetrics());
    }


}

package com.draglistview;

import android.content.Context;
import android.support.v4.view.GestureDetectorCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.GestureDetector.OnGestureListener;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.AbsListView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Scroller;
/**
*
* @author https://github.com/younfor
*
*/
public class DragDelItem extends LinearLayout {

public static final int STATE_CLOSE = 0;
public static final int STATE_OPEN = 1;
private View mContentView;
public View mMenuView;
public int mDownX;
public int state = STATE_CLOSE;
public boolean isFling;
private int mBaseX;
private Scroller scroll;

public DragDelItem(View contentView, View menuView) {
    super(contentView.getContext());
    scroll=new Scroller(getContext());
    mContentView = contentView;
    mMenuView = menuView;
    init();
}

private DragDelItem(Context context, AttributeSet attrs) {
    super(context, attrs);
}

private DragDelItem(Context context) {
    super(context);
}


private void init() {
    setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,
            LayoutParams.WRAP_CONTENT));
    LayoutParams contentParams = new LayoutParams(
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    mContentView.setLayoutParams(contentParams);

    mMenuView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
            LayoutParams.WRAP_CONTENT));

    addView(mContentView);
    addView(mMenuView);

}


public void swipe(int dis) {
    if (dis > mMenuView.getWidth()) {
        dis = mMenuView.getWidth();
    }
    if (dis < 0) {
        dis = 0;
    }
    mContentView.layout(-dis, mContentView.getTop(),
            mContentView.getWidth() - dis, getMeasuredHeight());
    mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(),
            mContentView.getWidth() + mMenuView.getWidth() - dis,
            mMenuView.getBottom());
}

@Override
public void computeScroll() {
    if (state == STATE_OPEN) {
        if (scroll.computeScrollOffset()) {
            swipe(scroll.getCurrX());
            postInvalidate();
        }
    } else {
        if (scroll.computeScrollOffset()) {
            swipe(mBaseX - scroll.getCurrX());
            postInvalidate();
        }
    }
}

public void smoothCloseMenu() {
    state = STATE_CLOSE;
    mBaseX = -mContentView.getLeft();
    scroll.startScroll(0, 0, mBaseX, 0, 350);
    postInvalidate();
}

public void smoothOpenMenu() {

    state = STATE_OPEN;
    scroll.startScroll(-mContentView.getLeft(), 0,
            mMenuView.getWidth()/2, 0, 350);
    postInvalidate();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    mMenuView.measure(MeasureSpec.makeMeasureSpec(0,
            MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(
            getMeasuredHeight(), MeasureSpec.EXACTLY));
    mContentView.measure(MeasureSpec.makeMeasureSpec(0,
            MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(
            getMeasuredHeight(), MeasureSpec.EXACTLY));

}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    mContentView.layout(0, 0, getMeasuredWidth(),
            mContentView.getMeasuredHeight());
    mMenuView.layout(getMeasuredWidth(), 0,
            getMeasuredWidth() + mMenuView.getMeasuredWidth(),
            mContentView.getMeasuredHeight());

}

}

package com.draglistview;

import java.util.List;

import com.draglistview.*;

import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

/** * * @author https://github.com/younfor * */
public class MainActivity extends Activity {
    private List<ApplicationInfo> mAppList;
    private DragDelListView mListView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);

        mAppList = getPackageManager().getInstalledApplications(0);
        mListView = (DragDelListView) findViewById(R.id.listView);
        mListView.setAdapter(new AppAdapter(mAppList));
    }
    class AppAdapter extends BaseAdapter {
        private List<ApplicationInfo> mAppList;
        public AppAdapter(List<ApplicationInfo> appList)
        {
            mAppList=appList;
        }
        @Override
        public int getCount() {
            return mAppList.size();
        }

        @Override
        public ApplicationInfo getItem(int position) {
            return mAppList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            final int loc=position;
            ViewHolder holder=null;
            View menuView=null;
            if (convertView == null) {
                convertView = View.inflate(getApplicationContext(),
                        R.layout.swipecontent, null);
                menuView = View.inflate(getApplicationContext(),
                        R.layout.swipemenu, null);
                //合成内容与菜单
                convertView = new DragDelItem(convertView,menuView);;
                holder=new ViewHolder(convertView);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
                ApplicationInfo item = getItem(position);
                holder.iv_icon.setImageDrawable(item.loadIcon(getPackageManager()));
                holder.tv_name.setText(item.loadLabel(getPackageManager()));
                holder.tv_open.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View arg0) {
                        Toast.makeText(MainActivity.this, "open:"+loc, Toast.LENGTH_SHORT).show();
                    }
                });
                holder.tv_del.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View arg0) {

                    }
                });
            return convertView;
        }

        class ViewHolder {
            ImageView iv_icon;
            TextView tv_name;
            TextView tv_open,tv_del;
            public ViewHolder(View view) {
                iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
                tv_name = (TextView) view.findViewById(R.id.tv_name);
                tv_open=(TextView)view.findViewById(R.id.tv_open);
                tv_del=(TextView)view.findViewById(R.id.tv_del);
                view.setTag(this);
            }
        }
    }
}

你可能感兴趣的:(android)