Android定制化ListView

来源:互联网 发布:网络3d游戏大全 编辑:程序博客网 时间:2024/05/21 19:31
/**
 * 定制化ListView, 实现了锁定其它ListView, 使其它ListView在他滑动时也跟着滑动
 *
 */
public class SynchScrollListView extends ListView {
    
    private float mDeceleration;

    /** 关联的ListView **/
    private List<SynchScrollListView> mLinkList = new ArrayList<SynchScrollListView>();
    
    private int mLastY;
    
    private VelocityTracker mVelocityTracker;

    /** 是否自动触发的Touch事件 **/
    protected boolean autoTouch;

    public SynchScrollListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public SynchScrollListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public SynchScrollListView(Context context) {
        super(context);
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        
        float ppi = getContext().getResources().getDisplayMetrics().density * 160.0f;
        
        mDeceleration = SensorManager.GRAVITY_EARTH   // g (m/s^2)
                * 39.37f                        // inch/meter
                * ppi                           // pixels per inch
                * ViewConfiguration.getScrollFriction();
        
        setOnTouchListener(null);
        setOnScrollListener(null);
    }

    /**
     * 绑定相关ListView
     *
     * @param lv
     */
    public void linkListView(SynchScrollListView lv) {
        mLinkList.add(lv);
    }

    /**
     * 取消绑定
     *
     * @param lv
     */
    public void removeLink(SynchScrollListView lv) {
        mLinkList.remove(lv);
    }

    /**
     * 取消所有绑定
     */
    public void removeAllLinks() {
        mLinkList.clear();
    }
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        
        for (SynchScrollListView lv : mLinkList) {
            if (lv != null && !autoTouch) {
                lv.autoTouch = true;
                lv.dispatchTouchEvent(ev);

            } else if (autoTouch) {
                autoTouch = false;
            }
        }
        
        return super.dispatchTouchEvent(ev);
        
    }
    
//    @Override
//    public boolean onTouchEvent(MotionEvent ev) {
//        // TODO Auto-generated method stub
//        
//        final int y = (int) ev.getY();
//        
//        final int action = ev.getActionMasked();
//        
//        if (mVelocityTracker == null) {
//            mVelocityTracker = VelocityTracker.obtain();
//        }
//        
//        mVelocityTracker.addMovement(ev);
//        
//        switch(action){
//        
//        case MotionEvent.ACTION_DOWN:
//            
//            mLastY = y;
//            
//            break;
//        
//        case MotionEvent.ACTION_MOVE:
//            
//            final int distance = mLastY - y;
//            
//            if(Math.abs(distance) > 1){
//                smoothScrollBy(distance, 0);
//                
//                mLastY = y;
//            }
//            
//            return false;
//            
//        case MotionEvent.ACTION_UP:
//            
//            final VelocityTracker velocityTracker = mVelocityTracker;
//            velocityTracker.computeCurrentVelocity(1000);
//            
//            final int initialVelocity = (int) velocityTracker.getYVelocity();
//            if(Math.abs(initialVelocity) > 500){
//                smoothScrollBy(-initialVelocity);
//                
//            }
//            
//            //回收资源
//            if (mVelocityTracker != null) {
//                
//                mVelocityTracker.recycle();
//
//                mVelocityTracker = null;
//
//            }
//            
//            mLastY = y;
//            
//            break;
//        }
//
//        
//        return super.onTouchEvent(ev);
//    }
    
    
    public void smoothScrollBy(int velocityY){
        
        final float velocity = (float)Math.hypot(0, velocityY);
        
        final float mCoeffY = velocityY == 0 ? 1.0f : velocityY / velocity;

        final int totalDistance = (int) ((velocity * velocity) / (2 * mDeceleration));
        
        final int duration = (int) (1000 * velocity / mDeceleration);
        
        final int distance = Math.round(totalDistance * mCoeffY);
        
        smoothScrollBy(distance, duration);
    }
    
//    @Override
//    public void smoothScrollBy(int distance, int duration) {
//        // TODO Auto-generated method stub
//        super.smoothScrollBy(distance, duration);
//        
//        for (ListView lv : mLinkList) {
//            if (lv != null && !autoTouch) {
//                if (lv instanceof SynchScrollListView) {
//                    ((SynchScrollListView) lv).autoTouch = true;
//                }
//                lv.smoothScrollBy(distance, duration);
//
//            } else if (autoTouch) {
//                autoTouch = false;
//            }
//        }
//    }
//    
//    @Override
//    public void smoothScrollToPosition(int position) {
//        // TODO Auto-generated method stub
//        super.smoothScrollToPosition(position);
//        
//        for (ListView lv : mLinkList) {
//            if (lv != null && !autoTouch) {
//                if (lv instanceof SynchScrollListView) {
//                    ((SynchScrollListView) lv).autoTouch = true;
//                }
//                lv.smoothScrollToPosition(position);
//
//            } else if (autoTouch) {
//                autoTouch = false;
//            }
//        }
//        
//        
//    }
//    
//    @Override
//    public void smoothScrollToPosition(int position, int boundPosition) {
//        // TODO Auto-generated method stub
//        super.smoothScrollToPosition(position, boundPosition);
//        
//        for (ListView lv : mLinkList) {
//            if (lv != null && !autoTouch) {
//                if (lv instanceof SynchScrollListView) {
//                    ((SynchScrollListView) lv).autoTouch = true;
//                }
//                lv.smoothScrollToPosition(position, boundPosition);
//
//            } else if (autoTouch) {
//                autoTouch = false;
//            }
//        }
//    }
    

    
//    @Override
//    public void setOnTouchListener(final OnTouchListener l) {
//        final OnTouchListener mtl = new OnTouchListener() {
//
//            @Override
//            public boolean onTouch(View v, MotionEvent event) {
//                for (ListView lv : mLinkList) {
//                    if (lv != null && !autoTouch) {
//                        if (lv instanceof SynchScrollListView) {
//                            ((SynchScrollListView) lv).autoTouch = true;
//                        }
//                        lv.dispatchTouchEvent(event);
//
//                    } else if (autoTouch) {
//                        autoTouch = false;
//                    }
//                }
//
//                if (l != null) {
//                    l.onTouch(v, event);
//                }
//
//                return false;
//            }
//        };
//
//        super.setOnTouchListener(mtl);
//    }

    @Override
    public void setOnScrollListener(final OnScrollListener l) {

        final OnScrollListener sl = new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

                for (ListView lv : mLinkList) {
                    if (lv != null) {
                        
                        
                        // 在停止滑动的时候保证两列表所处位置一致
                        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
                            final int position1 = getFirstVisiblePosition();
                            final int position2 = lv.getFirstVisiblePosition();

                            final int top1 = getChildAt(0).getTop();
                            final int top2 = lv.getChildAt(0).getTop();

                            if (top1 != top2 || position1 != position2) {

                                setSelection(position1);
                                lv.setSelection(position1);

                            }

                        }
                    }
                }

                if (l != null) {
                    l.onScrollStateChanged(view, scrollState);
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {

                if (l != null) {
                    l.onScroll(view, firstVisibleItem, visibleItemCount,
                            totalItemCount);
                }
            }
        };

        super.setOnScrollListener(sl);
    }

}

原创粉丝点击