2012-07-02 101 views

回答

31

由于Romain Guy (Google工程师在UI工具包上工作)在他的帖子中说

通过将宽度设置为wrap_content您告诉ListView的宽度与其最宽的子级一样宽。因此,ListView必须测量它的项目并获取它必须在适配器上调用getView()的项目。这可能会发生多次,具体取决于布局过程的数量,父布局的行为等。

因此,如果将ListView的布局宽度或布局高度设置为wrap_content,则ListView将尝试测量每个视图这是附加到它 - 这绝对不是你想要的。

请记住:避免设置wrap_content的列表视图或GridView的时刻,更多详情请参阅本Google I/O video谈论的ListView

+8

这个建议看起来并不普遍。ListView/Adapater组合比起人们最初可能意识到的更具通用性和可扩展性,这意味着人们也可能没有意识到将wrap_content与任意数据集一起使用的后果。但这并不是说在数据集的大小是固定的或有限的情况下没有多少情况。在这些情况下,使用wrap_content将更像是一个判断呼叫。 – spaaarky21

+3

这看起来像林特应该警告的东西 - 但它目前不。 –

+1

我不知道为什么这个答案被接受:它根本不回答这个问题。它也鹦鹉回到了罗曼的Guy的帖子 - 这是一个完全不同的问题:布局测量的次数 - 并指向一个视频,实际解释了为什么wrap_content应该起作用,至少对于3个列表项,以及“排序工作“更复杂的清单(成本相当可观)。 – Rick77

3
I want my list view to wrap its content horizontally and not to fill all the width. 

在列表视图情况下,你不能给WRAP_CONTENT,因为如果你给WRAP_CONTENT的列表视图仅前三个项目(行)将显示其余的将被忽略。所以不要” T选用WRAP_CONTENT。请务必使用FILL_PARENT或match_parent的列表视图

有关列表视图高效的设计,你可以看到这个World of ListView

+2

不要使用FILL_PARENT。它在Android 2.2中被弃用:http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#FILL_PARENT – spaaarky21

29

的世界为了实现wrap_content高度ListView,我们需要使用CustomListViewextends我们的原生ListView

MyListView.java

public class MyListView extends ListView { 

    private android.view.ViewGroup.LayoutParams params; 
    private int oldCount = 0; 

    public MyListView(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) 
    { 
     if (getCount() != oldCount) 
     { 
      int height = getChildAt(0).getHeight() + 1 ; 
      oldCount = getCount(); 
      params = getLayoutParams(); 
      params.height = getCount() * height; 
      setLayoutParams(params); 
     } 

     super.onDraw(canvas); 
    } 

} 
在你这样的 layout使用自定义视图

layout.xml

<com.yourpackagename.MyListView 
     ...  
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     ... /> 
+0

完美的作品! – beetree

+1

太棒了!当我想要在RecyclerView中使用ListView时为我工作。 – VSG24

+3

这个答案很有用,但是当ListView在一个RecyclerView里时,滚动看起来好像是bug。所以真正的解决方案是重写onMeasure方法。看到这个答案:http://stackoverflow.com/a/24186596/1901561 – RIscRIpt

3

它可以使用的LinearLayout 创建实施像这个例子

public class LinearLayoutAdapter { 
LinearLayout linearLayout; 
ArrayList<String> arrayList 
private View rootView; 
private static LayoutInflater inflater; 
public ChoicesAdapter_(ArrayList<String> arrayList ,LinearLayout linearLayout) 
{ 
    this.index =index; 
    this.arrayList=arrayList; 
    this.linearLayout=linearLayout; 
    notifyDataSetChanged(); 
} 
private void notifyDataSetChanged() { 
    linearLayout.removeAllViews(); 
    for (int i =0;i<getCount();i++){ 
     linearLayout.addView(getView(i,null,null)); 
    } 
} 
public int getCount() { 
    return arrayList.size(); 
} 
public Object getItem(int position) { 
    return null; 
} 
public long getItemId(int position) { 
    return 0; 
} 
public View getView(final int position, View convertView, ViewGroup parent) { 
    rootView = inflater.inflate(R.layout.row_list, null); 
    TextView textView = (TextView)rootView.findViewById(R.id.text);  
    textView.setText(arrayList.get(position)); 
    return rootView; 
} 

MainActivity例如

public class MainActivity extends Activity { 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ArrayList<String> arrayList = new ArrayList<String>(); 
    arrayList.add("Accent"); 
    arrayList.add("Acclaim"); 
    arrayList.add("Accord"); 
    arrayList.add("Achieva"); 
    arrayList.add("Aerio"); 
    arrayList.add("Aerostar"); 
    LinearLayout linearLayout = (LinearLayout)findViewById(R.id.linearLayout); 
    linearLayoutAdapter= LinearLayoutAdapter(arrayList,linearLayout); 
} 

}

XML例如

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@android:id/text" 
android:layout_width="match_parent" 
android:layout_height="50dp" 
android:gravity="center" 
android:textColor="@color/dark_gray" 
android:background="@color/white" 
android:textSize="20dp" 
android:text="" /> 
+0

是的,你可以做到这一点,但你松散(或有很多实现)的listitem意见的回收系统。它适用于少数项目,但少数项目可能会考虑不使用列表视图,也不适用适配器。 –