package com.vaguehope.onosendai.ui;

import android.content.Context;
import android.graphics.Color;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;

public class ScrollIndicator {

	private static final int ITEM_HEIGHT_DIP = 2;
	private static final int BAR_WIDTH_DIP = 7;
	private static final int COLOUR = Color.GRAY;

	private ScrollIndicator () {
		throw new AssertionError();
	}

	public static void attach (final Context context, final ViewGroup rootView, final ListView tweetList) {
		final View bar = new View(context);
		bar.layout(0, 0, 0, 0);
		bar.setBackgroundColor(COLOUR);
		bar.bringToFront();
		rootView.addView(bar);

		final int barWidth = (int) dipToPixels(context, BAR_WIDTH_DIP);
		final float pxPerItem = dipToPixels(context, ITEM_HEIGHT_DIP);

		tweetList.setOnScrollListener(new BarMovingScrollListener(bar, pxPerItem, barWidth));
	}

	private static float dipToPixels (final Context context, final int a) {
		return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, a, context.getResources().getDisplayMetrics());
	}

	private static class BarMovingScrollListener implements OnScrollListener {

		private final View bar;
		private final float pxPerItem;
		private final int barWidth;

		public BarMovingScrollListener (final View bar, final float pxPerItem, final int barWidth) {
			this.bar = bar;
			this.pxPerItem = pxPerItem;
			this.barWidth = barWidth;
		}

		@Override
		public void onScrollStateChanged (final AbsListView view, final int scrollStateFlag) {
			final int y = (int) (view.getFirstVisiblePosition() * this.pxPerItem);
			this.bar.layout(view.getRight() - this.barWidth, view.getTop(), view.getRight(), view.getTop() + y);
		}

		@Override
		public void onScroll (final AbsListView view, final int firstVisibleItem, final int visibleItemCount, final int totalItemCount) {
			onScrollStateChanged(view, 0);
		}

	}

}

@@ -1369,16 +1369,50 @@
 Width;%0A%0A
+%09%09private int lastPosition = -1;%0A%0A
 %09%09public
@@ -1498,16 +1498,16 @@
 idth) %7B%0A
-
 %09%09%09this.
@@ -1700,19 +1700,19 @@
 int 
-y = (int) (
+position = 
 view
@@ -1737,16 +1737,91 @@
 sition()
+;%0A%09%09%09if (position != this.lastPosition) %7B%0A%09%09%09%09final int y = (int) (position
  * this.
@@ -1832,16 +1832,17 @@
 rItem);%0A
+%09
 %09%09%09this.
@@ -1937,16 +1937,55 @@
 ) + y);%0A
+%09%09%09%09this.lastPosition = position;%0A%09%09%09%7D%0A
 %09%09%7D%0A%0A%09%09@

Improve ScrollIndicator performance by only redrawing when needed.