美文网首页
listview获取Y轴的滚动距离

listview获取Y轴的滚动距离

作者: flame_ash | 来源:发表于2017-08-12 17:46 被阅读0次

    最近项目中有个需求,就是根据listview滚动的Y值坐标,要做一个简单的动画效果,可是发现listview.getScrollY()获得到的始终是0,脑袋里一万只草泥马奔腾而过。所以果断的去百度,结果搜到的全是类似这样的结果:
    http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0924/1711.html

    这样方案,只是比较适合 每个item高度固定的情况,可是我的listview中有是混排的,而且item的高度很有可能不一样,所以结果是不行的。

    绞尽脑汁,最后想到了解决方案,解决了问题,方法有点儿low,希望各位给出点儿建议。

    废话少说,直接上代码:

    自定义listview,监听listview的onscroll事件,在滚动的时候,记录每一个item的高度,最后加起来,就是getScrollY()

     package com.example.luwenxiang.testapplication.widget;
    
    import android.content.Context;
    import android.os.Build;
    import android.support.annotation.RequiresApi;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.widget.AbsListView;
    import android.widget.ListView;
    
    import java.util.ArrayList;
    
    /**
     * Created by luwenxiang on 17-8-10.
     */
    
    public class AcquiredScrollYListview extends ListView implements AbsListView.OnScrollListener {
        private static final String TAG = "AcquiredScrollYListview";
        private OnScrollListener mScrollListener;
    
        /**
         * 保存上次的firstvisibleposition
         */
        private int mLastFirstVisiblePosition = INVALID_POSITION;
    
        /**
         * 保存上次的lastvisibleposition
         */
        private int mLastLastVisiblePosition = INVALID_POSITION;
        private ArrayList mLocalHeightList;
        private int mTotalItemCount;
    
        public AcquiredScrollYListview(Context context) {
            super(context);
            init(context);
        }
    
        public AcquiredScrollYListview(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        public AcquiredScrollYListview(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(context);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        public AcquiredScrollYListview(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            init(context);
        }
    
        private void init(Context context) {
            super.setOnScrollListener(this);
        }
    
    
        @Override
        public void setOnScrollListener(OnScrollListener listener) {
            if (listener == null) return;
            this.mScrollListener = listener;
            super.setOnScrollListener(this);
        }
    
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            if (mScrollListener != null) {
                mScrollListener.onScrollStateChanged(view, scrollState);
            }
        }
    
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            mTotalItemCount = totalItemCount;
            if (mScrollListener != null) {
                mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
            }
        }
    
    
        /**
         * 滚动时 实时更新 保存 滚动的y值
         */
        public int getListViewScrollY() {
    
            if (getChildCount() == 0) {
                Log.i(TAG, "listview's length is zero");
                return -1;
            }
    
            ArrayList<IntegerValue> localHeight = getHeightList();
            ensureListCapacity(localHeight, Math.max(getLastVisiblePosition(), mTotalItemCount), IntegerValue.class);
            int tempHeight = 0;
            if (mLastFirstVisiblePosition != getFirstVisiblePosition()
                    || mLastLastVisiblePosition != getLastVisiblePosition()) {//当 firstvisibleitem 或者 lastvisibleitem 变化的时候都会更新这个值
                mLastFirstVisiblePosition = getFirstVisiblePosition();
                mLastLastVisiblePosition = getLastVisiblePosition();
    
                for (int i = getFirstVisiblePosition(); i <= getLastVisiblePosition(); i++) {
                    int childMeasuredHeight = getChildAt(i - getFirstVisiblePosition()).getMeasuredHeight();
                    int savedItemHeight = localHeight.get(i).getValue();
                    if (savedItemHeight != childMeasuredHeight) {
                        localHeight.get(i).setValue(childMeasuredHeight);
                        localHeight.get(i).setIndex(i);
                    }
                }
    
                //remove dirty data
                for (int i = getLastVisiblePosition() + 1; i < localHeight.size(); i++) {
                    localHeight.get(i).setValue(0);
                }
            }
            for (int i = 0; i < getFirstVisiblePosition(); i++) {
                tempHeight += getHeightList().get(i).getValue();
            }
            tempHeight -= getChildAt(0).getTop();
    
            return tempHeight;
        }
    
        private <T> void ensureListCapacity(ArrayList<T> localHeight, int index, Class<T> clazz) {
            if (localHeight == null) return;
            int listSize = localHeight.size();
            if (index < listSize) return;
            localHeight.ensureCapacity(index + 1);
    
            for (int i = listSize; i <= index; i++) {
                try {
                    localHeight.add(clazz.newInstance());
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    
    
        public ArrayList<IntegerValue> getHeightList() {
            if (mLocalHeightList == null) {
                mLocalHeightList = new ArrayList<IntegerValue>();
            }
            return mLocalHeightList;
        }
    
    
        public static class IntegerValue {
            private int index;
            private int value;
    
            public IntegerValue() {
            }
    
            public IntegerValue(int index, int value) {
                this.index = index;
                this.value = value;
            }
    
            public int getIndex() {
                return index;
            }
    
            public void setIndex(int index) {
                this.index = index;
            }
    
            public int getValue() {
                return value;
            }
    
            public void setValue(int value) {
                this.value = value;
            }
        }
    }
    

    在activity中测试获取的 值是否准确:

    package com.example.luwenxiang.testapplication;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Color;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.WindowManager;
    import android.widget.AbsListView;
    import android.widget.BaseAdapter;
    import android.widget.ListView;
    import android.widget.TextView;
    
    import com.example.luwenxiang.testapplication.widget.AcquiredScrollYListview;
    
    public class MainActivity3 extends Activity {
    
        private TextView tv_button;
        private AcquiredScrollYListview  listview;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main3);
            initViews();
            setAdapter();
            setScrollListener();
        }
    
        private void setScrollListener() {
            listview.setOnScrollListener(new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
    
                }
    
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    Log.i("lwx","firstVisibleItem:"+firstVisibleItem+ "||visibleItemCount:"+visibleItemCount+"|| totalItemCount:"+totalItemCount+"|| getListviewScrollY:"+listview.getListViewScrollY());
                }
            });
        }
    
        private void setAdapter() {
            TextView headerTextView = new TextView(getApplicationContext());
            headerTextView.setText("this is header");
            headerTextView.setHeight(1000);
            headerTextView.setTextColor(Color.parseColor("#000000"));
            listview.addHeaderView(headerTextView);
    
    //        TextView headerTextView1 = new TextView(getApplicationContext());
    //        headerTextView1.setText("this is header two");
    //        headerTextView1.setHeight(0);
    //        headerTextView1.setTextColor(Color.parseColor("#000000"));
    //        listview.addHeaderView(headerTextView1);
    
            listview.setAdapter(new BaseAdapter() {
                @Override
                public int getCount() {
                    return 100;
                }
    
                @Override
                public Object getItem(int position) {
                    return null;
                }
    
                @Override
                public long getItemId(int position) {
                    return 0;
                }
    
                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    TextView tempView = new TextView(getApplicationContext());
                    tempView.setText("item:" + position);
                    tempView.setTextColor(Color.parseColor("#000000"));
                    tempView.setHeight(500);
                    return tempView;
                }
            });
        }
    
        private void initViews() {
            listview = (AcquiredScrollYListview ) findViewById(R.id.listview);
        }
    
    }
    

    简单记录一下自己的学习心得,也算是 对自己的一种督促

    相关文章

      网友评论

          本文标题:listview获取Y轴的滚动距离

          本文链接:https://www.haomeiwen.com/subject/evglrxtx.html