自定义listview快速滚动条

来源:互联网 发布:阿里巴巴不能传淘宝 编辑:程序博客网 时间:2024/04/26 04:22
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.效果


0 0
原创粉丝点击