#android #listview #scroll #background-image
#Android #listview #прокрутка #фоновое изображение
Вопрос:
Я хочу создать действие с listview и фоновым изображением, которое автоматически перемещается по вертикали, когда пользователь прокручивает listview вниз (изображение должно прокручиваться медленнее, чем просмотр списка), что-то вроде приложения yahoo weather.
Мне было интересно, существует ли существующий код / библиотека, которая делает это хорошо (хорошая обертка кода, установка изображения больше экрана, улучшения в использовании, чтобы OutOfMemory не происходило и т.д.).
Комментарии:
1. То, что вы ищете, — это параллакс, поиск в Google выдает несколько вариантов, один из которых github.com/nirhart/ParallaxScroll
2. У меня не работает. Это хорошая библиотека, но я не могу понять, как использовать ее с фоновыми изображениями активности.
Ответ №1:
Хорошо, итак, мне удалось найти способ сделать это. Я не знаю, насколько хорошо это работает на более слабых устройствах.
Макет:
... inside a RelativeLayout
...
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="none"
>
<ScrollView
android:id="@ id/act_background_scrollview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollY="70dp"
android:fillViewport="false"
android:scrollbarStyle="outsideOverlay"
android:scrollbars="none"
>
<ImageView
android:id="@ id/act_background_wallpaper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerInside" >
</ImageView>
</ScrollView>
</HorizontalScrollView>
...
<ListView
...
>
Настройка фонового изображения:
* константа 1.4 предназначена только для тестирования, изображение должно иметь соотношение 1/2 (с / высота), также ширина изображения должна быть равна ширине экрана
public static Map<Integer, BitmapDrawable> imageMap = new HashMap<Integer, BitmapDrawable>();
protected void setBackgroundResource(int imgRes, int viewRes) {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = (int)(size.x * 1.4);
int height = (int)(size.y * 1.4);
BitmapDrawable dr = imageMap.get(imgRes);
if (dr == null) {
dr = EBitmapUtils.getDrawable(getResources(), imgRes, width, height);
imageMap.put(imgRes, dr);
}
((ImageView)findViewById(R.id.act_background_wallpaper))
.setImageDrawable(dr);
}
Где EBitmapUtils находится:
public static Bitmap getResizedBitmap(Bitmap image, int newHeight, int newWidth) {
int width = image.getWidth();
int height = image.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(image, 0, 0, width, height,
matrix, false);
return resizedBitmap;
}
public static BitmapDrawable getDrawable(Resources res, int imgRes
, int width, int height){
Bitmap bm = BitmapFactory.decodeResource(res, imgRes);
Bitmap bmResized = getResizedBitmap(bm, height, width);
bm.recycle();
return new BitmapDrawable(res, bmResized);
}
И фоновая прокрутка программно при прокрутке списка (ListComponent — это пользовательский виджет, который фактически оборачивает ListView):
backgroundScroll = (ScrollView)findViewById(R.id.act_background_scrollview);
listComponent.setCompositeOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (listComponent.getListView().getChildAt(0) == null)
return;
View c = listComponent.getListView().getChildAt(0);
int top = -c.getTop() (listComponent.getListView().getFirstVisiblePosition() -1)
* c.getHeight();
backgroundScroll.scrollTo(0, top / 3);
}
});