一个ListView的Layout_widthListView、Layout_width

2023-09-12 08:07:01 作者:逼我们成熟的是人心

好了,所以我用ListView的attribut layout_width遇到的问题。

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

在我的项目我有一个背景图片为我的ListView不适合屏幕的宽度。所以我设置WRAP_CONTENT的layout_width,和我水平居中列表视图。

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.

看来,这是一个坏主意,因为在适配器的GetView方法被称为细胞的3倍以上显示的号码。如果我设置FILL_PARENT问题得到解决的layout_width。我创建了一个简单的项目,显示了问题。

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.

下面是活动的的xml:

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>

在item_list的xml:

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>

最后活动:

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);
        }
}
}

所以,我的解决办法是简单地设置FILL_PARENT的layout_width,并修改列表视图背景的图像添加一些透明的边框,以适应屏幕大小。

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.

不过,我想知道为什么有WRAP_CONTENT出现在列表视图这个问题,为什么这不是在doc如果它是一个已知的问题...

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...

推荐答案

通过设置宽度为WRAP_CONTENT你告诉ListView控件是一样宽最宽的孩子。因此,ListView控件必须衡量其项目,并得到它必须调用getView()上的适配器的项目。这种情况可能发生数次取决于布局的遍数,父布局的行为,等等。

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.

记住,不能保证按时间getView()上的适配器调用的数量,也没有在什么命令调用会发生。因此,您必须实现getView()要尽可能高效。底线是,这不是一个问题,它在这种情况下,预期的行为。

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.