自定义listview快速滚动条

    xiaoxiao2021-04-12  33

    1.滚动条 package com.example.myviews.views; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Point; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListAdapter; import android.widget.ListView; import com.example.myviews.R; import com.example.myviews.utils.DensityUtil; /** * create by sclgxt at 2017.4.11 * * */ public class ScrollView extends View { private float scrollbarWidth; private float scrollbarHeight; private float scrollbarRId; private float scrollbarY; private Paint scrollbarPaint; private RectF rectFScrollbar; private float topY; private float hScrollview; private float wScrollview; private Point pDown; private Point pMove; private Bitmap scrollbarBitmap; public static final String TAG = "ScrollView"; private ListView listView; private float hListViewItemSum; protected int mCurrentfirstVisibleItem; private boolean onTouch; private float percentY; // the height of your listview's item int dp40 = DensityUtil.dip2px(getContext(), 40); public ScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // TODO Auto-generated constructor stub init(); } public ScrollView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub init(); } public ScrollView(Context context) { super(context); // TODO Auto-generated constructor stub init(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub Log.i(TAG, "-->onMeasure"); scrollbarWidth = DensityUtil.dip2px(getContext(), 5); // scrollbarHeight = 40; hScrollview = getMeasuredHeight(); wScrollview = getMeasuredWidth(); topY = getMeasuredHeight(); // To be exactaly,the scrollbarHeight is the result of the height of // listview divided by the sum of all listview's child // mulitiplied by the height of scrollview! // I think the height of listview is as high as scrollview // you can change this ! if (hListViewItemSum != 0) { scrollbarHeight = (float) getMeasuredHeight() / hListViewItemSum * getMeasuredHeight(); } else { scrollbarHeight = getMeasuredHeight(); } scrollbarY = scrollbarHeight / 2; Log.i(TAG, "-->getMeasuredHeight(): " + getMeasuredHeight() + ", hListViewItemSum: " + hListViewItemSum + ", scrollbarHeight: " + scrollbarHeight); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); hScrollview = getHeight(); wScrollview = getWidth(); topY = getHeight(); if (hListViewItemSum != 0) { scrollbarHeight = (float) getHeight() / hListViewItemSum * getHeight(); } else { scrollbarHeight = getHeight(); } if (percentY != -1) { scrollbarY = percentY * hScrollview; percentY = -1; } Log.i(TAG, "-->getHeight " + getHeight()); rectFScrollbar = new RectF(wScrollview / 2 - scrollbarWidth / 2, scrollbarY, wScrollview / 2 + scrollbarWidth / 2, scrollbarY + scrollbarHeight); canvas.drawBitmap(scrollbarBitmap, null, rectFScrollbar, scrollbarPaint); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub Log.i(TAG, "--> event.getY(): " + event.getY()); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: onTouch = true; pDown = new Point((int) event.getX(), (int) event.getY()); if (pDown.y + scrollbarHeight / 2 >= topY) { scrollbarY = topY - scrollbarHeight; } else if (pDown.y < scrollbarHeight / 2) { scrollbarY = 0; } else { scrollbarY = pDown.y - scrollbarHeight / 2; } break; case MotionEvent.ACTION_MOVE: onTouch = true; pMove = new Point((int) event.getX(), (int) event.getY()); if (pMove.y + scrollbarHeight / 2 >= topY) { scrollbarY = topY - scrollbarHeight; } else if (pMove.y < scrollbarHeight / 2) { scrollbarY = 0; } else { scrollbarY = pMove.y - scrollbarHeight / 2; } Log.i(TAG, "--> event.ACTION_MOVE()"); break; case MotionEvent.ACTION_UP: onTouch = false; break; default: break; } Log.i(TAG, "-->scrollbarY: " + scrollbarY); if (listView != null) { int sumoffset = (int) ((event.getY() - scrollbarHeight / 2) / hScrollview * hListViewItemSum); int position = sumoffset / dp40; int offset = sumoffset % dp40; Log.i(TAG, "-->sumoffset: " + sumoffset); Log.i(TAG, "-->position: " + position + " offset: " + offset); listView.setSelectionFromTop(position, -offset); } invalidate(); return super.onTouchEvent(event); } private void init() { scrollbarPaint = new Paint(); scrollbarBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.main_dial_pointe2r); } private void caculateListViewOffset() { listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // TODO Auto-generated method stub } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { mCurrentfirstVisibleItem = firstVisibleItem; View firstView = view.getChildAt(0); if (null != firstView) { int height = 0; for (int i = 0; i < mCurrentfirstVisibleItem; i++) { height += dp40; } // In my project,the height of listview's item is fixed! int h = height - firstView.getTop();// 滚动距离 if (!onTouch) scrollTo(h); } } }); } public void setListView(ListView listView) { this.listView = listView; ListAdapter listAdapter = listView.getAdapter(); hListViewItemSum = listAdapter.getCount() * dp40; caculateListViewOffset(); } /** The method was used in which the size of data had changed */ public void notifySizeChanged() { hListViewItemSum = listView.getAdapter().getCount() * dp40; if (hListViewItemSum != 0) { scrollbarHeight = (float) getMeasuredHeight() / hListViewItemSum * getMeasuredHeight(); } else { scrollbarHeight = getMeasuredHeight(); } scrollbarY = scrollbarHeight / 2; Log.i(TAG, "-->listView.getMeasuredHeight(): " + getMeasuredHeight() + ", hListViewItemSum: " + hListViewItemSum + ", scrollbarHeight: " + scrollbarHeight); invalidate(); } public void scrollTo(int y) { // TODO Auto-generated method stub // I found that while the phone close then opened the life of scrollview // will rerun,onMeasuered->onDraw,and the height was changed!then I sava // the percentY. hScrollview = getHeight(); percentY = y / hListViewItemSum; invalidate(); Log.i(TAG, "-->list view onScroll: "); } }

     

      2.使用 2.1布局 <LinearLayout 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:orientation="horizontal" tools:context=".MainActivity" > <ListView android:id="@+id/lv_main" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> <com.example.myviews.views.ScrollView android:id="@+id/sv_main" android:layout_width="40dp" android:layout_height="match_parent" android:background="#88ededed" android:clickable="true" /> </LinearLayout>

     

    2.2 代码 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); List<String> list = new ArrayList<String>(); for (int i = 0; i < 120; i++) { list.add(i + ""); } ArrayAdapter<String> adapter = new ArrayAdapter<String>( getApplicationContext(), R.layout.item_lv_main, R.id.tv_item_lv, list); ListView listView = (ListView) findViewById(R.id.lv_main); listView.setAdapter(adapter); ScrollView scrollView = (ScrollView) findViewById(R.id.sv_main); scrollView.setListView(listView); scrollView.notifySizeChanged(); }

     

    3.效果  
    转载请注明原文地址: https://ju.6miu.com/read-668243.html

    最新回复(0)