实现上下左右滑动的listview,表头联动(附带可以点击的效果)

整体思路:


1.触摸事件的统一传递

2.HorizontalScrollview的重写

3.touch事件的处理


1.item和头布局都统一用的布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="88px"
    android:background="#FFF3F3F3">

    <TextView
        android:id="@+id/tv_contract"
        android:layout_width="180px"
        android:layout_height="88px"
        android:layout_alignParentLeft="true"
        android:gravity="center"
        android:text="合约号"
        android:textSize="32px"
        android:textColor="#000000"
        android:background="#F4F4F4" />

    <View
        android:id="@+id/view"
        android:layout_toRightOf="@+id/tv_contract"
        android:layout_width="1px"
        android:layout_height="88px"
        android:background="#FFCCCCCC" />

    <LinearLayout
        android:id="@+id/scroollContainter"
        android:layout_width="match_parent"
        android:layout_height="88px"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@id/view"
        android:background="#F4F4F4"
        >

        <com.dlfc.android.smartinfo.ui.view.OptionalScrollView
            android:id="@+id/headerHScrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:focusable="false"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/textView1"
                    android:layout_width="180px"
                    android:layout_height="match_parent"
                    android:textSize="32px"
                    android:gravity="center"
                    android:textColor="#000000"
                    android:text="最新价" />

                <TextView
                    android:id="@+id/textView2"
                    android:layout_width="180px"
                    android:layout_height="match_parent"
                    android:textSize="32px"
                    android:gravity="center"
                    android:textColor="#000000"
                    android:text="涨跌(%)" />

                <TextView
                    android:id="@+id/textView3"
                    android:layout_width="180px"
                    android:layout_height="match_parent"
                    android:textSize="32px"
                    android:gravity="center"
                    android:textColor="#000000"
                    android:text="成交量" />

                <TextView
                    android:id="@+id/textView4"
                    android:layout_width="180px"
                    android:layout_height="match_parent"
                    android:textSize="32px"
                    android:gravity="center"
                    android:textColor="#000000"
                    android:text="今日开盘" />

                <TextView
                    android:id="@+id/textView5"
                    android:layout_width="180px"
                    android:layout_height="match_parent"
                    android:textSize="32px"
                    android:gravity="center"
                    android:textColor="#000000"
                    android:text="持仓量" />

                <TextView
                    android:id="@+id/textView6"
                    android:layout_width="180px"
                    android:layout_height="match_parent"
                    android:textSize="32px"
                    android:gravity="center"
                    android:textColor="#000000"
                    android:text="昨日结算" />
            </LinearLayout>
        </com.dlfc.android.smartinfo.ui.view.OptionalScrollView>
    </LinearLayout>

</RelativeLayout>

HorizontalScrollview的重写:
package com.dlfc.android.smartinfo.ui.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;

import com.dlfc.android.smartinfo.utils.Log.LogUtils;
import com.dlfc.android.smartinfo.utils.ToastUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by joseph on 2017/3/2.
 */
public class OptionalScrollView extends HorizontalScrollView {
    private static final String TAG = "MyHScrollView";
    ScrollViewObserver mScrollViewObserver = new ScrollViewObserver();

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

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

    public OptionalScrollView(Context context) {
        super(context);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(ev);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        if (mScrollViewObserver != null) {
            mScrollViewObserver.NotifyOnScrollChanged(l, t, oldl, oldt);
        }
        super.onScrollChanged(l, t, oldl, oldt);
    }

    public void AddOnScrollChangedListener(OnScrollChangedListener listener) {
        mScrollViewObserver.AddOnScrollChangedListener(listener);
    }

    public void RemoveOnScrollChangedListener(OnScrollChangedListener listener) {
        mScrollViewObserver.RemoveOnScrollChangedListener(listener);
    }

    /*
     * 当发生了滚动事件时
     */
    public static interface OnScrollChangedListener {
        public void onScrollChanged(int l, int t, int oldl, int oldt);
    }

    public static class ScrollViewObserver {
        List<OnScrollChangedListener> mList;

        public ScrollViewObserver() {
            super();
            mList = new ArrayList<OnScrollChangedListener>();
        }

        public void AddOnScrollChangedListener(OnScrollChangedListener listener) {
            mList.add(listener);
        }

        public void RemoveOnScrollChangedListener(OnScrollChangedListener listener) {
            mList.remove(listener);
        }

        public void NotifyOnScrollChanged(int l, int t, int oldl, int oldt) {
            if (mList == null || mList.size() == 0) {
                return;
            }
            for (int i = 0; i < mList.size(); i++) {
                if (mList.get(i) != null) {
                    mList.get(i).onScrollChanged(l, t, oldl, oldt);
                }
            }
        }
    }

}

使用页面的初始化

protected void initViewsAndEvents() {
        listHeader.setFocusable(true);
        listHeader.setClickable(true);
        loadOPFuturesDetals();
    }

    private void loadOPFuturesDetals() {
        list = new ArrayList<List<String>>();
        for (int i = 0; i < 15; i++) {
            List<String> list1 = new ArrayList<String>();
            for (int j = 0; j < 7; j++) {
                list1.add("期货" + i + "" + j);
            }
            list.add(list1);
        }
        if (opfdAadpter == null) {
            opfdAadpter = new OPFuturesDetalsAdapter(getCtx(), list, listHeader);
            opfdAadpter.setonLvItemClickListener(new OPFuturesDetalsAdapter.onLvItemClickListener() {
                @Override
                public void onItemClicked(int position) {
                    ToastUtil.getToastUtil().showToast(mContext,"单击"+position);
                }

                @Override
                public void onItemLongClicked(int position) {
                    ToastUtil.getToastUtil().showToast(mContext,"长按"+position);
                    list.remove(position);
                    opfdAadpter.update(list);
                }
            });
            lvOptional.setAdapter(opfdAadpter);
        } else {
            opfdAadpter.update(list);
        }

    }

Adapter的重写:
public class OPFuturesDetalsAdapter extends BaseAdapter {

    private Context context;
    private List<List<String>> list;
    private RelativeLayout mHeader;
    private LayoutInflater inflater;
    private List<String> list1;
    private OptionalScrollView headerHScrollViewTop;
    private GestureDetector mGestureDetector ;
    private GestureListener mGestureListener;
    private onLvItemClickListener onLvItemClickListener;


    public OPFuturesDetalsAdapter(Context ctx, List<List<String>> list, RelativeLayout listHeader) {
        this.context = ctx;
        this.list = list;
        this.mHeader = listHeader;
        inflater = LayoutInflater.from(ctx);
        mGestureListener=new GestureListener();
        mGestureDetector = new GestureDetector(mGestureListener);
    }

    public void update(List<List<String>> list) {
        this.list = list;
        notifyDataSetChanged();
    }

    public void setonLvItemClickListener(onLvItemClickListener listener) {
        onLvItemClickListener = listener;
    }

    @Override
    public int getCount() {
        return null != list ? list.size() : 0;
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        list1 = list.get(position);
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.optional_item, null);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.headerHScrollView.setTag(position);
        headerHScrollViewTop = (OptionalScrollView) mHeader.findViewById(R.id.headerHScrollView);
        headerHScrollViewTop.setTag(-1);
        headerHScrollViewTop.AddOnScrollChangedListener(new OnScrollChangedListenerImp(viewHolder.headerHScrollView));
        headerHScrollViewTop.setOnTouchListener(new ListViewAndHeadViewTouchLinstener());
        viewHolder.headerHScrollView.setOnTouchListener(new ListViewAndHeadViewTouchLinstener());

        if (!StringUtils.isBlank(list.get(position).get(0))) {
            viewHolder.tvContract.setText(list.get(position).get(0));//合约号
        } else {
            viewHolder.tvContract.setText("--");
        }

        if (!StringUtils.isBlank(list.get(position).get(1))) {
            viewHolder.textView1.setText(list.get(position).get(1));//合约号
        } else {
            viewHolder.textView1.setText("--");
        }


        if (!StringUtils.isBlank(list1.get(2))) {
            viewHolder.textView2.setText(list1.get(2));//
        } else {
            viewHolder.textView2.setText("--");
        }

        if (!StringUtils.isBlank(list1.get(3))) {
            viewHolder.textView3.setText(list1.get(3));//
        } else {
            viewHolder.textView3.setText("--");
        }

        if (!StringUtils.isBlank(list1.get(4))) {
            viewHolder.textView4.setText(list1.get(4));//
        } else {
            viewHolder.textView4.setText("--");
        }

        if (!StringUtils.isBlank(list1.get(5))) {
            viewHolder.textView5.setText(list1.get(5));//
        } else {
            viewHolder.textView5.setText("--");
        }

        if (!StringUtils.isBlank(list1.get(6))) {
            viewHolder.textView6.setText(list1.get(6));//
        } else {
            viewHolder.textView6.setText("--");
        }

        return convertView;
    }

    class ViewHolder {
        @BindView(R.id.scroollContainter)
        IntewceptScrolView scroollContainter;
        @BindView(R.id.headerHScrollView)
        OptionalScrollView headerHScrollView;

        @BindView(R.id.tv_contract)
        TextView tvContract;
        @BindView(R.id.textView1)
        TextView textView1;
        @BindView(R.id.textView2)
        TextView textView2;
        @BindView(R.id.textView3)
        TextView textView3;
        @BindView(R.id.textView4)
        TextView textView4;
        @BindView(R.id.textView5)
        TextView textView5;
        @BindView(R.id.textView6)
        TextView textView6;

        public ViewHolder(View convertView) {
            ButterKnife.bind(this, convertView);
        }
    }

    private class OnScrollChangedListenerImp implements OptionalScrollView.OnScrollChangedListener {
        OptionalScrollView mScrollViewArg;

        public OnScrollChangedListenerImp(OptionalScrollView headerHScrollView) {
            mScrollViewArg = headerHScrollView;
        }

        @Override
        public void onScrollChanged(int l, int t, int oldl, int oldt) {
            mScrollViewArg.smoothScrollTo(l, t);
        }
    }

    //将list和heder的滑动事件全部传给HorizontalScrollView
    //保证滑动的事件的统一
    private class ListViewAndHeadViewTouchLinstener implements View.OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            headerHScrollViewTop.onTouchEvent(event);
            mGestureDetector.onTouchEvent(event);
            mGestureListener.setPos((int)v.getTag());
            return false;
        }
    }

    public interface onLvItemClickListener {
        void onItemClicked(int position);
        void onItemLongClicked(int position);
    }

    /**
     * 手势监听
     */
    private class GestureListener extends GestureDetector.SimpleOnGestureListener {
        private int pos;

        public GestureListener() {
            super();
        }

        public void setPos(int pos) {
            this.pos = pos;
        }

        public int getPos() {
            return pos;
        }

        /**
         * 单击事件
         *
         * @param e
         * @return
         */
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            if(getPos() != -1)
            if (onLvItemClickListener != null) {
                onLvItemClickListener.onItemClicked(getPos());
            }
            return super.onSingleTapUp(e);
        }

        /**
         * 长按事件
         *
         * @param e
         */
        @Override
        public void onLongPress(MotionEvent e) {
            if(getPos() != -1)
            if (onLvItemClickListener != null) {
                onLvItemClickListener.onItemLongClicked(getPos());
            }
            super.onLongPress(e);
        }
    }


}

GestureListener 里还可以写很多种类的点击事件

第一次写可能有很多问题,第一篇博客,多多包涵




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值