Фон нижнего колонтитула в виде списка на Android 2.3.3 - PullRequest
22 голосов
/ 02 июня 2011

Это странно. У меня есть представление списка, которое является частью Relative Layout. Я установил фон для этого Относительного макета и сделал фон в виде списка прозрачным.

Теперь все работало отлично до сегодняшнего утра. Я мог видеть весь экран, покрытый моим собственным фоном, даже если в моем виде списка есть только одна строка.

Затем я получил обновление для Verizon Motorola Droid X для 2.3.3 (раньше было 2.2). Как только оно было обновлено, я снова запустил свое приложение, и теперь вот что происходит.

Если в моем представлении списка есть только одна строка, я вижу белую область под ней, а не свой пользовательский фон. Но если он имеет, скажем, 100 строк и, таким образом, покрывает весь экран, я не увижу этот странный белый фон. Мой относительный макет имеет ширину и высоту, установленную на «fill_parent».

Я разместил свой XML внизу. Кто-нибудь еще сталкивался с этой проблемой, или я делаю какую-то действительно глупую ошибку.

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background = "@drawable/background" 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ListView   android:id = "@+id/listQueue"
                android:layout_width = "fill_parent"
                android:layout_height = "fill_parent"
                android:layout_below = "@id/homeScreenBanner"
                android:background="@android:color/transparent"
                android:divider="@drawable/separator"
                android:scrollingCache="false"/>
</RelativeLayout>

EDIT:

Я думаю, что нашел решение этой проблемы:

Изменен атрибут layout_height на wrap_content, и он работал как шарм. :)

После измененной строки. android:layout_height = "wrap_content"

Ответы [ 5 ]

6 голосов
/ 02 ноября 2011

Я написал класс, который можно использовать в Android 2.1 / 2, который будет правильно работать в 2.3, используя отражение с ListViews:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.ListView;

public class TransparentListView extends ListView {

    private void makeTransparent() {
        if (Build.VERSION.SDK_INT >= 9) {
            try {

                Method overscrollFooterMethod = 
                    TransparentListView.class.getMethod("setOverscrollFooter", new Class[] {Drawable.class});
                Method overscrollHeaderMethod = 
                    TransparentListView.class.getMethod("setOverscrollHeader", new Class[] {Drawable.class});


                try {
                    overscrollFooterMethod.invoke(this, new Object[] {null});
                    overscrollHeaderMethod.invoke(this, new Object[] {null});
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }

    public TransparentListView(Context context) {
        super(context);
        this.makeTransparent();
    }

    public TransparentListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.makeTransparent();
    }

    public TransparentListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.makeTransparent();
    }
}

Используйте его в XML следующим образом:

<com.myapp.TransparentListView android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:transcriptMode="alwaysScroll"
    android:layout_weight="1"
    android:dividerHeight="0dip"
    android:divider="#00000000"
    android:cacheColorHint="#00000000"
/>  
6 голосов
/ 13 октября 2011

На самом деле существует простое решение этой проблемы с использованием базовых макетов, полностью реализованных в файле макета .xml.

Во-первых, предложение блога Motorola неприемлемо, поскольку требует использования API v2.3 для использования «android:overScrollFooter», что приводит к принудительному выполнению нескольких сборок или недоступности для большинства устройств Android.

Предложение установить android:layout_height="wrap_content" для ListView работает во многих случаях и очень полезно, если под ListView нет элементов макета.

Проблема возникает, когда есть один или несколько видов сверху и один или несколько видов под списком. Для этого требуется установить значения android:layout_below и android:layout_above для ListView, который растягивает высоту ListView до высоты доступного пространства, которое больше необходимого 'wrap_content'. Когда это происходит, появляется «ошибка» - дополнительное пространство внизу ListView заполняется цветом фона нижнего колонтитула по умолчанию, темно-серым и непрозрачным.

Теперь о простом решении .

Поместите ListView внутри вертикального LinearLayout или его эквивалента. Разрешить LinearLayout, чтобы охватить сверху вниз доступного пространства с height="fill_parent", дополнительные будут заполнены с правильным фоном рисования или цвета. Установите высоту ListView равным "wrap_content", чтобы не было неиспользуемого пространства для неприглядного серого фона нижнего колонтитула.

Вот пример:

<Button> android:id=@+id/MyTopButton" ... </Button>
<Button> android:id=@+id/MyBottomButton" android:layout_alignParentBottom="true" ... </Button>

<LinearLayout
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:orientation="vertical"
    android:layout_below="@+id/MyTopButton"
    android:layout_above="@+id/MyBottomButton"
    >

    <!-- Note: This is a bug fix for a particular problem experienced on 
         Motorola OS v2.3.3 devices only in which the space below the unused 
         portion of the ListView is rendered in gray instead of the desired 
         transparent 'cacheColorHint' color. This solution which wraps the 
         ListView in another container (a LinearLayout in this case) allows 
         the ListView to be of height "wrap_content" while the parent 
         container is forced to be the desired height - namely from the 
         header area above down to the buttons below. -->

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/MyList"
        android:cacheColorHint="#00000000"
        />

</LinearLayout>
4 голосов
/ 14 октября 2011

Да, решение Дэвида работает в некоторых случаях и позволяет вам собираться с Android до 2.3. Фактически, это первое решение, которое я опубликовал на форуме MotoDev с загружаемым примером кода еще в июне.

Однако некоторые разработчики сказали, что он оставляет артефакт (имеется в виду: беспорядочная горизонтальная серая линия внизу списка). Я видел это сам. Это не работает для тех, кто заботится о деталях дизайна. Решение android:overScrollFooter="@null" не оставляет артефактов. Но вы правы, чтобы использовать его, вам нужно собрать Android 2.3 или выше.

3 голосов
/ 02 октября 2011

См. Сообщение в блоге Motorola об этом поведении - ответ в том, что в Motoblur 2.3 установлен нижний колонтитул по умолчанию, который можно исправить, установив android:overScrollFooter="@null", но только для Android 2.3+.

Их рекомендуемое решение для всего приложения - использовать настраиваемую тему с настраиваемым набором listViewStyle только в папке values-v10 с установленным этим свойством.

0 голосов
/ 03 июня 2011

Можете ли вы попробовать установить параметр cacheColorHint вашего ListView на прозрачный?

android: cacheColorHint = "@ android: color / transparent"

...