Android listView单元格循环使用可变大小的单元格

Android listView单元格循环使用可变大小的单元格,android,listview,Android,Listview,我有一个列表视图。单元格的高度可变。这就导致了回收电池的问题——回收电池的高度可能不正确。关闭循环使用会使滚动变得太不稳定。如何在回收电池的同时获得正确的高度 编辑:每个地方的高度都不同。没有可能值的简短列表。两个单元格类型 通常问题来自getView。我不确定您真正想要的是什么,因为您没有提供自定义适配器。但是,我给出了一个有两种不同单元格类型的示例,但是该单元格只包含一个textview 在这种情况下,所有的电池都会随着循环进行完全调整。仔细阅读并扩展/修改以满足您的需要 在您的Custom

我有一个列表视图。单元格的高度可变。这就导致了回收电池的问题——回收电池的高度可能不正确。关闭循环使用会使滚动变得太不稳定。如何在回收电池的同时获得正确的高度


编辑:每个地方的高度都不同。没有可能值的简短列表。

两个单元格类型

通常问题来自getView。我不确定您真正想要的是什么,因为您没有提供自定义适配器。但是,我给出了一个有两种不同单元格类型的示例,但是该单元格只包含一个textview

在这种情况下,所有的电池都会随着循环进行完全调整。仔细阅读并扩展/修改以满足您的需要

在您的
CustomAdapter

private final class CustomArrayAdapter extends ArrayAdapter<String> {
    //the fastest is to get the layout inflater once and not each time getView is called
    private LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    public CustomArrayAdapter(Context context, int resource, int textViewResourceId, String[] objects) {
        super(context, resource, textViewResourceId, objects);
    }

    ...

    //here depending on the item position determine if cell is of type 1 or 2
    @Override
    public int getItemViewType(int position) {
        if (/* your type 1 criteria is match */) {
            return TYPE_1;
        } else {
            return TYPE_2;
        }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        int type = getItemViewType(position);
        if (convertView == null) {
            holder = new ViewHolder();
            switch (type) {
                case TYPE_1:
                    convertView = mInflater.inflate(R.layout.row_of_type_1, parent, false);
                    holder.text = (TextView) convertView.findViewById(R.id.textview_type_1);
                    break;
                case TYPE_2:
                    convertView = mInflater.inflate(R.layout.row_of_type_2, parent, false);
                    holder.text = (TextView) convertView.findViewById(R.id.textview_type_2);
                    break;
             }
             convertView.setTag(holder);
         } else {
             holder = (ViewHolder) convertView.getTag();
         }

         //get the text for that specific cell and set it
         holder.text.setText(getMyCustomTextForThisCell());

         return convertView;
    }
}

static class ViewHolder {     
    TextView text;
}
private final class CustomArrayAdapter extends ArrayAdapter<String> {
    //the fastest is to get the layout inflater once and not each time getView is called
    private LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    public CustomArrayAdapter(Context context, int resource, int textViewResourceId, String[] objects) {
        super(context, resource, textViewResourceId, objects);
    }

    ...

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        if (convertView == null) {
            holder = new ViewHolder();
            convertView = mInflater.inflate(R.layout.row_type, parent, false);
            holder.text = (TextView) convertView.findViewById(R.id.textview_in_your_row);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        //get the text for that specific cell and set it
        holder.text.setText(getMyCustomTextForThisCell());

        return convertView;
    }
}

static class ViewHolder {     
    TextView text;
}

单元布局

在示例中,我给出的文件row_type.xml(您所在行的布局文件)应如下所示:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textview_in_your_row"
    android:paddingLeft="6dp"
    android:paddingRight="6dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

不要忘记android:layout\u height=“wrap\u content”,否则单元格将无法调整大小


旁白

这篇旁白没有提到OP问题,但是如果人们因为标题中的细胞回收词而来到这里,他们可能会对以下事实感兴趣,即我在这里给出了一个完整的细胞回收示例,其中包含一个EditText


以下是我如何使用Xamarin解决这个问题的

public override View GetView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;

        int type = GetItemViewType(position);
        if (convertView == null)
        {
            holder = new ViewHolder();
            convertView = context.LayoutInflater.Inflate(Resource.Layout.my_row_layout, parent, false);
            holder.myTextView = FindViewById<TextView>(Resource.Id.viewRow);
            convertView.Tag = holder;
        }
        else 
        {
            holder = (ViewHolder)convertView.Tag;
            int heightWeWant = heights[type];
            if (holder.myTextView.Height != heightWeWant) //height we have isn't what we want
            {
                AbsListView.LayoutParams parms = new AbsListView.LayoutParams(LinearLayout.LayoutParams.MatchParent, heightWeWant); //Width, Height //resize the view to the height we want
                convertView.LayoutParameters = parms;
            }
            convertView.Tag = holder;
        }

        holder.myText = "Some text here";

        return convertView;
    }
public override View GetView(int位置、视图转换视图、视图组父视图){
视窗座;
int type=GetItemViewType(位置);
if(convertView==null)
{
holder=新的ViewHolder();
convertView=context.LayoutInflater.Inflate(Resource.Layout.my_row_Layout,parent,false);
holder.myTextView=FindViewById(Resource.Id.viewRow);
convertView.Tag=holder;
}
其他的
{
holder=(ViewHolder)convertView.Tag;
int heightWeWant=高度[类型];
如果(holder.myTextView.Height!=heightWeWant)//我们拥有的高度不是我们想要的
{
AbsListView.LayoutParams parms=新的AbsListView.LayoutParams(LinearLayout.LayoutParams.MatchParent,heightWeWant);//宽度,高度//将视图调整为所需高度
convertView.LayoutParameters=parms;
}
convertView.Tag=holder;
}
holder.myText=“此处有一些文本”;
返回视图;
}

每行的大小是否不同?甚至当你有不同的高度时,你知道你会有多少不同的高度吗?你使用getitemviewtype了吗?我认为你的问题没有解决办法(无限不同的类型+回收)。不管怎样,我把问题投了更高的票,让我们看看是否会有一些有趣的答案。我不明白为什么不需要引用每种类型就可以拥有大量的类型?这是一个真实的案例还是一个假设的案例?你能提供更多的细节吗?高度取决于单元格中文本的高度。如果OP没有添加:“各地的高度都不同。没有可能的值的简短列表。”我不明白这一点,那么你的方法就是正确的。他所说的“各地不同”是什么意思。我的意思是,我第一次遇到问题,因为我没有在正确的位置进行setTag,所以只能循环使用1种类型。我不能确定,但我怀疑他是说所有视图都可以有不同的类型。由于两个视图需要具有相同的类型才能在另一个视图中进行转换,如果它们都具有不同的类型,那么回收将一事无成——它们都是相同的类型,因为它们的内容是相同的类型。但是,根据文本的长度,高度可能相当高,也可能相当短。因此,如果我正确理解,您有一个带有textview的单元格,并且希望显示文本,但每个单元格都有不同长度的文本?如果是这样的话,我的代码就是这么做的。删除第二种类型,只使用一种,它就会工作。重用的目的是获取标签并将标签设置在正确的位置。