Постановка задачи: Нужно чтобы ScrollView всегда показывал, в какой части списка мы сейчас находимся.
Проблема: Линия прокрутки (ScrollView) пропадает, на некоторых телефонах, и появляется только когда идет процес прокручивания списка.
Версия Android-а: 1.6
Решение.
Код своего скролбара CustomFastScrollView.java :
import com.evos.R;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.Shape;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup.OnHierarchyChangeListener;
public class CustomFastScrollView extends FrameLayout
implements OnScrollListener, OnHierarchyChangeListener {
private final int ITEM_HEIGHT = 100;
private final int COLOR = Color.GRAY;
private Drawable _murrentThumb;
private int _thumbW;
private int _thumbY;
private int _overlayScrollThumbWidth;
private boolean _dragging;
private ListView _list = null;
private boolean _drawOverlay;
private boolean _changedBounds;
private int _heightScrollDrawable = 40;
private int _amount = 0;
private int _screenHeight = 0;
boolean _globalListenerBeCalled = false;
public CustomFastScrollView(Context context) {
super(context);
init(context, null);
}
public CustomFastScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CustomFastScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void useThumbDrawable(Drawable drawable) {
_murrentThumb = drawable;
_thumbW = _overlayScrollThumbWidth;
_changedBounds = true;
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.CustomFastScrollView);
_overlayScrollThumbWidth = typedArray.getDimensionPixelSize(
R.styleable.CustomFastScrollView_overlayScrollThumbWidth, 0);
}
ShapeDrawable shapeDrawable = new ShapeDrawable();
shapeDrawable.setShape(new Shape() {
@Override
public void draw(Canvas canvas, Paint paint) {
paint.setColor(COLOR);
paint.setAntiAlias(true);
if (getAmountElements() != 0) {
_heightScrollDrawable = _screenHeight * _screenHeight / (getAmountElements() * ITEM_HEIGHT);
canvas.drawRect(0, 0, 5, _heightScrollDrawable, paint);
}
}
});
useThumbDrawable(shapeDrawable);
setWillNotDraw(false);
setOnHierarchyChangeListener(this);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
final int y = _thumbY;
final int viewWidth = getWidth();
canvas.translate(0, y);
_murrentThumb.draw(canvas);
canvas.translate(0, -y);
if (_dragging && _drawOverlay) {
} else {
invalidate(viewWidth - _thumbW, y, viewWidth, y + _heightScrollDrawable);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (_screenHeight == 0) _screenHeight = h;
if (_murrentThumb != null) {
_murrentThumb.setBounds(w - _thumbW, 0, w, _heightScrollDrawable);
}
}
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
if (totalItemCount - visibleItemCount > 0 && !_dragging) {
_thumbY = ((getHeight() - _heightScrollDrawable) * firstVisibleItem) / (totalItemCount - visibleItemCount);
if (_changedBounds) {
final int viewWidth = getWidth();
_murrentThumb.setBounds(viewWidth - _thumbW, 0, viewWidth, _heightScrollDrawable);
_changedBounds = false;
}
}
}
public void onChildViewAdded(View parent, View child) {
if (child instanceof ListView) {
_list = (ListView)child;
_list.setOnScrollListener(this);
}
}
public void onChildViewRemoved(View parent, View child) {
if (child == _list) {
_list = null;
}
}
public synchronized void setAmountElements(int amount) {
_amount = amount;
}
public synchronized int getAmountElements() {
return _amount;
}
}
Для того чтобы им воспользоваться нужно:
1) в проект добавить файл res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomFastScrollView">
<attr name="overlayScrollThumbWidth" format="dimension"/>
</declare-styleable>
</resources>
2) использовать в main.xml :
android:layout_height="fill_parent">
<test.test.view.CustomFastScrollView
android:id="@+id/custom_fast_scroll_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
test:overlayScrollThumbWidth="7dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:test="http://schemas.android.com/apk/res/test.test">
<ListView
android:id="@+id/list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</test.test.view.CustomFastScrollView>
в выделенных местах: test.test.view и test.test подставить свои значения.
3) задать количество елементов в листе (для вычисления высоты скорлбара, в коде прописан костыль: считается что велечина одного елемента 100 пикселей:
private final int ITEM_HEIGHT = 100;
, а количество задается методом: setAmountElements ).
Проблема: Линия прокрутки (ScrollView) пропадает, на некоторых телефонах, и появляется только когда идет процес прокручивания списка.
Версия Android-а: 1.6
Решение.
Код своего скролбара CustomFastScrollView.java :
import com.evos.R;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.Shape;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup.OnHierarchyChangeListener;
public class CustomFastScrollView extends FrameLayout
implements OnScrollListener, OnHierarchyChangeListener {
private final int ITEM_HEIGHT = 100;
private final int COLOR = Color.GRAY;
private Drawable _murrentThumb;
private int _thumbW;
private int _thumbY;
private int _overlayScrollThumbWidth;
private boolean _dragging;
private ListView _list = null;
private boolean _drawOverlay;
private boolean _changedBounds;
private int _heightScrollDrawable = 40;
private int _amount = 0;
private int _screenHeight = 0;
boolean _globalListenerBeCalled = false;
public CustomFastScrollView(Context context) {
super(context);
init(context, null);
}
public CustomFastScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CustomFastScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void useThumbDrawable(Drawable drawable) {
_murrentThumb = drawable;
_thumbW = _overlayScrollThumbWidth;
_changedBounds = true;
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.CustomFastScrollView);
_overlayScrollThumbWidth = typedArray.getDimensionPixelSize(
R.styleable.CustomFastScrollView_overlayScrollThumbWidth, 0);
}
ShapeDrawable shapeDrawable = new ShapeDrawable();
shapeDrawable.setShape(new Shape() {
@Override
public void draw(Canvas canvas, Paint paint) {
paint.setColor(COLOR);
paint.setAntiAlias(true);
if (getAmountElements() != 0) {
_heightScrollDrawable = _screenHeight * _screenHeight / (getAmountElements() * ITEM_HEIGHT);
canvas.drawRect(0, 0, 5, _heightScrollDrawable, paint);
}
}
});
useThumbDrawable(shapeDrawable);
setWillNotDraw(false);
setOnHierarchyChangeListener(this);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
final int y = _thumbY;
final int viewWidth = getWidth();
canvas.translate(0, y);
_murrentThumb.draw(canvas);
canvas.translate(0, -y);
if (_dragging && _drawOverlay) {
} else {
invalidate(viewWidth - _thumbW, y, viewWidth, y + _heightScrollDrawable);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (_screenHeight == 0) _screenHeight = h;
if (_murrentThumb != null) {
_murrentThumb.setBounds(w - _thumbW, 0, w, _heightScrollDrawable);
}
}
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
if (totalItemCount - visibleItemCount > 0 && !_dragging) {
_thumbY = ((getHeight() - _heightScrollDrawable) * firstVisibleItem) / (totalItemCount - visibleItemCount);
if (_changedBounds) {
final int viewWidth = getWidth();
_murrentThumb.setBounds(viewWidth - _thumbW, 0, viewWidth, _heightScrollDrawable);
_changedBounds = false;
}
}
}
public void onChildViewAdded(View parent, View child) {
if (child instanceof ListView) {
_list = (ListView)child;
_list.setOnScrollListener(this);
}
}
public void onChildViewRemoved(View parent, View child) {
if (child == _list) {
_list = null;
}
}
public synchronized void setAmountElements(int amount) {
_amount = amount;
}
public synchronized int getAmountElements() {
return _amount;
}
}
Для того чтобы им воспользоваться нужно:
1) в проект добавить файл res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomFastScrollView">
<attr name="overlayScrollThumbWidth" format="dimension"/>
</declare-styleable>
</resources>
2) использовать в main.xml :
android:layout_height="fill_parent">
<test.test.view.CustomFastScrollView
android:id="@+id/custom_fast_scroll_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
test:overlayScrollThumbWidth="7dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:test="http://schemas.android.com/apk/res/test.test">
<ListView
android:id="@+id/list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</test.test.view.CustomFastScrollView>
в выделенных местах: test.test.view и test.test подставить свои значения.
3) задать количество елементов в листе (для вычисления высоты скорлбара, в коде прописан костыль: считается что велечина одного елемента 100 пикселей:
private final int ITEM_HEIGHT = 100;
, а количество задается методом: setAmountElements ).
Комментариев нет:
Отправить комментарий