(Android) How to fill ListView background and pres

2019-04-04 18:08发布

问题:

I have a custom image background that fills the entire screen behind a ListView.

The ListView has a header that contains some data, then a transparent 10dp margin(allowing us to see a little bit of the background image), and then some more data. Below this header, in the "body" of the ListView, I need to make the ListView's background fill all the way to the bottom of the screen even if the items within do not go all the way to the bottom.

If I set the background of the ListView, then I get the desired effect of always filling to the bottom of the screen, even with only a couple items(or none at all). But this also covers up the 10dp transparent divider in the header, so that I can no longer see the custom background "through" the header.

Can someone please point me down the right path for getting both the filling of the screen while maintaining the transparent divider inside the header?

Someone mentioned in passing that I might need to create "fake" item cells that could be used to create the illusion of a ListView background without impacting the header's transparent divider. However, I am hoping to find an easier solution if possible.. or if that is the best solution see if someone can give me some pointers on how to accomplish that in the most efficient way.

Thank you!

EDIT:

Here's how I am defining the header, although I think this question has more to do with the ListView than this header which I am adding to the ListView via addHeaderView().

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:background="@android:color/transparent" android:orientation="vertical">

    <include android:id="@+view_list_header/headertop"
        layout="@layout/view_list_item"/>

    **<LinearLayout android:id="@+view_list_header/ll_transparent_filler"
    android:layout_width="fill_parent" android:layout_height="10dp"/>**     

    <RelativeLayout android:id="@+view_list_header/sort" android:layout_width="fill_parent" android:layout_height="wrap_content">
        <TextView.../> <ImageView.../> <TextView.../>
    </RelativeLayout>
</RelativeLayout>

So, I've tried various ways of creating the 10dp filler, currently I'm using an "empty" 10dp LinearLayout so that I can obtain a reference to it and set its visibility to GONE when I want to(which I am NOT doing in the case I am discussing)

I am setting the ListView's background like this: listView.setBackgroundResource(resource).

Again, when I do set the background to this ListView, I get the desired behavior of the background always filling the entire screen, even if the number of items I have added to the list(which incidentally all use the same background resource that I am setting to the ListView) is not enough to fill the screen. But when I do this, the 10dp "transparent margin" in the header is not visible because, behind it, the ListViews background is preventing the underlying views from being seen.

I am assuming this happens because the ListView's background also goes behind the Header and Footer views.

The point is, there are lots of ways to create a 10dp "transparent margin" between elements that will allow the underlying views to show through. My problem lies in creating a background for the ListView "body"(i.e. not the Header/Footer) that always fills the screen, even when the list is partially filled or empty and at the same time preserving that transparency in the header so that I can still see the views that are "behind" the ListView.

回答1:

You need to make the items in the ListView transparent by setting following on the ListView:

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

Then your items Layout needs to have whatever color/image (this will be put on top of the transparency).

This should work but will be heavy work on Android as transparency really takes its toll on Android especially when it's in a ListView where there is a lot of UI updates.



回答2:

I hacked it by adding a colored footer. The footer was a LinearLayout containing a View called "fill" set to 5dp height w/ my desired bg color.

After populating & scaling my list header (prior code), I then adjusted the footer to fill in the remaining screen space:

        ...

    int totHeight = getTotalHeightofListView();

    if((mHeader.getMeasuredHeight() + totHeight) < mList.getMeasuredHeight())
        addFooterFill(mHeader.getMeasuredHeight() + totHeight);
}

protected int getTotalHeightofListView() {

    ListAdapter LvAdapter = mList.getAdapter();
    int totHeight = 0;
    for (int i = 0; i < mAdapter.getCount(); i++) {
        View mView = mAdapter.getView(i, null, mList);
        mView.measure(
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        totHeight += mView.getMeasuredHeight();
    }

    return totHeight; 
}

protected void addFooterFill(int sizeUsed){

    View fill = (View) mFooter.findViewById(R.id.fill);

    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) fill.getLayoutParams();
    params.height = mList.getMeasuredHeight() - sizeUsed;
    fill.setLayoutParams(params);
}

In theory this should work even if you already have a footer. You're essentially just adjusting the height of a view within the footer.



回答3:

I have found solution to this, if anyone still needs it. I just made drawable that has top colored as header background like this:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:right="-45dp" android:left="-45dp" android:bottom="-45dp">
    <shape>
        <solid android:color="@color/gray_back" />
        <stroke android:width="40dp" android:color="@color/colorPrimaryDark" />
    </shape>

</item>

I know it's possible to use NavigationView now but I needed quick fix for current app.