Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

android - Layout_width of a ListView

Ok so I encountered an issue with the attribut layout_width of a listView.

In my project I had a background image for my listview that didn't fit the width of the screen. So I set the layout_width on wrap_content, and I centered horizontally the listView.

It seems that this was a bad idea, because in the adapter the GetView method was called more than 3 times the number of cell displayed. If I set the layout_width on fill_parent the problem is resolved. I created a simple project that shows the problem.

Here is the xml of the activity :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
    android:id="@android:id/list"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
/>
</RelativeLayout>

The item_list xml :

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="16sp" >
</TextView>

And finally the Activity :

package fr.example.android.listviewbug;

import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

public class ExampleListViewBugActivity extends ListActivity{
    public static int cpt;

    public static final String[] COUNTRIES = new String[] {
        "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
        "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
        "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
        "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
        "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
        "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",
        "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
        "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
        "Cayman Islands", "Central African Republic", "Chad", "Chile"};

    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);

      cpt = 0;
      setListAdapter(new CustomArrayAdapter(this, R.layout.list_item, COUNTRIES));  
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("AdapterTest", "onDestroy()");
    }

    private class CustomArrayAdapter extends ArrayAdapter<String>{
        public CustomArrayAdapter(Context context, int textViewResourceId, String[] countries) {
            super(context, textViewResourceId, countries);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Log.d("AdapterTest", " cpt:"+ ++cpt);
            return super.getView(position, convertView, parent);
        }
}
}

So my solution is to simply set the layout_width on fill_parent, and modify the image of the listview background to add some transparent borders to fit the screen size.

But I'd like to know why this issue appears with wrap_content on a listview, and why it's not in the doc if it's a known problem...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

By setting the width to "wrap_content" you are telling ListView to be as wide as the widest of its children. ListView must therefore measure its items and to get the items it has to call getView() on the Adapter. This may happen several times depending on the number of layout passes, the behavior of the parent layout, etc.

Remember there are no guarantees on the number of times getView() is invoked on the Adapter, nor in what orders the calls will happen. You must therefore implement getView() to be as efficient as possible. The bottom line is, this is not an issue, it's the expected behavior in this situation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...